ASP.NET MVC(4) - 按特定顺序绑定属性

Mik*_*der 5 asp.net-mvc asp.net-mvc-3 asp.net-mvc-2 asp.net-mvc-4

有没有办法在C之前强制绑定属性A和B?

System.ComponentModel.DataAnnotations.DisplayAttribute类中有Order属性,但它是否会影响绑定顺序?

我想要实现的是

page.Path = page.Parent.Path + "/" + page.Slug
Run Code Online (Sandbox Code Playgroud)

在自定义的ModelBinder中

Dan*_*ous 0

我最初会推荐 Sams 答案,因为它根本不涉及 Path 属性的任何绑定。您提到可以使用 Path 属性连接这些值,因为这会导致延迟加载发生。因此,我想您正在使用域模型向视图显示信息。因此,我建议使用视图模型仅显示视图中所需的信息(然后使用 Sams 答案检索路径),然后使用工具(即AutoMapper)将视图模型映射到域模型。

但是,如果您继续在视图中使用现有模型并且无法使用模型中的其他值,则可以在其他绑定发生后将路径属性设置为自定义模型绑定程序中表单值提供程序提供的值(假设不对路径属性执行验证)。

因此,假设您有以下观点:

@using (Html.BeginForm())
{
    <p>Parent Path: @Html.EditorFor(m => m.ParentPath)</p>
    <p>Slug: @Html.EditorFor(m => m.Slug)</p>
    <input type="submit" value="submit" />
}
Run Code Online (Sandbox Code Playgroud)

以及以下视图模型(或域模型,视情况而定):

公共类 IndexViewModel { 公共字符串 ParentPath { 获取;放; } 公共字符串 Slug { 获取;放; } 公共字符串路径 { 获取;放; } }

然后您可以指定以下模型绑定器:

public class IndexViewModelBinder : DefaultModelBinder
    {
        protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            //Note: Model binding of the other values will have already occurred when this method is called.

            string parentPath = bindingContext.ValueProvider.GetValue("ParentPath").AttemptedValue;
            string slug = bindingContext.ValueProvider.GetValue("Slug").AttemptedValue;

            if (!string.IsNullOrEmpty(parentPath) && !string.IsNullOrEmpty(slug))
            {
                IndexViewModel model = (IndexViewModel)bindingContext.Model;
                model.Path = bindingContext.ValueProvider.GetValue("ParentPath").AttemptedValue + "/" + bindingContext.ValueProvider.GetValue("Slug").AttemptedValue;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

最后通过在视图模型上使用以下属性来指定要使用此模型绑定器:

[ModelBinder(typeof(IndexViewModelBinder))]
Run Code Online (Sandbox Code Playgroud)