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

私の簡単なテストでは、この 1 つのクラスを使用して、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 をスローしますが、エンジンは黙って停止し、プロパティに null 値が設定されます。

コントローラーでカスタム モデル バインダーを使用するには:

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