我很好奇我可以忽略从客户端UI(OpenUI5)发送到我的后端API(ASP.NET Web API OData v1-3)的其他属性.
问题
OpenUI5总是发送一个额外的属性和请求,这会导致一个null参数(我通常有一个Delta< Models.Item>补丁),以及一个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":""
}
}
}
(服务器端)Models / 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将无法修改传入的Request主体,并且由于MERGE / PATCH请求中使用的类型是Delta< T>,因此创建自定义ModelBinder可能很困难. ValueProvider实现可能很困难,但可以接受建议.
最佳答案 您可以创建一个继承自原始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]);
};