【问题标题】:How to use DynamicObject in model csharp如何在模型 csharp 中使用 DynamicObject
【发布时间】:2020-07-15 14:12:11
【问题描述】:

我可以在模型中使用 DynamicObject。我想在剃须刀页面中使用它。有可能吗?

public class ProductsModel
    {
        public ProductDetail ProductDetail { get; set; } 
        public MyDynamicClass  
    }

以下简单示例允许在运行时添加任意动态属性。该类覆盖 TrySetMember 和 TryGetMember 虚拟方法以提供行为。请注意,这些方法有一个 binder 参数,该参数提供有关正在尝试的动态操作的信息,例如属性名称 (binder.Name)。另请注意,这些方法返回一个布尔值以向运行时指示动态操作是否成功。

class MyDynamicClass : DynamicObject
{
    private readonly Dictionary<string, object> _dynamicProperties = new Dictionary<string, object>();

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _dynamicProperties.Add(binder.Name, value);

        // additional error checking code omitted

        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return _dynamicProperties.TryGetValue(binder.Name, out result);
    }

    public override string ToString()
    {
        var sb = new StringBuilder();

        foreach (var property in _dynamicProperties)
        {
            sb.AppendLine($"Property '{property.Key}' = '{property.Value}'");
        }

        return sb.ToString();
    }

    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return _dynamicProperties.Keys;
    }
}

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    我可以在模型中使用 DynamicObject。我想在剃须刀页面中使用它。是吗 可能吗?

    这是可能的,但首先你必须标准化 ProductsModel 的写法,如@Jawad said

       public class ProductsModel
       {
                public ProductDetail ProductDetail { get; set; }
                public MyDynamicClass myDynamic { get; set; }
       }
    
        public class ProductDetail
        {
            public int Id { get; set; }
            public string Details { get; set; }
        }
    

    那么,为了保证ProductsModel数据可以在页面上展示,那么需要在MyDynamicClass中添加Dictionary字段,这样就可以获取到数据了MyDynamicClass 下的动态字段。

    我的动态类:

     public class MyDynamicClass : DynamicObject
        {
            private readonly Dictionary<string, object> _dynamicProperties = new Dictionary<string, object>();
    
           public MyDynamicClass()
           {
              for (int i = 0; i < 10; i++)
              {
                  _dynamicProperties.Add("Id" + i, i);
                  _dynamicProperties.Add("Value" + i, "Value" + i);
              }
           }
    
            // This property returns the number of elements
            // in the inner dictionary.s
            public Dictionary<string, object> MyData
            {
                get
                {
                    return _dynamicProperties;
                }
            }
    
            public override bool TrySetMember(SetMemberBinder binder, object value)
            {
                _dynamicProperties.Add(binder.Name, value);
    
                // additional error checking code omitted
    
                return true;
            }
            public override bool TryGetMember(GetMemberBinder binder, out object result)
            {
                return _dynamicProperties.TryGetValue(binder.Name, out result);
            }
    
            public override string ToString()
            {
                var sb = new StringBuilder();
    
                foreach (var property in _dynamicProperties)
                {
                    sb.AppendLine($"Property '{property.Key}' = '{property.Value}'");
                }
    
                return sb.ToString();
            }
            public override IEnumerable<string> GetDynamicMemberNames()
            {
                return _dynamicProperties.Keys;
            }
        }
    

    索引.cshtml.cs:

       public class IndexModel : PageModel
        { 
            [BindProperty]
            public ProductsModel data { get; set; } 
            public void OnGet()
            {
                dynamic formData = new MyDynamicClass(); 
    
                data = new ProductsModel()
                {
                    myDynamic = formData,
                    ProductDetail = new ProductDetail() { Id = 1, Details = "aaaaaaaaa" }
                };
    
            }
        }
    

    Index.cshtml:

    @page
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    <h1>DynamicTest</h1>
    
    <table class="table table-bordered">
        <tr>
    
            <th> @Html.DisplayNameFor(x => Model.data.ProductDetail.Id)</th>
            <th> @Html.DisplayNameFor(x => Model.data.ProductDetail.Details)</th>
            @foreach (var item in Model.data.myDynamic.MyData)
            {
                <th> @item.Key</th>
            }
        </tr>
        <tr>
            <td> @Model.data.ProductDetail.Id</td>
            <td> @Model.data.ProductDetail.Details</td>
            @foreach (var item in Model.data.myDynamic.MyData)
            {
                <td> <input asp-for="@item.Value" />  </td>
            }
        </tr>
    </table>
    

    这是测试结果:

    【讨论】:

      【解决方案2】:

      您必须定义属性的名称。你拥有它的方式,public MyDynamicClass 是无效代码,必须有一个属性名称。 public MyDynamicClass MyObject。然后就可以使用getter和setter来设置值了

      【讨论】:

        【解决方案3】:

        我可以在 Constructor 中设置它吗?我想在 razpor 页面中使用表单

            <form method="post">
                <input asp-for="MyDynamicClass.Id1" /> 
                <input asp-for="MyDynamicClass.Value1" />
                     <input type="button" value="Submit" />
            </form>
        

        如何以及在哪里可以设置它

        public class MyDynamicClass : DynamicObject
        {
            public MyDynamicClass()
            {
                dynamic d = new MyDynamicClass();
                for (int i = 0; i < 10; i++)
                {
                    d["Id" + 1] = 0;
                    d["Value" + 1] = string.Empty;
        
                }
            }
            //....
        }
        

        【讨论】:

        • 您想将不同的字段动态绑定到 MyDynamicClass?如果是这样,可以在MyDynamicClass的构造函数中实现,但是只能通过向Dictionary添加数据的方式添加,而不是d["Id" + 1]数组形式。您需要知道 MyDynamicClass 基本上是自定义动态类。按照方法可以看出最后其实是Dictionary的类型,所以不能用asp-for形式绑定MyDynamicClass.Id1字段的值,建议用我的代码测试,我已经更新了我的回复。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-20
        • 1970-01-01
        • 2014-08-26
        • 1970-01-01
        • 2011-06-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多