web api 2.0中的实例引用/链接

时间:2014-08-19 17:33:38

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

如何在webapi 2中进行restful实例引用?

对象通常引用其他对象的实例。例如,博客帖子引用了创建帖子的作者。

public class Blogpost {
   public string Title {get; set;}
   public string Text {get; set;}
   public Author Author {get; set;}
}

根据this video @ 45:00,RESTful原则是转换为对直接URI的引用。像这样:

{
  "Id": 1,
  "Title": "My first blogpost",
  "Text": "Hello World",
  "Author": [ "href" : "http://app.com/api/authors/4"]
}

这应该如何在webapi 2中完成?默认情况下,如果禁用延迟加载,则引用仅作为空数组返回:

{
  "Id": 1,
  "Title": "My first blogpost",
  "Text": "Hello World",
  "Author": []
}

1 个答案:

答案 0 :(得分:2)

我不知道是否有内置的方法来执行此任务,但您可以使用自定义合约解析程序,自定义值提供程序以及在您的实体上使用接口或基类来获得所需内容

实体基类: 可能你的实体已经有了一个定义公共Id属性的基类,如果不是,只需创建基类并将实体类更改为继承自DomainEntityBase。

public abstract class DomainEntityBase
{
    public int Id { get; set; }
}

自定义合约解析器: 我们将使用自定义合约解析程序来更改引用实体的值提供程序。

public class ReferenceLinkContractResolver : CamelCasePropertyNamesContractResolver
{
    #region Methods
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);
        var childProperties = properties.Where(p => typeof(DomainEntityBase).IsAssignableFrom(p.PropertyType));

        foreach (var c in childProperties)
        {
        c.ValueProvider = new ReferenceLinkingValueProvider(ReflectionHelper.GetProperty(type, c.PropertyName));
        }

        return properties;
    }
    #endregion
}

自定义价值提供商 使用此自定义值提供程序,我们将引用实体序列化更改为href属性。

public class ReferenceLinkingValueProvider : IValueProvider
{
    #region Fields
    private PropertyInfo m_property;
    #endregion

    #region Constructors
    public ReferenceLinkingValueProvider(PropertyInfo property)
    {
        m_property = property;
    }
    #endregion

    #region Methods
    public object GetValue(object target)
    {
        if (target == null)
        {
            return null;
        }

        var value = m_property.GetValue(target);
        var entity = value as DomainEntityBase;

        if (entity == null)
        {
        return value;
        }

        // If your resources are in plural, you will need some helper method 
        // to put in right plural (remember the resources with 'y' ends).
        var resourceName = entity.GetType().Name;

        // Here is where the real work happens. You change the entire entity
        // serialization to just the href property.
        return new
        {
        href = "http://app.com/api/{0}/{1}".With(resourceName, entity.Id)
        };
    }

    public void SetValue(object target, object value)
    {
        m_property.SetValue(target, value);
    }
    #endregion
}

现在,在您的网络API配置中,设置json格式化程序的ContractResolver:

var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.JsonFormatter.SerializerSettings.ContractResolver = new ReferenceLinkContractResolver();
  

注意:一些帮助和扩展方法,例如&#34; With&#34;一来,来   来自HelperSharp图书馆。