1

我正在研究如何为特定资源实现超媒体,但找不到真正的实现示例,只是抽象......

你知道,在各种文章中,这个家伙创建了一个方法,比如:

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;
    }

和约会类:

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; }
}

有正确的方法吗?我的意思是,没有硬编码链接?如何为给定类型动态创建它们,即约会类?

我使用的是 c# Webapi,而不是 c# MVC。

4

2 回答 2

2
  1. 为了向 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;
      }; 
      
  2. 也可以动态地将链接添加到结果对象,而无需为每个类声明 HyperMedia 属性:

    • 定义一个没有链接的类:

      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" 
          }));
      }
      
于 2016-11-16T09:37:40.217 回答
1

您绝对可以将其提取Rel到一个Enum(实际上是 2 个标准的 -DeletePut- 和一个自定义的 - 后者可以包含自定义关系,如customer-by-id)。

您还可以Href动态构建参数(从对象的属性中提取参数),但至于资源本身......您可能会坚持硬编码(您也可以查看反射)。

于 2016-11-16T08:14:32.687 回答