【问题标题】:Web API OData v2 Ignore Extra Client-Side PropertiesWeb API OData v2 忽略额外的客户端属性
【发布时间】:2016-01-27 16:16:02
【问题描述】:

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


问题

OpenUI5 总是发送一个附加属性以及导致空参数的请求(我通常有一个 Delta<Models.Item> patch)和一个 BadRequest 响应:

{
    "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":""
        }
    }
}

(服务器端)模型/Item.cs

public partial class Application
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }
    public string Property3 { get; set; }
}

我的客户端库正在发送一个 HTTP MERGE,其中只有几个属性发生了变化,因此我们可以使用 WebAPI 的 Delta<T>

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

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"
    }
}

这几乎正是我想要发送的内容,__metadata 对象除外。我看到了一个类似的帖子,正确的方法(在 OData v4 中)是允许 DynamicProperties (https://stackoverflow.com/a/26312571/569531)。但是,使用 UI5,我目前仅限于 v2。


问题

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

【问题讨论】:

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


    【解决方案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]);
    };
    

    【讨论】:

    • 我喜欢这种方法,因为它让客户端有责任与后端系统一起工作,而不是让后端系统为特定客户端工作。但是,我会对后端的一种方法感兴趣,该方法也忽略与预期传入类型不匹配的属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 2021-01-20
    相关资源
    最近更新 更多