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


106

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 개체를 보면 괜찮아 보입니다 (제품 및 임계 값의 두 가지 속성).


답변:


150

뷰 모델로 익명 클래스의 인스턴스를 전달하고 있습니까? 방금 이것을 시도했고 (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에 통합하게 된 것입니다!


1
이 편집은 알아서 반갑습니다. 나는 똑같은 문제가 있었고 거기에서 WTF를 이해하지 못했습니다. 설명 해주셔서 감사합니다.
Yanick Rochon 2013 년

18
편집 # 2는 이제 (MVC> 3) "오류"로 표시된 줄을 수행 할 수 있음을 제안합니다. return View(new { Foo = 1, Bar = "test" });? MVC 4를 사용하고 있지만 여전히 "개체에 Foo에 대한 정의가 포함되어 있지 않습니다"라는 메시지가 표시되기 때문에
sports

@sports 저도 ... 해결 방법을 찾았습니까? ( ToExpando하나 옆에 )
Alex

2
이제 2018 년에 ASP.NET Core 2.1 및 Razor보기를 사용하여 원래 질문의 오류가 여전히 나를 물고 있음을 알았습니다. 그래서 나는 MVC 3이 이것을 고치는 것에 대한 이야기가 무엇인지 모르겠습니다.
Andrew Arnott

41

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


아니에요. 아마도 이것은 익명 유형을 더 유용하게 만들기 위해 M $를 차게 할 것입니다
Adaptabi

이것은 Partials에도 적용됩니까?
Partials를

1
어떤 부분? 예를 들어 줄 수 있습니까?
Adaptabi

27

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

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

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

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

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

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

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

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

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

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

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

2
이로 인해 문제가 해결되었습니다. "@model dynamic"을 사용하는 것이 처음에는 올바른 수정처럼 보였지만 실제로는 잘못된 길을 택했습니다.
크림 보 2014 년

솔루션을 정리하고 다시 빌드했는데 오류가 사라졌습니다. 121 개 투표가 잘못되었습니다.
maxbeaudoin 2014-08-27

MVC 3 이후 동적 뷰 모델에 대한 MVC의 지원을 반영하기 위해 내 답변을 업데이트했습니다.
Lucas

때때로 뷰 컴파일을 활성화하는 것은 거대한 코드베이스에 항상 유용합니다. T4MVC가 도입 한 강력한 타이핑 덕분에 모든 종류의 문제, 오타, 오류를 공개합니다.
Denis The Menace

아, 맞다 : 방금 우리가 뷰에서 파셜로 넘어가는 것에 대해 이야기하고 있다는 것을 알아 차 렸습니다. 컨트롤러에서 뷰로가 아니라 내 문제입니다.
mwardm

9

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

    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());

1
먼저 동적 개체를 만든 다음 ExpandoObject를 만드는 데 불필요한 오버 헤드처럼 보입니다 ... 대신 ExpandoObject를 만듭니다.
Baz1nga

@ Baz1nga 당신은 할 수 없습니다 ... new Expando () {prop = value, ...}, 그것은 문제를 만듭니다. 비슷한 용도로 Json.Net의 JObject를 사용하고 있습니다.
Tracker1 jul.

3
거기에 HtmlHelper가있는 것은 잘못된 느낌입니다 ... public static ExpandoObject ToExpando (this object o) {IDictionary <string, object> expando = new ExpandoObject (); foreach (var propertyInfo in o.GetType (). GetProperties ()) {expando.Add (new KeyValuePair <string, object> (propertyInfo.Name, propertyInfo.GetValue (o, index : null))); } return (ExpandoObject) expando; }
erlando

6

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>

0

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


0

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

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

-6

dynamic유형 을 사용하려면 Microsoft.CSharp어셈블리 를 참조해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.