在对WebApi的POST调用中,我试图返回一个Created(newobject)的东西。但是ApiController中没有Created的签名,只能接受对象并完成剩下的工作。
如果我返回类似的内容,它可以正常工作:
return Created(newobject.blahid.ToString(), newobject);
或者如果我做了
return CreatedAtRoute("DefaultApi", new { controller = ControllerContext.ControllerDescriptor.ControllerName, id = newobject.blahid.ToString()}, newobject);
我想将其简化为:
return Created(newobject);
我需要在BaseController中实现一个方法
public class BaseController : ApiController
{
protected new CreatedNegotiatedContentResult<T> Created<T>(T content)
{
var id = GetId(content);//need help here
return base.Created(id, content);
}
}
我不想担心在不同模型中以不同方式调用对象的唯一标识符,例如myobjguid,someblahguid等我只是想找到它并将其标记为“id”。
说我的模特是否
public class Model_A
{
public List<Model_A> ChildModels { get; set; }
[LookForThisAttribute]//I want something like this
public Guid Model_AGuid { set; get; }
public Guid ? ParentGuid { set; get; }
public List<SomeOtherObject> OtherObjects { set; get; }
}
是否有一个属性([LookForThisAttribute])或我可以在我的所有模型上设置的东西,以指定如果我找到它,这是被认为是唯一标识符的人。
就像Entity Framework中的[Key]属性一样。无论你怎么称呼它,Entity Framework都知道它将成为主键。
因此,GetId(T内容)方法可以获取对象并返回具有[LookForThisAttribute]
集的属性的值吗?
答案 0 :(得分:0)
我最终编写了自己的属性,然后在BaseController中查找它。
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class UniqueIdAttribute: Attribute
{
}
在BaseController创建的方法中:
protected CreatedNegotiatedContentResult<T> Created<T>(T content)
{
var props =typeof(T).GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(UniqueIdAttribute)));
if (props.Count() == 0)
{
//log this
return base.Created(Request.RequestUri.ToString(), content);
}
var id = props.FirstOrDefault().GetValue(content).ToString();
return base.Created(new Uri(Request.RequestUri + id), content);
}
Mark Gravell的帖子帮助我获取具有自定义属性的属性的值: How to get a list of properties with a given attribute?
对于控制器的相应单元测试,对我来说工作正常。
现在我可以从所有ApiControllers中调用Created(anyobject);
,而不必为人们为他们的ID添加不同的名称,只要他们使用我的自定义属性进行装饰。