【问题标题】:MVC4 WebApi OData Delta<T> is not populating GUIDs or Int fieldsMVC4 WebApi OData Delta<T> 未填充 GUID 或 Int 字段
【发布时间】:2012-11-14 16:11:50
【问题描述】:

我希望使用 Delta 包装器对 Web api 控制器操作进行部分更新。

我有一个这样的模型:

public class Person
{
    public Guid PersonId { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public bool IsActive { get; set; }

    public int NumVacationDays { get; set; }

    public double Salary { get; set; }
}

我有这样的 api 控制器:

    public void Put(Delta<Person> person)
    {
        var p = person.GetEntity();

        Person existingPerson = _repository.Get(p.PersonId);

        person.Patch(existingPerson);

        _repository.Update();

        return;
    }

我像这样调用 web api(使用 fiddler)

url: http://localhost:49933/api/Person (PUT)


Response Body
    {
      "PersonId": "b269c49f-8a90-41d6-b102-7cfba3812b1c",
      "FirstName": "sample string 2",
      "LastName": "sample string 3",
      "IsActive": true,
      "NumVacationDays": 5,
      "Salary": 6.1
    }

The controller is hit and al

l 除了 NumVacationDays(为 0)和 PersonId(默认为 00000000-0000-0000-0000-000000000000)之外,还会填充数据

有谁知道为什么 GUID 和 int 字段没有从 json 中填充?

【问题讨论】:

    标签: asp.net-mvc-4 asp.net-web-api odata


    【解决方案1】:

    在这个bug中提到了这个问题:http://aspnetwebstack.codeplex.com/workitem/562 ...声称要修复但在刚刚发布的4.0中仍然存在。

    问题在于 Newtonsoft Json 将一个数字反序列化为 Int64,它未能通过 IsAssignable 对 int 的测试,因此它被跳过。 guid 与字符串的类似问题。

    您应该能够通过使用 OData 媒体类型格式化程序来解决此问题,这些格式化程序是通过派生自 ODataController 而不是 ApiController 启用的。但是,这对我没有影响 - int 值仍然不起作用(但是当我将数据类型更改为 Int64 时,它起作用了)。

    我希望看到一个使用包含 int 的补丁增量发布 json 的工作示例。

    【讨论】:

    • 这显然也会影响 DateTimes。您不能使用“2015-06-17T00:00”进行修补,它必须是完整的“2015-06-17T00:00:00.000”。当我对此进行测试时,我注意到 changedProperties 不会返回它可以 Newtonsoft Json 无法反序列化的值(正如 greg 指出的那样),但是当传递 null 时,它总是显示出来。所以用 Null 修补对我来说是一个很好的健全性检查..
    【解决方案2】:

    我可以大胆猜测 PersonId 发生了什么,但无法解释 NumVacationDays。我的猜测是 PersonId 是 Person 实体的关键属性,默认情况下 OD​​ataFormatter 不会修补关键属性。如果您想要这种行为,您可以将 ODataMediaTypeFormatter.PatchKeyMode 上的设置更改为 Patch。

    此外,在操作中查看 person.GetChangedPropertyNames() 的值以查看 PersonId 和 NumVacationDays 是否实际显示在那里会很有趣。

    【讨论】:

    • 嗨拉古拉姆。谢谢回复。只是为了测试你的理论,我添加了两个新列:CompanyId 是一个 guid,NumDaysTaken 是一个 int。两者都作为默认值发送(同上)。 GetChangedPropertyNames 的结果还有其他 4 列(FirstName、LastName、IsActive、Salary)
    • 您是否对 JsonMediaTypeFormatter 使用 Delta 而不是 ODataMediaTypeFormatter?不支持将 Delta 与 json 格式化程序一起使用。我已经测试了 odata 格式化程序以及 guid 和 int 工作。
    • 你好红叶,是的,我是。我将研究 odata 格式化程序。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-10-09
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    • 2022-11-26
    • 2011-04-22
    • 1970-01-01
    相关资源
    最近更新 更多