我有一个页面,我在其中维护一个列表,如下所示。
@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对象,我可以在请求参数中看到我的值
我不知道服务器中发生了什么以及我遗漏了什么。有没有办法控制模型绑定。
这是视图的模型
和Controller只有基本上获取和保存模式的动作方法。
答案 0 :(得分:0)
这是我写的模型活页夹。我知道这不是我正在寻找的解决方案,但我已经花了很多时间来查找问题的原因。在满足截止日期后将进行更详细的调查;)
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;
}
}
}`