MVC Razor 동적 모델, ‘개체’에 ‘PropertyName’에 대한 정의가 포함되어 있지 않습니다.

Razor보기 엔진과 함께 MVC 3 사용. 이보기가 있습니다.

@model dynamic
@{
    var products = (List<ListItemBaseModel>)Model.Products;
    var threshold = (int)(Model.Threshold ?? 1);
    var id = Guid.NewGuid().ToString();
}

다음 코드를 사용하여 다른 뷰에서 호출됩니다.

@Html.Partial("PartialViewName", new { Products = Model, Threshold = 5 })

두 뷰 모두에서 디버깅하고 모델을 볼 때 올바른 객체를 포함하는 것 같습니다. 코드를 실행하면 “var products =”줄에 다음과 같은 오류가 표시됩니다.

‘개체’에 ‘제품’에 대한 정의가 없습니다.

누구든지 내가 왜 그 오류가 발생하는지 설명 할 수 있습니까? 다시 말하지만, 디버깅 모드에서 Model 개체를 보면 괜찮아 보입니다 (제품 및 임계 값의 두 가지 속성).



답변

뷰 모델로 익명 클래스의 인스턴스를 전달하고 있습니까? 방금 이것을 시도했고 (CSHTML의 동적 뷰 모델) 익명 클래스를 사용할 때와 동일한 오류가 발생했지만 명명 된 클래스를 만들면 제대로 작동했습니다. 나는 수색했지만 이것이 어디에도 문서화 된 것을 보지 못했습니다.

// error
return View(new { Foo = 1, Bar = "test" });

// worked
return View(new TestClass { Foo = 1, Bar = "test" });

# 1 수정 :

David Ebbo 에 따르면 익명 유형은 .NET Framework 로 컴파일되기 때문에 동적 유형이 지정된 뷰에 익명 유형을 전달할 수 없습니다 internal. CSHTML보기는 별도의 어셈블리로 컴파일되기 때문에 익명 형식의 속성에 액세스 할 수 없습니다.

# 2 수정 :

David Ebbo는 다음과 같은 설명으로 게시물을 편집했습니다.

참고 (2011 년 12 월 22 일) : 이제 MVC 3에서 동적을 직접 지원하므로 아래 기술은 더 이상 필요하지 않습니다. 이 게시물은 사실이 기능을 MVC에 통합하게 된 것입니다!


답변

.NET 4.0에서 익명 유형은 ExpandoObjects로 쉽게 변환 될 수 있으므로 모든 문제는 변환 자체의 오버 헤드로 해결됩니다. 여기에서 확인 하세요


답변

이것은 내부 속성을 가진 익명 유형과는 관련이 없습니다.

이다 완벽하게 가능 부분 뷰에보기에서 익명 형식을 전달하는

나는 오늘 같은 문제에 직면했고 익명 유형 및 고유 internal속성 을 전달하는 문제와 (직접) 관련이 없습니다 .

따라서, OPS 질문과 관련, @Lucas에 의한 대답은 무관하다 – 해결 방법에도 불구하고 작동합니다 .

OPs 질문에서 익명 형식이 어셈블리 X의 뷰에서 어셈블리 X의 부분 으로 전달 되므로 David Ebbo가 익명 형식의 내부 속성에 대해 설명한 문제는 중요하지 않습니다. 뷰에 대해 컴파일 된 형식, 부분 형식 및 익명 형식은 모두 동일한 어셈블리에 포함 됩니다.

그렇다면 뷰에서 파셜로 익명 유형을 전달하는 데 갑자기 실패하는 원인은 무엇입니까?

적어도 상황에서는 해결할 수없는 모델 유형을 지정하는 SAME FOLDER에 다른보기 가 있다는 것을 발견했습니다 . 뷰는 런타임에 컴파일되므로 런타임에 뷰를 컴파일하는 데 실패하면 동적 유형을 컴파일하는 데 실패하고 부분은 단순히 object. 무슨 일이 일어나고 있는지 즉시 명확하지 않지만 OP의 특정 예 (및 내)에서는 이것이 문제의 원인 일 가능성이 높습니다.

모델 유형이 정확하지만 뷰의 다른 부분이 컴파일되지 않으면 익명 유형이 동일한 방식으로 영향을받지 않는다는 점이 흥미 롭습니다. 이것은 Razor가 뷰의 구성 요소 부분의 동적 컴파일을 어떻게 분리하는지에 달려 있습니다.

문제가되는 뷰를 수정 한 후에는 전체 솔루션을 다시 빌드하거나 프로젝트가 수정되었는지 확인하기 전에 정리하고 다시 빌드하십시오.

이 문제에 다시 걸리지 않도록 csproj파일에 다음 을 추가하여 Razor 뷰의 컴파일 시간 컴파일을 활성화 할 수 있습니다 .

<PropertyGroup>
    <MvcBuildViews>true</MvcBuildViews>
</PropertyGroup>


답변

솔루션의 아무 곳에 나 다음 클래스를 추가합니다 (시스템 네임 스페이스를 사용하여 참조를 추가하지 않고도 사용할 수 있음)-

    namespace System
    {
        public static class ExpandoHelper
        {
            public static ExpandoObject ToExpando(this object anonymousObject)
            {
                IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(anonymousObject);
                IDictionary<string, object> expando = new ExpandoObject();
                foreach (var item in anonymousDictionary)
                    expando.Add(item);
                return (ExpandoObject)expando;
            }

        }
    }

모델을 뷰로 보낼 때 Expando로 변환하십시오.

    return View(new {x=4, y=6}.ToExpando());


답변

dynamic부분보기 내 에서 모델 유형 을 사용하는 대신 .

@ViewData.Eval("foo")대신을 사용하여 익명 개체 속성을 호출 할 수 있습니다 @Model.foo.

그런 다음 @Model dynamic보기에서 제거 할 수 있습니다.

최근 Facebook 소셜 댓글 통합을 위해보기간에 몇 가지 속성을 전달할 때이 문제를 발견했습니다. 예제 코드 :

Html.RenderPartial(@"Layouts/Partials/_Comments", new {currentUrl = Model.CurrentPage.GetAbsoluteUrl(), commentCount = 5 });

그런 다음 내 관점에서 방금이 div가 있습니다.

<div class="fb-comments" data-href="@ViewData.Eval("currentUrl")" data-numposts="@ViewData.Eval("commentCount")" data-width="100%"></div>


답변

해결 방법을 구현하지 않았기 때문에이 오류가 발생하는지 잘 모르겠습니다. 부분보기에서 동일한 오류가 발생했습니다. 해결책은 빌드를 정리하고 다시 빌드하는 것입니다. 구문이 올 바르면 코드가 작동하지만 면도기 엔진이 코드 변경 사항을 제대로 업데이트하지 않을 수 있습니다.


답변

사전을 사용하여이 문제를 해결했습니다.

 @Html.Partial("_Partial", new Dictionary<string, string> { { "Key1", "Val1" }, { "Key2", "Val2" }, { "Key3", "Val3" } });