为了账号安全,请及时绑定邮箱和手机立即绑定

ASP.NET MVC - 将动态 ExpandoObject 从控制器传递到视图时出现

ASP.NET MVC - 将动态 ExpandoObject 从控制器传递到视图时出现

C#
郎朗坤 2022-12-24 10:16:03
由于不可能将多个模型传递给 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层上面的assignment时,抛出如下异常:'Model.Artist.Artist_Name' threw an exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'Data: {System.Collections.ListDictionaryInternal}HResult: -2146233088HelpLink: nullInnerException: nullMessage: "'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)}有谁知道我需要做什么来解决这个问题?不确定这是快速修复还是更广泛的重新设计。
查看完整描述

2 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

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


通过参考官方文档和其他资源,您可以使用扩展方法将对象转换为 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 运行时允许的操作。


查看完整回答
反对 回复 2022-12-24
?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

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

string artist_Name = Model.Artist.Artist_Name;

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

要么

改变

@model dynamic

@model ExpendoObject


查看完整回答
反对 回复 2022-12-24
  • 2 回答
  • 0 关注
  • 151 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号