2009-07-24 6 views
12

이것이 가능합니까?동적 유형의 ViewPage

public ActionResult Index() 
    { 
     dynamic p = new { Name = "Test", Phone = "111-2222" }; 
     return View(p); 
    } 

을 그리고 내보기 System.Web.Mvc.ViewPage<dynamic>에서 상속 및 Model.Name을 인쇄하려고 : 여기에 내가 노력하고있어입니다. 난 그냥 불가능 할 노력하고있어 무엇, 그래서 기본적으로 인해

의 보호 수준

에 '<> f__AnonymousType1.Name이'액세스 할 수 없습니다 :

나는 오류를 받고 있어요? 그 이유는 무엇?

업데이트 : 여기

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %> 

<asp:Content ...> 
    <%=Model.Name%> 
    <%=Model.Phone%> 
</asp:Content> 

보기 생성자가 내장 된 프레임 워크 내보기입니다.

+1

당신이 코드의 자세한 내용을 게시 할 수 확인 ? 보기에 특히 생성자를보고 싶습니다. – Randolpho

+1

Phil Haack의 블로그 게시물 링크가있는 최신 업데이트를 확인하십시오. – CoderDennis

답변

7

익명 형식은 메서드에서 반환 할 수 없습니다. 정의 된 메소드의 범위 내에서만 유효합니다.

이전에 정의한 Model 클래스를 사용하여 View에 전달해야합니다. 모든 필드가 정의되어 있지 않은 Model 클래스를 전달하는 것은 아무 문제가 없습니다.

업데이트 :

나는 한번도 잘못 생각합니다. 이것은 효과가있다. 아마도 문제는보기 내에 있습니다. 더 많은 코드를 게시 할 수 있습니까? 특히 View와 그 생성자.

업데이트 둘째 :

좋아, 나는 동적 변수로 사용하기 위해 다른 방법에 익명 형식을 전달하는 방법에 대한 잘못 - 할 수있다.

그러나 나는 또한 당신이하려고하는 것이 효과가있을 것이라는 나의 믿음으로 잘못되었습니다. 불행히도 당신에게는 그렇지 않습니다. 문제는 내부적으로 ViewDataDictionary<TModel>을 사용하는 ViewPage<TModel>을 사용하고 있다는 것입니다. 강력한 유형이 필요하기 때문에 강력한 유형을 사용할 수 없습니다. 내부 구조는 내부적으로 동적 인 것을 사용하지 않고, 타입이 실패 할 때 동적 인 것을 지정합니다.

DynamicViewPage 클래스와 이에 해당하는 DynamicViewDataDictionary 클래스가 있으며 object을 허용하고 내부적으로 동적으로 저장하는 클래스가 필요합니다. 그런 다음 익명 형식을 사용하여 뷰에 전달할 수 있습니다.

즉, 아무 것도 얻지 못할 것이라고 말했습니다. 이전과 마찬가지로 조회수를 지정할 수는 있지만 (예 : <%=Model.Name%>) 강력한 입력의 이점은 없습니다. 인텔리 센스가 없으며 형식 안전성이 없습니다. @Dennis Palmer가 제안한대로 형식이 지정되지 않은 ViewDataDictionary을 사용하는 것이 좋습니다.

이것은 흥미로운 (그리고 불행히도 나를 흡수하는) 사고 실험 이었지만 궁극적으로는 그렇게되지 않을 것이라고 생각합니다. 공개 형식을 선언하고보기에 전달하거나 형식이없는 사전을 사용하십시오.

+1

하지만 리플렉션을 통해 객체의 멤버에 액세스 할 수 있으므로 동적 타이핑이 효과적 일 수 있다고 생각한 것입니다. –

+1

음 ...뷰에서 익명 형식이 전달되지만 Name의 기본 보호 수준은 보호되거나 비공개임을 나타내는 오류가 발생합니다. 또한 익명 형식을 선언 할 때 보호 수준을 지정할 수 없습니다. – Randolpho

+0

좋아요, 업데이트를 게시했습니다. –

7

여기서 동적 유형을 사용하면 어떤 이점이 있습니까?

ViewData 사전을 사용하면 매우 쉽게 임의의 개체/항목을보기 출력에 추가 할 수 있습니다.

