MVC Custom type property is not binding in my model

老子叫甜甜 提交于 2019-12-01 05:29:18

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!