最好的办法部分更新ASP.NET MVC模式(“合并”用户提交的与模型的形式) [英] Best way to do partial update to ASP.NET MVC model ('merge' user submitted form with model)

查看:287
本文介绍了最好的办法部分更新ASP.NET MVC模式(“合并”用户提交的与模型的形式)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是basicially一样的情况presented在这个堆栈溢出问题,我多么希望自己从数据库加载模型的现有的有效版本,以及更新的领域的某个子集它的一部分暴露我的网页形式。

My question is basicially the same as the situation presented in this stack overflow question where I find myself wanting to load the existing valid version of model from the DB, and update a portion of it as a certain sub-set of fields are exposed on my web form.

反正我可以让我的ID属性将首先被绑定的模型绑定工艺保证?

Is there anyway I can make the Model Binding process guarantee that my ID property will be bound first?

如果我能保证这一点的话,我的视图模型的ID setter方法​​里面,我可能会引发'负荷',让对象最初从DB(或WCF服务..或XML文件填充。 。或选择的其他资料库),然后从表单提交后剩余财产整齐地融入对象MVC完成了它的模型绑定过程。

If I could guarantee this one thing, then, inside the setter of my ViewModel's ID property, I could trigger a 'load', so that the object is initially populated from the DB (or WCF service.. or Xml file.. or other repository of choice) and then the remaining properties submitted from the FORM post neatly merge into the object as MVC finishes up it's model binding process.

然后,我IValidatableObject.Validate方法逻辑将很好地告诉我,如果得到的对象仍然是有效的..等等等等..

Then, my IValidatableObject.Validate method logic will nicely tell me if the resulting object is still valid.. and so forth and so on..

它只是在我看来,不必编写管道,我必须手动(knownValidDomainModelInstanceFromStorage,postedPartialViewModelInstanceFromForm)模型的两个实例,然后通过所需的属性映射是重复的东西,真的是已经被处理的MVC ......如果我能只控制身份的绑定顺序。

It just seems to me that having to write plumbing where I have two instances of a model(knownValidDomainModelInstanceFromStorage, postedPartialViewModelInstanceFromForm) and then manually mapping over desired properties is to repeat something that is really already handled by MVC... if I could only control the binding order of the identity.

编辑 - 我发现属性绑定以便可以用自定义粘结剂进行操作。很容易。阅读下面我公布答案。仍然欢迎您提供反馈或意见。

EDIT - I discovered property binding order CAN be manipulated with a custom binder. Very easily. Read the answer I posted below. Would still welcome your feedback or observations.

推荐答案

好吧,就如何定制默认的模型绑定看完后,我觉得code的该位才可能做到分类属性的伎俩每一次都会给我所需要的绑定顺序。基本上让我先绑定的标识属性(因此让我有我的视图模型触发一个负载),允许模型绑定过程的其余部分合并基本上发挥作用!

Ok, after reading up on how to customize the default model binder, I think this bit of code just may do the trick of sorting the properties and will give me the desired binding order every time. Basically allowing me to bind the identity properties first (and thus allowing me to have my View Model trigger a 'load') allowing the remainder of the model binding process to function essentially as a merge!

''' <summary>
''' A derivative of the DefaultModelBinder that ensures that desired properties are put first in the binding order.
''' </summary>
''' <remarks>
''' When view models can reliably expect a bind of their key identity properties first, they can then be designed trigger a load action 
''' from their repository. This allows the remainder of the binding process to function as property merge.
''' </remarks>
Public Class BindIdFirstModelBinder
        Inherits DefaultModelBinder

    Private commonIdPropertyNames As String() = {"Id"}
    Private sortedPropertyCollection As ComponentModel.PropertyDescriptorCollection

    Public Sub New()
        MyBase.New()
    End Sub

    ''' <summary>
    ''' Use this constructor to declare specific properties to look for and move to top of binding order.
    ''' </summary>
    ''' <param name="propertyNames"></param>
    ''' <remarks></remarks>
    Public Sub New(propertyNames As String())
        MyBase.New()
        commonIdPropertyNames = propertyNames
    End Sub

    Protected Overrides Function GetModelProperties(controllerContext As ControllerContext, bindingContext As ModelBindingContext) As ComponentModel.PropertyDescriptorCollection
        Dim rawCollection = MyBase.GetModelProperties(controllerContext, bindingContext)

        Me.sortedPropertyCollection = rawCollection.Sort(commonIdPropertyNames)

        Return sortedPropertyCollection
    End Function

End Class

然后,我可以代替我DefaultModelBinder的注册,并提供我想有最常见的属性名称'漂浮'的ModelBinding过程的顶部...

Then, I can register this in place of my DefaultModelBinder, and supply the most common property names that I'd like to have 'floated' to the top of the ModelBinding process...

    Sub Application_Start()

            RouteConfig.RegisterRoutes(RouteTable.Routes)
            BundleConfig.RegisterBundles(BundleTable.Bundles)
            ' etc... other standard config stuff omitted...
            ' override default model binder:
            ModelBinders.Binders.DefaultBinder = New BindIdFirstModelBinder({"Id", "WorkOrderId", "CustomerId"})
    End Sub

这篇关于最好的办法部分更新ASP.NET MVC模式(“合并”用户提交的与模型的形式)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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