보기 내에서 속성 이름을 가져 오기 위해 리플렉션을 수행 할 필요가 없습니다. ViewData.Keys을 사용하면 이름 모음을 얻을 수 있습니다.

편집 : 난 그냥 내 자신 역학에 대해 조금 더 배운 내가 어쩌면 당신이 DynamicObject에서 상속 자신의 동적 객체 클래스를 만들 필요가 있다고 생각합니다. 해당 클래스에 비공개 사전이 있고 TrySetMemberTryGetMember을 무시하고 싶을 것입니다.

편집 : 강력한 형식의 ViewModel의 한 가지 이점은 POST Action 메서드의 매개 변수로 받아 들일 수 있다고 생각합니다. MVC 프레임 워크는 모델 바인딩을 처리 할 것이고 액션 메소드에서 ViewModel 클래스의 인스턴스를 간단히 가질 수 있습니다. 나는 그들이 일을해도 당신이 역동적 인면에서 이점을 얻지 못할 것이라고 생각합니다.

편집 결과 : 글쎄, DynamicObject에서 파생 된 클래스를 사용했지만 뷰를 렌더링하려고 할 때 VS2010이 충돌합니다. 어떤 예외도 발생하지 않으며 하드 충돌이 발생하고 Visual Studio가 다시 시작됩니다. 충돌을 일으킨 원인은 다음과 같습니다.

사용자 정의 동적 클래스 : 컨트롤러에서

public class DynViewModel : DynamicObject 
{ 
    private Dictionary<string, object> ViewDataBag; 
    public DynViewModel() 
    { 
     this.ViewDataBag = new Dictionary<string, object>(); 
    } 
    public override bool TrySetMember(SetMemberBinder binder, object value) 
    { 
     this.ViewDataBag[binder.Name] = value; 
     return true; 
    } 
    public override bool TryGetMember(GetMemberBinder binder, out object result) 
    { 
     result = this.ViewDataBag[binder.Name]; 
     return true; 
    } 
} 

:

public ActionResult DynamicView() 
{ 
    dynamic p = new DynamicViewModel.Models.DynViewModel(); 
    p.Name = "Test"; 
    p.Phone = "111-2222"; 

    return View(p); 
} 

내보기는 기본적으로 질문에 나열된 것과 동일합니다

<p>Name: <%=Model.Name %></p> 
<p>Phone: <%=Model.Phone %></p> 

내 결론 :이 방법이 효과가있을 수 있지만 VS2010의 베타 1에서는 내 코드로 인해 Visual Studio가 중단되는 이유를 찾아냅니다. 역학을 배우는 흥미로운 연습이기 때문에 VS2010 베타 2에서 다시 시도해 보겠습니다. 그러나 이것이 작동한다고해도 ViewData 사전을 사용하는 것보다 여전히 이점이 없습니다.

Phil Haack을 구하기 위해! Phil Haack의 블로그 게시물을 통해 도움을받을 수 있습니다. 그것은 당신이 찾고 있었던 것처럼 보입니다. Fun With Method Missing and C# 4

+0

음, 아직 100 % 확신 할 수는 없지만 4.0으로 약간 실험하고 있습니다. 내가보기에는 ViewModel을 명시 적으로 작성하지 않고 ViewModel 패턴을 사용할 수있는 기능이 있지만 C#의 동적 유형 지정에 대한 더 깊은 이해를 얻으려고합니다. –

1

여기서 실제 오류 (<>f__AnonymousType1.Name' is inaccessible due to its protection level)는 익명의 유형을 사용한 결과이다. 익명 형식은 암시 적으로 internal (적어도 C#에서는)이므로 동일한 어셈블리에서만 정상적으로 액세스 할 수 있습니다. 보기가 런타임에 별도의 어셈블리으로 컴파일되므로 익명 유형 internal에 액세스 할 수 없습니다.

해결 방법은 콘크리트/명명 된 클래스를 모형으로 모델에 전달하는 것입니다. 원하는 경우보기 자체에서 dynamic을 계속 사용할 수 있습니다.

1

.NET 4.0 익명 형식은 쉽게 ExpandoObjects로 변환 될 수 있으므로 모든 문제는 변환 자체의 오버 헤드로 수정됩니다. here