Dynamic Anonymous type in Razor causes RuntimeBinderException

后端 未结 12 982
不思量自难忘°
不思量自难忘° 2020-11-22 07:45

I\'m getting the following error:

\'object\' does not contain a definition for \'RatingName\'

When you look at the anonymous dyn

12条回答
  •  庸人自扰
    2020-11-22 08:18

    Using the ExpandoObject Extension works but breaks when using nested anonymous objects.

    Such as

    var projectInfo = new {
     Id = proj.Id,
     UserName = user.Name
    };
    
    var workitem = WorkBL.Get(id);
    
    return View(new
    {
      Project = projectInfo,
      WorkItem = workitem
    }.ToExpando());
    

    To accomplish this I use this.

    public static class RazorDynamicExtension
    {
        /// 
        /// Dynamic object that we'll utilize to return anonymous type parameters in Views
        /// 
        public class RazorDynamicObject : DynamicObject
        {
            internal object Model { get; set; }
    
            public override bool TryGetMember(GetMemberBinder binder, out object result)
            {
                if (binder.Name.ToUpper() == "ANONVALUE")
                {
                    result = Model;
                    return true;
                }
                else
                {
                    PropertyInfo propInfo = Model.GetType().GetProperty(binder.Name);
    
                    if (propInfo == null)
                    {
                        throw new InvalidOperationException(binder.Name);
                    }
    
                    object returnObject = propInfo.GetValue(Model, null);
    
                    Type modelType = returnObject.GetType();
                    if (modelType != null
                        && !modelType.IsPublic
                        && modelType.BaseType == typeof(Object)
                        && modelType.DeclaringType == null)
                    {
                        result = new RazorDynamicObject() { Model = returnObject };
                    }
                    else
                    {
                        result = returnObject;
                    }
    
                    return true;
                }
            }
        }
    
        public static RazorDynamicObject ToRazorDynamic(this object anonymousObject)
        {
            return new RazorDynamicObject() { Model = anonymousObject };
        }
    }
    

    Usage in the controller is the same except you use ToRazorDynamic() instead of ToExpando().

    In your view to get the entire anonymous object you just add ".AnonValue" to the end.

    var project = @(Html.Raw(JsonConvert.SerializeObject(Model.Project.AnonValue)));
    var projectName = @Model.Project.Name;
    

提交回复
热议问题