如何使用Microsoft ASP.NET Web API OData中的Delta <t>与Code First \ JsonMediaTypeFormatter </t>

时间:2013-02-06 12:35:55

标签: c# rest asp.net-web-api odata

有什么问题?

我正在尝试在我的ASP.net web api应用程序中启用修补程序。我正在使用代码第一实体框架。

我有以下方法标题,我可以设置一个断点,它会点击:

[AcceptVerbs("PATCH")]
public async Task<HttpResponseMessage> Patch(long appId, long id, Delta<SimpleFormGroup> formGroup)

但是当我调用formGroup.Patch(entity)时,我的实体没有任何更改。如果我将以下内容放入即时窗口:

formGroup.GetChangedPropertyNames()

然后这个集合是空的,这似乎是错误的。

我尝试了什么?

我一直在提到以下示例

http://techbrij.com/http-patch-request-asp-net-webapi http://www.strathweb.com/2013/01/easy-asp-net-web-api-resource-updates-with-delta/

Json MediaType Formatter似乎不知道如何正确构建Delta对象,但是在第二个链接中,filip似乎表明它应该在没有oDataMediaTypeFormatter的情况下工作。

我已经开始试图将我的模型序列化为EDMX表示,然后从那里提取CSDL以便我可以创建一个oDataMediaTypeFormatter,但我也遇到了障碍,加上它似乎有点矫枉过正。

如果有人能对此有所了解,那就非常感激了。如果需要更多信息,请告诉我。

修改

以下是SimpleFormGroup的类定义:

public class SimpleFormGroup
{
    public int LastUpdate;

    public string Identifier;

    public string Title;

    public int DisplayOrder;
}

以下是我发送的数据:

Content-Type: 'application/json'

{ "DisplayOrder" : "20 }

谢谢,皮特

2 个答案:

答案 0 :(得分:8)

有趣的是,看起来像Delta<T>的int成员在JSON中不起作用。

不幸的是,Delta<T>是专门为OData创建的。如果Delta<T>似乎与除OData之外的任何格式化程序一起使用,那么这是巧合而不是故意的。

好消息是,没有什么可以阻止你为JSON定义自己的PATCH格式,如果没有人编写过一个可以更好地使用Json.NET的人,我会感到惊讶。我们可能会在未来的Web API版本中重新修改补丁,并尝试提出一个适用于格式化程序的一致故事。

答案 1 :(得分:4)

感谢Youssef调查并发现为什么事情不起作用。希望能够解决这个问题。

在仔细研究了oData包源之后,我终于自己解决了这个问题。我选择实现另一个包含逻辑的MediaTypeFormatter,因为它提供了对HttpContent的轻松访问,但还有其他方法可以实现这一点。

关键部分是弄清楚如何解释代码第一模型,请参阅下面的注释行:

public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
    var builder = new ODataConventionModelBuilder();

    // This line will allow you to interpret all the metadata from your code first model
    builder.EntitySet<EfContext>("EfContext");

    var model = builder.GetEdmModel();
    var odataFormatters = ODataMediaTypeFormatters.Create(model);
    var delta = content.ReadAsAsync(type, odataFormatters).Result; 

    var tcs = new TaskCompletionSource<object>(); 
    tcs.SetResult(delta); 
    return tcs.Task; 
}

希望这可以节省一些人的麻烦!