【问题标题】:Do not bind one parameter of action不绑定一个action参数
【发布时间】:2011-06-30 14:21:16
【问题描述】:

我有一个如下所示的操作:

[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 对象,因为它稍后会创建?

【问题讨论】:

  • 那么如果你不想在调用方法时绑定MyModel对象,那你为什么要把它放在参数列表中呢?另外,您熟悉自定义操作过滤器吗?您可以访问动作的模型并在进入或退出时填充它。
  • 我选择通过 ActionParameters 将对象从 ActionFilter 传递到 Controller。对我来说,这似乎是最简洁易读的解决方案。模型对象不是动作的模型。这是我执行操作然后返回 JSONResult 的业务逻辑对象。
  • 那么,为什么不能在动作本身中执行动作过滤器中正在执行的逻辑呢?当您有一些代码需要在许多不同的操作上执行时,可以使用操作过滤器。它有助于强制执行 DRY 主体。但是,在您的情况下,这看起来特定于这一操作。那么为什么不直接在操作中调用 getModelFromDataStoreById 方法呢?

标签: c# asp.net-mvc asp.net-mvc-3 actionresult


【解决方案1】:

自定义模型绑定器似乎比自定义操作过滤器更适合此任务:

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

你会在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();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 2011-12-13
    • 2015-11-29
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多