问题
I have the following scenario: A C# base project, with all data domains (custom types) that are used by all others projects in the company. So, It´s a little bit hard to modify it.
Now, we are creating our first mvc project with that base project as reference, and the model binding doesnt work for properties of those strings custom types:
[Serializable]
[TypeConverter(typeof(ShortStrOraTypeConverter))]
public class ShortStrOra : BaseString
{
public ShortStrOra()
: this(String.Empty)
{
}
public ShortStrOra(string stringValue)
: base(stringValue, 35)
{
}
public static implicit operator ShortStrOra(string stringValue)
{
return new ShortStrOra(stringValue);
}
public static implicit operator string(ShortStrOra value)
{
if (value == null)
{
return null;
}
else
{
return value.ToString();
}
}
public void Add(object o)
{
}
}
The TypeConverter:
public class ShortStrOraTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
return new ShortStrOra(Convert.ToString(value));
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
return ((ShortStrOra)value).ToString();
return base.ConvertTo(context, culture, value, destinationType);
}
}
And in my simple test, with this single class, the Name property has not been binded, but Lastname has.
public class TesteModel
{
public ShortStrOra Name {get; set;}
public String Lastname { get; set; }
public TesteModel() { }
}
My view:
@using (Html.BeginForm("EditMember", "Home", FormMethod.Post, new { @id = "frmEditMembers" }))
{
@Html.TextBoxFor(m => m.Name)<br />
@Html.TextBoxFor(m => m.Lastname)
<input type="submit" value="Salvar" />
}
My controller:
public ActionResult EditMember(TesteModel model)
{
return View("Index", model);
}
Finally, where is the problem? Serialization? Model binding? Converter? I dont know where to go. There is no error or exception.
Any ideias? Thanks
回答1:
I found it. I read about custom model binding and then solved my problem with this approach:
Creating a new class, to override model binding, and checking if the property is of the custom type and then initializes it.
public class TesteModelBinder2 : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
{
NameValueCollection values = controllerContext.HttpContext.Request.Form;
if (propertyDescriptor.PropertyType.Equals(typeof(ShortStrOra)))
{
ShortStrOra value = new ShortStrOra(values[propertyDescriptor.Name]);
propertyDescriptor.SetValue(bindingContext.Model, value);
return;
}
else
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
What solved the problem was this line:
ShortStrOra value = new ShortStrOra(values[propertyDescriptor.Name]);
Without it the engine throws a CastException when tries to set a string value on my ShortStrOra type, but it dies silently and a null value is setted on the property.
To use the custom model binder in controller:
[HttpPost]
public ActionResult EditMember([ModelBinder(typeof(TesteModelBinder2))]TesteModel model)
{
return View("Index", model);
}
来源:https://stackoverflow.com/questions/15499089/mvc-custom-type-property-is-not-binding-in-my-model