asp.net mvc web api 部分更新与 OData 补丁 [英] asp.net mvc web api partial update with OData Patch

查看:18
本文介绍了asp.net mvc web api 部分更新与 OData 补丁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 HttpPatch 来部分更新一个对象.为了让它工作,我使用了 OData 的 Delta 和 Patch 方法(这里提到:目前推荐的使用 Web API 执行部分更新的方法是什么?).一切似乎都运行良好,但注意到映射器区分大小写;当传递以下对象时,属性将获得更新的值:

I am using HttpPatch to partially update an object. To get that working I am using Delta and Patch method from OData (mentioned here: What's the currently recommended way of performing partial updates with Web API?). Everything seems to be working fine but noticed that mapper is case sensitive; when the following object is passed the properties are getting updated values:

{
  "Title" : "New title goes here",
  "ShortDescription" : "New text goes here"
}

但是当我传递具有小写或驼峰属性的同一个对象时,Patch 不起作用 - 新值没有通过,所以看起来反序列化和属性映射存在问题,即:shortDescription"到简短描述".

But when I pass the same object with lower or camel-case properties, Patch doesn't work - new value is not going through, so it looks like there is a problem with deserialisation and properties mapping, ie: "shortDescription" to "ShortDescription".

是否有配置部分会使用 Patch 忽略区分大小写?

仅供参考:

在输出时,我使用以下格式化程序具有驼峰式大小写属性(遵循 REST 最佳实践):

On output I have camel-case properties (following REST best practices) using the following formatter:

//formatting
JsonSerializerSettings jss = new JsonSerializerSettings();
jss.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.SerializerSettings = jss;

//sample output
{
  "title" : "First",
  "shortDescription" : "First post!"
}

然而,我的模型类遵循 C#/.NET 格式约定:

My model classes however are follwing C#/.NET formatting conventions:

public class Entry {
  public string Title { get; set;}
  public string ShortDescription { get; set;}
  //rest of the code omitted
}

推荐答案

Short answer, No there is no config option to undo the casesensitiveness (据我所知)

Short answer, No there is no config option to undo the case sensitiveness (as far as i know)

长答案:我今天遇到了和你一样的问题,这就是我解决它的方法.
我发现它必须区分大小写非常烦人,因此我决定取消整个 oData 部分,因为它是一个我们正在滥用的巨大库....

Long answer: I had the same problem as you today, and this is how i worked around it.
I found it incredibly annoying that it had to be case sensitive, thus i decided to do away with the whole oData part, since it is a huge library that we are abusing....

可以在我的 github github

An example of this implementation can be found at my github github

我决定实施我自己的补丁方法,因为那是我们实际上缺乏的肌肉.我创建了以下抽象类:

I decided to implement my own patch method, since that is the muscle that we are actually lacking. I created the following abstract class:

public abstract class MyModel
{
    public void Patch(Object u)
    {
        var props = from p in this.GetType().GetProperties()
                    let attr = p.GetCustomAttribute(typeof(NotPatchableAttribute))
                    where attr == null
                    select p;
        foreach (var prop in props)
        {
            var val = prop.GetValue(this, null);
            if (val != null)
                prop.SetValue(u, val);
        }
    }
}

然后我让我所有的模型类都继承自 *MyModel*.注意我使用 *let* 的那一行,我稍后会解释.所以现在你可以从你的控制器动作中删除 Delta,然后像 put 方法一样让它再次进入.例如

Then i make all my model classes inherit from *MyModel*. note the line where i use *let*, i will excplain that later. So now you can remove the Delta from you controller action, and just make it Entry again, as with the put method. e.g.

public IHttpActionResult PatchUser(int id, Entry newEntry)

您仍然可以像以前一样使用补丁方法:

You can still use the patch method the way you used to:

var entry = dbContext.Entries.SingleOrDefault(p => p.ID == id);
newEntry.Patch(entry);
dbContext.SaveChanges();

现在,让我们回到正题

let attr = p.GetCustomAttribute(typeof(NotPatchableAttribute))

我发现任何属性都可以通过补丁请求更新,这是一个安全风险.例如,您现在可能希望补丁可以更改 ID.我创建了一个自定义属性来装饰我的属性.NotPatchable 属性:

I found it a security risk that just any property would be able to be updated with a patch request. For example, you might now want the an ID to be changeble by the patch. I created a custom attribute to decorate my properties with. the NotPatchable attribute:

public class NotPatchableAttribute : Attribute {}

您可以像使用任何其他属性一样使用它:

You can use it just like any other attribute:

public class User : MyModel
{
    [NotPatchable]
    public int ID { get; set; }
    [NotPatchable]
    public bool Deleted { get; set; }
    public string FirstName { get; set; }
}

在此调用中,Deleted 和 ID 属性无法通过 patch 方法更改.

This in this call the Deleted and ID properties cannot be changed though the patch method.

我希望这也能为您解决问题.如果您有任何问题,请随时发表评论.

I hope this solve it for you as well. Do not hesitate to leave a comment if you have any questions.

我添加了我在一个新的 mvc 5 项目中检查道具的屏幕截图.如您所见,Result 视图填充有 Title 和 ShortDescription.

I added a screenshot of me inspecting the props in a new mvc 5 project. As you can see the Result view is populated with the Title and ShortDescription.

这篇关于asp.net mvc web api 部分更新与 OData 补丁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