0

次のようなアクションがあります。

[Post]
[PopulateModelFromId]
public ActionResult ChangeName( string name, MyModel model )
{
    try
    {
        model.changeName
        return JSONSuccess();
    }
    catch( ModelUpdateException )
    {
        return JSONFail();
    }
}

名前とモデル ID は ajax POST によって送信され、ID を取得してデータベースからモデルを取得するカスタム アクション フィルターによってモデルが設定されます。

アクションフィルターは次のようになります。

...
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    // parse the id from the request
    MyModel model = getModelFromDataStoreById( id );
    filterContext.ActionParameters["model"] = model;
}
...

問題は、MyModel オブジェクトにパラメーターなしのコンストラクターがないことです。MVC は、ActionFilter が呼び出される前に MyModel オブジェクトを作成してバインドしようとしますが、MyModel オブジェクトをインスタンス化できないため、例外をスローします。

私の最初の質問は、これを適切に行っているか、または HttpContext.Items のようなものを使用してフィルターとアクションの間でデータを転送する必要があるかということです。次に、後で作成されるため、MVC に MyModel オブジェクトをバインドしようとしないように指示する方法はありますか?

4

1 に答える 1

2

カスタムモデルバインダーは、カスタムアクションフィルターよりもこのタスクに適しているようです。

public class MyModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        var id = bindingContext.ValueProvider.GetValue("id");
        if (id != null)
        {
            return GetModelFromDataStoreById(id.AttemptedValue);
        }
        return base.CreateModel(controllerContext, bindingContext, modelType);
    }
}

どのyuoが登録するかApplication_Start

ModelBinders.Binders.Add(typeof(MyModel), new MyModelBinder());

これで、コントローラーのアクションは次のようになります。

[HttpPost]
public ActionResult ChangeName(string name, MyModel model)
{
    try
    {
        model.ChangeName();
        return JSONSuccess();
    }
    catch (ModelUpdateException)
    {
        return JSONFail();
    }
}
于 2011-06-30T15:05:29.333 に答える