不要绑定一个动作参数

发布于 2024-11-18 01:08:22 字数 859 浏览 3 评论 0原文

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

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

名称和模型 id 通过 ajax POST 发送,模型由自定义操作过滤器填充,该过滤器获取 id 并从数据库检索模型。

ActionFilter 看起来像这样:

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

I have an action that looks like this:

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

The name and model id are sent by an ajax POST, and the model is populated by a custom action filter that takes the id and retrieves the model from the database.

The actionfilter looks like this:

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

The problem is that the MyModel object doesn't have a parameterless constructor, and MVC is attempting to create and bind to the MyModel object before the ActionFilter is even called but throws an exception because it cannot instantiate the MyModel object.

My first question is am I doing this properly or should I be using something like HttpContext.Items to transfer data between filter and action? Second, is there a way to tell MVC to not try to bind the MyModel object because it will be created later?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅暮の光 2024-11-25 01:08:22

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

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

A custom model binder seems more appropriate for this task than a custom action filter:

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

which yuo would register in Application_Start:

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

Now your controller action might look like this:

[HttpPost]
public ActionResult ChangeName(string name, MyModel model)
{
    try
    {
        model.ChangeName();
        return JSONSuccess();
    }
    catch (ModelUpdateException)
    {
        return JSONFail();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文