跨webapi模型为对象指定唯一标识符属性

时间:2016-06-01 20:18:22

标签: c# post asp.net-web-api2

在对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]集的属性的值吗?

1 个答案:

答案 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添加不同的名称,只要他们使用我的自定义属性进行装饰。