2014-10-28 6 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", ... }); 

그리고 리팩토링에서이 영역을 놓쳤습니다. 꽤 당혹 스럽지만 다른 누군가가 벽을 치고 머리를 때리면 그만한 가치가 있습니다 :-)