[英]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
和这篇文章:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.