【问题标题】:List is not binding to the model while posting the form to mvc action method将表单发布到 mvc 操作方法时,列表未绑定到模型
【发布时间】:2014-07-28 10:43:10
【问题描述】:

我有一个页面,我在其中维护一个列表,如下所示。

 @for (int i = 0; i < Model.RuleDetails.Rules.AssociatedRules.Count; i++)
 {
    <div class="checkbox">
        <label><input type="checkbox" checked="true" value="true" />
                   @Model.RuleDetails.Rules.AssociatedRules[i].Rule_Name 
            </label>
             @Html.HiddenFor(x => x.RuleDetails.Rules.AssociatedRules[i].Rule_Id)
             @Html.HiddenFor(x => x.RuleDetails.Rules.AssociatedRules[i].State)
        </div>
  }

当我点击保存按钮时,我可以在网络监视器中看到数据正在发送到服务器..

但是当我看到动作参数中的模型时,我将 RuleDetails.Rules.AssociatedRules 设置为 null。

我调查了 Controller 中的 HttpRequest 对象,我可以在请求参数中看到我的值

我不知道服务器中发生了什么以及我缺少什么。有什么方法可以控制模型绑定。

这是视图的模型

并且控制器只有基本的获取和保存模式的操作方法。

【问题讨论】:

  • odetocode.com/blogs/scott/archive/2009/04/27/…中引用Prefer Binding Over Request.Form
  • 控制器中的代码是什么?什么是视图模型?
  • @user1666620 我已经用页面模型更新了问题。
  • 你有实际的代码吗?什么是数据类型等?屏幕截图不是很好,如果他们想尝试重现问题,没有人愿意输入大量其他人的代码。如果它是专有的,则对代码进行混淆 - 只允许我们重现行为的最小数量。
  • 我的第一个猜测是,模型只是由于某些类型绑定错误而没有绑定。检查ModelState.IsValid 属性,它可能是错误的,您将在模型状态值中遇到错误。有关从属性读取错误的快速示例,请参阅此答案。 stackoverflow.com/a/22305555/426894

标签: c# html asp.net asp.net-mvc-4


【解决方案1】:

这是我编写的模型活页夹。我知道这不是我正在寻找的解决方案,但我已经花了很多时间寻找问题的原因。将在截止日期后进行更详细的调查;)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;

namespace ModelBinderPoc
{
public class MyModelBinder : IModelBinder
{
    private bool IsPropertyClrObject(PropertyInfo obj)
    {
        var type = obj.PropertyType;

        return (type.Equals(typeof(Boolean)) || type.Equals(typeof(string)) || type.Equals(typeof(Int32)) || type.Equals(typeof(decimal))
            || type.Equals(typeof(DateTime)) || type.Equals(typeof(DateTime?)));
    }

    private void SetClrObjectValue(PropertyInfo pinfo, object model, object pvalue)
    {
        pinfo.SetValue(model, pvalue, null);
    }

    private object CreateCollection(object obj, string propertyPart)
    {
        var propertyLength = propertyPart.IndexOf('[');
        var propertyName = propertyPart.Substring(0, propertyLength);
        var index = propertyPart.Substring(propertyLength + 1, propertyPart.Length - (propertyLength + 2));

        var property = obj.GetType().GetProperty(propertyName);
        var propertyValue = property.GetValue(obj, null);
        if (propertyValue == null)
        {
            var ctype = property.PropertyType.GetGenericTypeDefinition();
            if (ctype.FullName.Contains("System.Collections.Generic.IList"))
            {
                var gptype = property.PropertyType.GetGenericArguments().First();
                var listInstance = (IList)typeof(List<>).MakeGenericType(gptype).GetConstructor(Type.EmptyTypes).Invoke(null);
                property.SetValue(obj, listInstance, null);
                propertyValue = listInstance;
            }
        }

        int count = (int)propertyValue.GetType().GetProperty("Count").GetValue(propertyValue, null);
        var gtype = propertyValue.GetType().GetGenericArguments().First();
        object listItem = null;

        if (int.Parse(index) + 1 > count)
        {
            ((IList)propertyValue).Add(listItem = gtype.GetConstructor(Type.EmptyTypes).Invoke(null));
        }
        else
        {
            listItem = propertyValue.GetType().GetMethod("get_Item").Invoke(propertyValue, new object[] { int.Parse(index) });
        }

        return listItem;
    }


    private void setPropertyValue(object model, string propertyName, string value)
    {
        var objectValue = model;

        foreach (var propertyPart in propertyName.Split('.'))
        {
            var propertyLength = propertyPart.Length;

            if ((propertyLength = propertyPart.IndexOf('[')) != -1)
            {
                objectValue = CreateCollection(objectValue, propertyPart);
                continue;
            }

            var property = GetProperty(objectValue, propertyPart);

            if (property == null)
                return; // invalid property

            if (IsPropertyClrObject(property))
            {
                SetValue(objectValue, property, value);
                return;
            }

            var propertyValue = GetValueOf(objectValue, property);
            if (propertyValue == null)
            {
                var newObjValue = GetNewValueFor(property);
                SetObjValue(objectValue, property, newObjValue);
                propertyValue = newObjValue;
            }

            objectValue = propertyValue;
        }
    }

    private void SetValue(object obj, PropertyInfo pinfo, object value)
    {
        if (pinfo.PropertyType.Equals(typeof(DateTime?)))
        {
            DateTime date = DateTime.Now;
            if (DateTime.TryParse(value as string, out date))
                pinfo.SetValue(obj, date, null);
            else
                pinfo.SetValue(obj, null, null);
            return;
        }

        if (value.ToString().Length != 0) 
            pinfo.SetValue(obj, Convert.ChangeType(value, pinfo.PropertyType), null);
    }

    private void SetObjValue(object obj, PropertyInfo pinfo, object value)
    {
        pinfo.SetValue(obj, value, null);
    }

    private object GetValueOf(object obj, PropertyInfo pinfo)
    {
        return pinfo.GetValue(obj, null);
    }

    private object GetNewValueFor(PropertyInfo pinfo)
    {
        return Instantiate(pinfo.PropertyType);
    }

    private object Instantiate(Type type)
    {
        return type.GetConstructor(Type.EmptyTypes).Invoke(null); ;
    }

    private PropertyInfo GetProperty(object obj, string property)
    {
        return obj.GetType().GetProperty(property);
    }

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var model = Instantiate(bindingContext.ModelType);
        var parameters = controllerContext.HttpContext.Request.Params;

        foreach (var key in parameters.AllKeys)
        {
            var value = parameters.GetValues(key);
            setPropertyValue(model, key, value.First());
        }

        return model;
    }
}
}`    

【讨论】:

    猜你喜欢
    • 2016-09-23
    • 1970-01-01
    • 2012-06-03
    • 2015-02-28
    • 2013-07-25
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 2011-01-02
    相关资源
    最近更新 更多