且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

asp.net mvc web api 部分更新与 OData 补丁

更新时间:2023-02-16 13:52:30

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.