使用asp.net web api进行部分更新

Wil*_*eer 8 c# asp.net-mvc json.net asp.net-web-api

我在asp.net mvc 3中使用web api和dbContext创建了一个简单的待办事项列表应用程序.(使用骨干和客户端的requirejs)一切正常,但我有点担心,如果我检查或取消选中待办事项,我必须将整个模型发送到服务器.我想在提交数据时只发送"完成"字段.

我应该提一下,我也使用JsonNetFormatter将JSON.NET用作默认的Serializer(在此解释:http://blogs.msdn.com/b/henrikn/archive/2012/02/18/using-json- net-with-asp-net-web-api.aspx).

目前这是我的api控制器方法来更新模型

public HttpResponseMessage Put(Todo todo)
{
    _db.Entry(todo).State = EntityState.Modified;
    _db.SaveChanges();
    return new HttpResponseMessage(HttpStatusCode.NoContent);
}
Run Code Online (Sandbox Code Playgroud)

它将此作为json数据

{"content":"Pick up milk","done":false,"id":10}
Run Code Online (Sandbox Code Playgroud)

当然这是有效的,但它正在更新整个模型,它应该只更新1个字段.我可以实现只从浏览器发送更改的字段到服务器,但我不知道web api方法应该是什么样子.我正在考虑使用FormCollection做一些事情,但这似乎不适用于web api,因为它似乎试图将提交的formvalues直接序列化为FormCollection类型,我收到此错误.

Cannot deserialize JSON object (i.e. {"name":"value"}) into type 'System.Web.Mvc.FormCollection'.
Run Code Online (Sandbox Code Playgroud)

如何将模型中的一个或多个字段的部分更新发送到我的web api?我只想将更新的字段发送到服务器,并从那里只将这些字段更新到数据库.我当然不希望在更新之前查询数据库.

elo*_*los 1

一种方法是使用名为Automapper 的工具并对其进行配置,以便在映射 Todo 对象时空值不会覆盖现有值。例如:

  Mapper.CreateMap<Todo,Todo>()
        .ForMember(d => d.Id, o => o.Ignore())
        .ForAllMembers(mo => mo.Condition(cond => !cond.IsSourceValueNull));  
Run Code Online (Sandbox Code Playgroud)

然后,您只需将接收到的对象值映射到现有对象值,如下所示:

  Mapper.Map(todo, item);
Run Code Online (Sandbox Code Playgroud)

另一个建议是使用 PATCH 而不是 PUT,这更适合根据 REST 部分更新资源

  • 不卖这个。如果要将某个字段设置为空怎么办? (4认同)
  • 您无法判断空值是由发送者设置的还是只是由于省略了字段而设置的。在这种情况下,我建议使用 PATCH 动词。 (2认同)