2012-04-27 60 views
5

有没有办法在C之前强制绑定属性A和B?ASP.NET MVC(4) - 以特定顺序绑定属性

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

我想要做到的,是

page.Path = page.Parent.Path + "/" + page.Slug 
在自定义

ModelBinder的

+0

我是否正确地说,“page.Parent.Path'和'page.Slug'被绑定到表单中,并且你希望'page.Path'在绑定发生后立即被设置为它们内容的连接?即表单中不存在'page.Path'值? – Dangerous 2012-04-27 13:33:54

+0

@危险正确,'page.Path'不在窗体上。我从表单中获得'page.Parent.Id'和'page.Slug'。 – 2012-04-28 07:23:15

+0

我想在'page.Parent'和'page.Slug'绑定后建立'page.Path'。 – 2012-04-28 07:32:25

回答

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" /> 
} 

而下面的视图模型(或视情况而定域模型):

公共类IndexViewModel { 公共字符串ParentPath {得到;组; } public string Slug {get;组; } public string Path {get;组; } }

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

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; 
      } 
     } 
    } 

最后指定该模型绑定是通过使用视图模型以下属性可用于:

[ModelBinder(typeof(IndexViewModelBinder))] 
1

为什么不实行Page属性为:

public string Path{ 
    get { return string.Format("{0}/{1}", Parent.Path, Slug); } 
} 

+0

这会导致所有页面的祖先逐个加载。例如。如果您显示10个页面(每个层次中的层次3),这可能会导致额外的20个查询到数据库。 – 2012-04-28 07:10:43