1

asp.net MVC で最初のモデル バインダーを作成しました。「fm_」で始まる名前を持つすべての入力を持つ純粋な HTML フォームから始めました。

public class HuggiesModel
{
    public string fm_firstname { get; set; }
    public DateTime fm_duedate { get; set; }
}

デフォルトのバインダーは問題なく機能し、時間の節約になったと思います。

次に、よりクリーンなプロパティ名が必要だと判断したため、次のように変更しました。

[ModelBinder(typeof(HuggiesModelBinder))]
public class HuggiesModel
{
    public string FirstName { get; set; }
    public DateTime? DueDate { get; set; }
}

モデル バインダー:

public class HuggiesModelBinder : IModelBinder
{
    private HttpRequestBase request;

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException("bindingContext");

        this.request = controllerContext.HttpContext.Request;

        var model = new HuggiesModel
        {
            FirstName = GetQueryStringValue("fm_firstname"),
        };

        string dateTimeString = GetQueryStringValue("fm_duedate");
        model.DueDate = string.IsNullOrWhiteSpace(dateTimeString) 
                                    ? default(DateTime?) 
                                    : DateTime.Parse(dateTimeString);

        return model;
    }

    private string GetQueryStringValue(string key)
    {
        if (this.request.HttpMethod.ToUpper() == "POST")
            return this.request.Form[key];
        return this.request.QueryString[key];
    }
}

DateTime を解析してデフォルトのバインダーを取得する必要がないように、これを実装する方法はありますか?

:

フォーム入力名を希望のモデル名に合わせて変更できることはわかっていますが、モデルバインダーの作成経験を積むために意図的にそうしなかったため、この質問に至りました。

質問のタイトルは、私がやろうとしていることの概念的なアイデアに基づいています-次のようなチェーンを作成します:

request
  -> default model binder binds get/post data to first view model
         -> my model binder binds first view model to second view model
               -> controller action method is called with second view model
4

1 に答える 1

1

IModelBinder を実装するのではなく、DefaultModelBinder を拡張できます。

ここに例があります

    public class HuggiesModelBinder:DefaultModelBinder
    {
        protected override void BindProperty( ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor )
        {
            if (propertyDescriptor.PropertyType == typeof(DateTime))
            {

                base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
            }
            // bind the rest of the properties here
        }
    }

ただし、HuggiesModel が複雑な型と単純な型 (現在のもののように) で構成されているというより現実的なシナリオを検討する場合は、単純な型で既定のモデル バインディングを使用します (命名規則と一緒に - 代わりに FirstName プロパティを使用します)。 fm_firstname の)。複雑な型の場合、型ごとにカスタム モデル バインダーを実装します。'HuggiesModel' 用に大きなカスタム モデル バインダーを 1 つ持つ必要はありません。

于 2013-02-21T06:34:23.213 に答える