簡體   English   中英

ASP.NET MVC-將動態ExpandoObject從控制器傳遞到視圖時出現RuntimeBinderException

[英]ASP.NET MVC - RuntimeBinderException when passing dynamic ExpandoObject from Controller to View

由於無法將多個模型傳遞給ASP.NET MVC 4中的視圖,因此我試圖將各種模型填充到動態ExpandoObject ,然后從視圖中解壓縮它。

我的模型 (不僅僅包括此類,而且為簡單起見,我將僅顯示此模型):

public class Modular_ArtistModel
{
    public string Artist_Name { get; set; }
}

我的控制器:(我不僅將這個List<>對象打包到dynamic對象中,但是為了簡潔起見...)

dynamic ArtistModel = new ExpandoObject();

        var Modular_ArtistModel = LoadSP_Modular_ArtistModel("sp_Mod_Artist_Artist", i);
        List<Modular_ArtistModel> mod_ArtistModel = new List<Modular_ArtistModel>();
        foreach (var row in Modular_ArtistModel)
        {
            mod_ArtistModel.Add(new Modular_ArtistModel
            {
                Artist_Name = row.Artist_Name
            });
        }
        ArtistModel.Artist = mod_ArtistModel;

我的視圖:(這是視圖中的第一件事,程序在以下分配中令人窒息)

@model dynamic
@{
string artist_Name = Model.Artist.Artist_Name;
}

當光標到達View層中的上述分配時,它將引發以下異常:

'Model.Artist.Artist_Name' threw an exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146233088
HelpLink: null
InnerException: null
Message: "'System.Collections.Generic.List<....Models.Modular_ArtistModel>' does not contain a definition for 'Artist_Name'"
Source: "Anonymously Hosted DynamicMethods Assembly"
StackTrace: "   at CallSite.Target(Closure , CallSite , Object )\r\n   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)"
TargetSite: {System.Object CallSite.Target(System.Runtime.CompilerServices.Closure, System.Runtime.CompilerServices.CallSite, System.Object)}

有誰知道我需要做些什么來解決這個問題? 不知道這是快速修復還是更廣泛的重新設計。

您發送列表藝術家,但嘗試獲取一位藝術家,則應更改此設置

string artist_Name = Model.Artist.Artist_Name;

string artist_Name= Model.Artist.FirstOrDefault().Artist_Name;

要么

更改

@model dynamic

@model ExpendoObject

我認為使用動態對象不是一個好主意,默認情況下視圖是強類型的,沒有模型就無法創建基於屬性的模型驗證...

通過參考官方文檔和其他資源,您可以使用擴展方法將您的對象轉換為ExpandoObject,並且您的功能應該可以使用:

擴展方式:

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

在您的控制器方法的返回中,嘗試添加:

return ( "yourView", ArtistModel.ToExpando() ); 

說明:

原因是匿名類型在內部的控制器中傳遞,因此只能從聲明它的程序集中進行訪問。 由於視圖是分別編譯的,因此動態活頁夾抱怨它不能越過該程序集邊界。

但是,如果您考慮一下,動態綁定器的這種限制實際上是很人為的,因為如果您使用私有反射,那么什么也不會阻止您訪問這些內部成員(是的,它甚至在“中等信任”中也有效)。 因此,默認的動態綁定程序將無法執行C#編譯規則(您無法訪問內部成員),而不是讓您執行CLR運行時所允許的工作。

有關更多詳細信息,請閱讀以下答案:

Razor中的動態匿名類型導致RuntimeBinderException

和這篇文章:

https://blogs.msdn.microsoft.com/davidebb/2009/12/18/passing-anonymous-objects-to-mvc-views-and-accessing-them-using-dynamic/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM