【问题标题】:Proper approach to create hypermedia in c# webapi在 c# webapi 中创建超媒体的正确方法
【发布时间】:2017-03-28 11:01:53
【问题描述】:

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

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

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。

【问题讨论】:

    标签: c# rest asp.net-web-api2 hateoas hypermedia


    【解决方案1】:
    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" 
            }));
        }
        

    【讨论】:

    • 谢谢。所以我的模型不是这样的......答案被接受了。
    【解决方案2】:

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

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

    【讨论】:

    • 谢谢,加 1 的帮助。我会考虑的。
    猜你喜欢
    • 2011-11-19
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多