ASP.NET MVC - 将动态 ExpandoObject 从控制器传递到 View 时的运行时绑定异常



由于无法在MVC 4 ASP.NET 将多个模型传递给视图,因此我正在尝试将各种模型填充到动态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;
}

当光标到达视图层中的上述分配时,会引发以下异常:

'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 )rn   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)}

有谁知道我需要做什么来解决这个问题?不确定这是快速修复还是更广泛的重新设计。

我认为使用动态对象不是一个好主意,默认情况下视图是强类型的,没有模型就无法创建基于属性的模型验证......

通过参考官方文档和其他资源,您可以使用扩展方法将对象转换为 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 中的动态匿名类型导致运行时绑定器异常

和这篇文章:

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

您发送列表艺术家,但尝试获得一位艺术家,您应该更改此设置

string artist_Name = Model.Artist.Artist_Name;

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

改变

@model dynamic

@model ExpendoObject

相关内容

最新更新