在 c# webapi 中创建超媒体的正确方法
Proper approach to create hypermedia in c# webapi
我正在研究如何为特定资源实施超媒体,但找不到真正的实施示例,只是抽象...
你知道,在各种文章中,这个人创建了如下方法:
public List<Link> CreateLinks(int id)
{
...//Here the guy put these three dots, whyyyyyyyyyy?
}
我目前拥有的:
public Appointment Post(Appointment appointment)
{
//for sake of simplicity, just returning same appointment
appointment = new Appointment{
Date = DateTime.Now,
Doctor = "Dr. Who",
Slot = 1234,
HyperMedia = new List<HyperMedia>
{
new HyperMedia{ Href = "/slot/1234", Rel = "delete" },
new HyperMedia{ Href = "/slot/1234", Rel = "put" },
}
};
return appointment;
}
和约会class:
public class Appointment
{
[JsonProperty("doctor")]
public string Doctor { get; set; }
[JsonProperty("slot")]
public int Slot { get; set; }
[JsonProperty("date")]
public DateTime Date { get; set; }
[JsonProperty("links")]
public List<HyperMedia> HyperMedia { get; set; }
}
public class HyperMedia
{
[JsonProperty("rel")]
public string Rel { get; set; }
[JsonProperty("href")]
public string Href { get; set; }
}
有正确的方法吗?我的意思是,没有对链接进行硬编码?如何为给定类型动态创建它们,即约会 class?
我使用的是 c# Webapi,而不是 c# MVC。
您绝对可以将 Rel
提取到 Enum
(实际上是标准的 2 - Delete
、Put
等 - 以及自定义的 -后者可以包含自定义关系,例如 customer-by-id
).
您还可以动态构建 Href
参数(从对象的属性中提取参数),但至于资源本身......您可能坚持使用硬编码(您也可以查看反思)。
要将路由动态添加到 HyperMedia 集合,您可以使用路由命名:
使用特定名称定义您的路线(例如删除):
[Route("{id:int}", Name = "AppointmentDeletion")]
public IHttpActionResult Delete(int slot)
{
//your code
}
使用方法UrlHelper.Link:
public Appointment Post(Appointment appointment)
{
appointment = new Appointment
{
HyperMedia = new List<HyperMedia>
{
new HyperMedia
{
Href = Url.Link("AppointmentDeletion", new { slot = 1234 }),
Rel = "delete"
}
}
return appointment;
};
也可以在不为每个 class:
声明 HyperMedia 属性 的情况下动态添加链接到结果对象
定义一个没有链接的class:
public class Appointment
{
[JsonProperty("doctor")]
public string Doctor { get; set; }
[JsonProperty("slot")]
public int Slot { get; set; }
[JsonProperty("date")]
public DateTime Date { get; set; }
}
定义扩展方法:
public static class LinkExtensions
{
public static dynamic AddLinks<T>(this T content, params object[] links)
{
IDictionary<string, object> result = new ExpandoObject();
typeof (T)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.ToList()
.ForEach(_ => result[_.Name.ToLower()] = _.GetValue(content));
result["links"] = links;
return result;
}
}
使用它:
public IHttpActionResult Post(Appointment appointment)
{
return Ok(appointment.AddLinks(new HyperMedia
{
Href = Url.Link("AppointmentDeletion", new { slot = 1234 }),
Rel = "delete"
}));
}
我正在研究如何为特定资源实施超媒体,但找不到真正的实施示例,只是抽象...
你知道,在各种文章中,这个人创建了如下方法:
public List<Link> CreateLinks(int id)
{
...//Here the guy put these three dots, whyyyyyyyyyy?
}
我目前拥有的:
public Appointment Post(Appointment appointment)
{
//for sake of simplicity, just returning same appointment
appointment = new Appointment{
Date = DateTime.Now,
Doctor = "Dr. Who",
Slot = 1234,
HyperMedia = new List<HyperMedia>
{
new HyperMedia{ Href = "/slot/1234", Rel = "delete" },
new HyperMedia{ Href = "/slot/1234", Rel = "put" },
}
};
return appointment;
}
和约会class:
public class Appointment
{
[JsonProperty("doctor")]
public string Doctor { get; set; }
[JsonProperty("slot")]
public int Slot { get; set; }
[JsonProperty("date")]
public DateTime Date { get; set; }
[JsonProperty("links")]
public List<HyperMedia> HyperMedia { get; set; }
}
public class HyperMedia
{
[JsonProperty("rel")]
public string Rel { get; set; }
[JsonProperty("href")]
public string Href { get; set; }
}
有正确的方法吗?我的意思是,没有对链接进行硬编码?如何为给定类型动态创建它们,即约会 class?
我使用的是 c# Webapi,而不是 c# MVC。
您绝对可以将 Rel
提取到 Enum
(实际上是标准的 2 - Delete
、Put
等 - 以及自定义的 -后者可以包含自定义关系,例如 customer-by-id
).
您还可以动态构建 Href
参数(从对象的属性中提取参数),但至于资源本身......您可能坚持使用硬编码(您也可以查看反思)。
要将路由动态添加到 HyperMedia 集合,您可以使用路由命名:
使用特定名称定义您的路线(例如删除):
[Route("{id:int}", Name = "AppointmentDeletion")] public IHttpActionResult Delete(int slot) { //your code }
使用方法UrlHelper.Link:
public Appointment Post(Appointment appointment) { appointment = new Appointment { HyperMedia = new List<HyperMedia> { new HyperMedia { Href = Url.Link("AppointmentDeletion", new { slot = 1234 }), Rel = "delete" } } return appointment; };
也可以在不为每个 class:
声明 HyperMedia 属性 的情况下动态添加链接到结果对象定义一个没有链接的class:
public class Appointment { [JsonProperty("doctor")] public string Doctor { get; set; } [JsonProperty("slot")] public int Slot { get; set; } [JsonProperty("date")] public DateTime Date { get; set; } }
定义扩展方法:
public static class LinkExtensions { public static dynamic AddLinks<T>(this T content, params object[] links) { IDictionary<string, object> result = new ExpandoObject(); typeof (T) .GetProperties(BindingFlags.Public | BindingFlags.Instance) .ToList() .ForEach(_ => result[_.Name.ToLower()] = _.GetValue(content)); result["links"] = links; return result; } }
使用它:
public IHttpActionResult Post(Appointment appointment) { return Ok(appointment.AddLinks(new HyperMedia { Href = Url.Link("AppointmentDeletion", new { slot = 1234 }), Rel = "delete" })); }