2014-10-28 33 views
0

所以我有这个观点,它是由CMS生成的。视图的大脑在RenderAction呈现的另一个视图中。视图模型中的嵌套对象会混淆MVC 4路由吗?

直到现在它已经是这样的:

Main.cshtml

<div>CMS content</div> 
@{ 
    var myContent = new MainContentModel() { 
     SomethingUsedFurtherDown = "Easier for CMS people to edit" 
    } 

    Html.RenderAction("_Main", "Foo", new { arg1 = "this", arg2 = "that", content = myContent }); 
} 

MainContentModel.cs

namespace MyApp.Services.ViewModels.Foo 
{ 
    public class MainContentModel 
    { 
     public string SomethingUsedFurtherDown { get; set; } 
    } 
} 

MainViewModel.cs

namespace MyApp.Services.ViewModels.Foo 
{ 
    public class MainViewModel 
    { 
     public string Arg1 { set; set; } 
     public string Arg2 { set; set; } 

     public string Name { get; set; } 
     public string Age { get; set; } 
     public string Address { get; set; } 

     public MainContentModel Content { get; set; } 
    } 
} 

_Main.cshtml

@model MyApp.Services.ViewModels.Foo.MainViewModel 

@Html.EditorFor(m => m.Name) 
@Html.EditorFor(m => m.Age) 
@Html.EditorFor(m => m.Address) 

<!-- whatever - doesn't matter --> 

FooController.cs

namespace My.App.Controllers 
{ 
    using System; 
    using System.Web.Mvc; 

    public class FooController 
    { 
     public ActionResult Main(string arg1, string arg2, MainContentModel cm) 
     { 
      var vm = new MainViewModel() { Arg1 = arg1, Arg2 = arg2, Content = cm }; 
      return this.View("_Main", vm); 
     } 
    } 
} 

一切工作正常。那么我为什么打扰你?那么,这显然不是真正的代码。控制器方法有更多的参数,它们都变得相当混乱。所以我想我会从外部视图传入视图模型。

Main.cshtml

<div>CMS content</div> 
@{ 
    var myVM = new MainViewModel() { 
     Arg1 = "this" 
     , Arg2 = "that" 
     , Content = new MainContentModel() { 
      SomethingUsedFurtherDown = "Easier for CMS people to edit" 
     } 
    }; 

    Html.RenderAction("_Main", "Foo", new { vm = myVM }); 
} 

...,只是有一个参数传递给控制器​​的方法

FooController.cs

namespace My.App.Controllers 
{ 
    using System; 
    using System.Web.Mvc; 

    public class FooController 
    { 
     public ActionResult Main(MainViewModel vm) 
     { 
      return this.View("_Main", vm); 
     } 
    } 
} 

这就是麻烦开始的地方。我得到这个错误:

The view '_Main' or its master was not found or no view engine supports the searched locations. The following locations were searched: 
~/Views/Foo/_Main.aspx 
~/Views/Foo/_Main.ascx 
~/Views/Shared/_Main.aspx 
~/Views/Shared/_Main.ascx 
~/Views/Foo/_Main.cshtml 
~/Views/Foo/_Main.vbhtml 
~/Views/Shared/_Main.cshtml 
~/Views/Shared/_Main.vbhtml 
~/Views/CMS/_Main.cshtml 
~/Views/CMS/Foo/_Main.cshtml 

但是,如果我删除内容模型的初始化,它都会再次运行。好吧,好吧,工作工作。但是错误消失了,让我想出了将内容模型添加到参数列表并将其分配给控制器方法中的视图模型的明显解决方案。

Main.cshtml

<div>CMS content</div> 
@{ 
    var myVM = new MainViewModel() { 
     Arg1 = "this" 
     , Arg2 = "that" 
    }; 
    var myCm = new MainContentModel() { 
      SomethingUsedFurtherDown = "Easier for CMS people to edit" 
    }; 

    Html.RenderAction("_Main", "Foo", new { vm = myVM, cm = myCm }); 
} 

FooController.cs

namespace My.App.Controllers 
{ 
    using System; 
    using System.Web.Mvc; 

    public class FooController 
    { 
     public ActionResult Main(MainViewModel vm, MainContentModel cm) 
     { 
      vm.Content = cm; 
      return this.View("_Main", vm); 
     } 
    } 
} 

除了有相当的现实视图模型的几个子对象,我不这很好希望将这些分离出来作为论据 - 它打破了本来应该是一个整理练习的目的。

问题

是MVC4应该是结合子对象无缝,这是一个错误?或者它不是以这种方式工作,我唯一的选择是将它们分离成上述的额外参数?

干杯, .pd。

回答

0

以防其他人陷入这个陷阱。问题不是模型绑定。 MVC 4很好地绑定了嵌套对象。我错过了错误的微妙之处。这里的标准是在“真实”视图名称前加一个下划线,这是这个没有找到。该故障是发生在这里:

return this.View("_Main"); 

我没有在我的岗位包括(曲子如果我还记得,那会已经定了!)是事实的真实情况RenderAction样子这个:

RenderAction("Main", "Foo", new { area = "SomeArea", ... }); 

而我错过了我的重构领域。相当尴尬,但如果它阻止别人在墙上跳动他们的头然后耻辱将是值得的:-)