Web API OData v2忽略额外的客户端属性

时间:2016-01-27 16:16:03

标签: odata asp.net-web-api2 sapui5

我很好奇我有哪些选项可以忽略从客户端UI( OpenUI5 )发送到我的后端API的其他属性( ASP.NET Web API OData v1 -3 )。

问题

OpenUI5总是发送一个额外的属性和请求,这会导致一个null参数(我通常有一个public class MainViewModel { private bool _Reset; public bool Reset{ get{ return _Reset;} set {_Reset = value;} } ... } ),以及一个BadRequest响应:

Delta<Models.Item> patch

(服务器端)Models / Item.cs

{
    "error": {
        "code":"",
        "message":{
            "lang":"en-US","value":"The request is invalid."
        },
        "innererror":{
            "message":"patch : The property '__metadata' does not exist on type 'Models.Item'. Make sure to only use property names that are defined by the type.",
            "type":"",
            "stacktrace":""
        }
    }
}

我的客户端库正在public partial class Application { public string Property1 { get; set; } public string Property2 { get; set; } public string Property3 { get; set; } } 发送只有少数已更改的属性,因此我们可以使用WebAPI的HTTP MERGE

我无法控制请求的发送方式(请参阅API documentation for OpenUI5 call here)。我无法控制看起来像这样的出站请求(假设我只更改了对象上的Property1和Property2):

Delta<T>

MERGE http://my-api.com/odata/Items(3)

除了{ "Property1": "ABC", "Property2": "DEF", "__metadata": { "id": "http://my-api.com/odata/Items(3)", "uri": "http://my-api.com/odata/Items(3)", "type": "Models.Item" } } 对象之外,这几乎就是我要发送的内容。我看到一篇类似的帖子,正确的方法(在OData v4中)是允许DynamicProperties(https://stackoverflow.com/a/26312571/569531)。但是,使用UI5,我目前仅限于v2。

问题

在模型绑定期间,是否可以实现MessageHandler,ModelBinder或在传入请求 - 或 - 之前剥离__metadata属性的替代方法?我唯一担心的是MessageHandler将无法修改传入的Request主体,并且由于MERGE / PATCH请求中使用的类型为__metadata,因此创建自定义ModelBinder可能会很困难。 ValueProvider实现可能很困难,但可以接受建议。

1 个答案:

答案 0 :(得分:1)

您可以创建一个继承自原始OData模型的新OData模型。 并覆盖_request函数。

var MyModel = ODataModel.extend("sap.ui.model.rest.MyModel",{
  constructor : function(sServiceUrl, mParameters) {
    ODataModel.apply(this, arguments);
  }
});
MyModel.prototype._request = function(oRequest, fnSuccess, fnError) {
  if (oRequest.data) {
    if (oRequest.data.__metadata) {
      delete oRequest.data.__metadata;
    }
  }
  return ODataModel.prototype._request.apply(this, [oRequest, fnSuccess, fnError]);
};