4

我有以下场景:AC# 基础项目,包含公司中所有其他项目使用的所有数据域(自定义类型)。所以,修改它有点困难。

现在,我们正在使用该基础项目作为参考创建我们的第一个 mvc 项目,并且模型绑定不适用于这些字符串自定义类型的属性:

    [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)
        { 
        }
    }

类型转换器:

    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);
        }
    }

在我的简单测试中,对于这个单一的类,Name 属性没有被绑定,但 Lastname 有。

public class TesteModel
{

    public ShortStrOra Name {get; set;}
    public String Lastname { get; set; }
    public TesteModel() { }

}

我的观点:

@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" />
}

我的控制器:

public ActionResult EditMember(TesteModel model)
{
    return View("Index", model);
}

最后,问题出在哪里?序列化?模型绑定?转换器?我不知道该去哪里。没有错误或异常。

有什么想法吗?谢谢

4

1 回答 1

4

我找到了。我阅读了自定义模型绑定,然后用这种方法解决了我的问题:

创建一个新类,覆盖模型绑定,并检查属性是否为自定义类型,然后对其进行初始化。

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);
    }
}

解决问题的是这一行:

ShortStrOra value = new ShortStrOra(values[propertyDescriptor.Name]);

如果没有它,当尝试在我的 ShortStrOra 类型上设置字符串值时,引擎会抛出 CastException,但它会默默地死去,并且在属性上设置了一个空值。

要在控制器中使用自定义模型绑定器:

[HttpPost]
public ActionResult EditMember([ModelBinder(typeof(TesteModelBinder2))]TesteModel model)
    {
        return View("Index", model);
    }
于 2013-03-19T13:52:11.623 回答