webapi 2.0中的实例引用/链接
本文关键字:引用 链接 实例 webapi | 更新日期: 2023-09-27 18:18:38
如何在webapi 2中实现restful实例引用?
对象通常有对其他对象实例的引用。例如,一个blogpost有一个对创建该post的作者的引用。
public class Blogpost {
public string Title {get; set;}
public string Text {get; set;}
public Author Author {get; set;}
}
根据这个视频@ 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": []
}
我不知道是否有一个内置的方法来完成这个任务,但是你可以使用一个自定义的合约解析器,一个自定义的值提供程序,并在你的实体上使用一个接口或基类来得到你想要的。
实体基类:可能你的实体已经有一个基类定义了公共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
}
现在,在你的web api配置中,设置json格式化器的ContractResolver:
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.JsonFormatter.SerializerSettings.ContractResolver = new ReferenceLinkContractResolver();
注意:一些帮助和扩展方法,比如"With"方法