我想使用我的自定义绑定器来处理构造函数(必要),然后让默认的模型绑定器正常填写其余的属性。
编辑:自定义的一个当然会先运行。
答案 0 :(得分:1)
活页夹:
public class RegistrationViewModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
return new RegistrationViewModel(Guid.NewGuid());
}
}
模特:
public class RegistrationViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public Guid Id { get; private set; }
public RegistrationViewModel(Guid id)
{
Id = id;
}
}
如果您的财产可以设置(在这种情况下是Id),您需要将其从绑定中排除:
[Bind(Exclude = "Id")]
public class RegistrationViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public Guid Id { get; set; }
}
答案 1 :(得分:1)
谢谢大家,我想我找到了一个解决方案,那就是覆盖defaultmodelbinder的createmodel方法。我从这里得到了额外的帮助: http://noahblu.wordpress.com/2009/06/15/modelbinder-for-objects-without-default-constructors/
由于在mvc中进行了更改,因此需要更新以使用modelmetadata而不是设置该链接中显示的模型类型。 这是我最初的第一次试用,似乎有效:
namespace NorthwindMVCApp.CustomBinders{
public class NewShipperBinder<T> : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
Type type1 = typeof(T);
ConstructorInfo[] constructors = type1.GetConstructors();
ConstructorInfo largestConstructor = constructors.OrderByDescending(x => x.GetParameters().Count()).First();
ParameterInfo[] parameters = largestConstructor.GetParameters();
List<object> paramValues = new List<object>();
IModelBinder binder;
string oldModelName = bindingContext.ModelName;
foreach (ParameterInfo param in parameters)
{
string name = CreateSubPropertyName(oldModelName, param.Name);
//bindingContext.ModelType = param.ParameterType;
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, param.ParameterType);
bindingContext.ModelName = name;
if (!System.Web.Mvc.ModelBinders.Binders.TryGetValue(param.ParameterType, out binder))
binder = System.Web.Mvc.ModelBinders.Binders.DefaultBinder;
object model = binder.BindModel(controllerContext, bindingContext);
paramValues.Add(model);
}
// bindingContext.ModelType = typeof(T);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(T));
bindingContext.ModelName = oldModelName;
Debug.WriteLine(Environment.StackTrace);
object obj = Activator.CreateInstance(type1, paramValues.ToArray());
return obj;
}
}
}
受约束的类如下。所有这一切的原因是它没有默认构造函数(为了确保不存在非空格):
namespace Core.Entities{
[EntityAttribute()]
public class Shipper
{
protected Shipper() : this("Undefined")
{
}
public Shipper(string CompanyName)
{
this.CompanyName = CompanyName;
Orders = new List<Order>();
}
public virtual int ShipperID { get; set; }
public virtual IList<Order> Orders { get; set; }
public virtual string CompanyName { get; set; }
public virtual string Phone { get; set; }
public override bool Equals(object obj)
{
Shipper obj_Shipper;
obj_Shipper = obj as Shipper;
if (obj_Shipper == null)
{
return false;
}
if (obj_Shipper.CompanyName != this.CompanyName)
{
return false;
}
return true;
}
public override int GetHashCode()
{
return CompanyName.GetHashCode();
}
}
}
顺便说一句,binder如下所示包含在global.asax中:
ModelBinders.Binders.Add(typeof(Shipper), new CustomBinders.NewShipperBinder<Shipper>());
因此我很容易添加大量的实体类(循环),因为我维护了一系列实体类型。
因此,我已经能够将该实体更新到数据库。
编辑:有点结冰,这是一个堆栈跟踪:
at NorthwindMVCApp.CustomBinders.NewShipperBinder`1.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) in C:\Users\####\Documents\Visual Studio 2010\Projects\TestFluentNHibernate\NorthwindMVC\NorthwindMVCApp\CustomBinders\NewShipperBinder.cs:line 37
at System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
答案 2 :(得分:0)
您是否已从DefaultModelBinder继承?我认为不可能按照您的意图行事 - 如果您创建客户模型绑定器并且它实现了IModelBinder,则该类必须执行所有必要的操作。