ASP.NET MVC 表单重新填充

发布于 2024-07-11 18:11:05 字数 1350 浏览 7 评论 0原文

我有一个具有两个操作的控制器:

[AcceptVerbs("GET")]
    public ActionResult Add()
    {
        PrepareViewDataForAddAction();
        return View();
    }


[AcceptVerbs("POST")]
    public ActionResult Add([GigBinderAttribute]Gig gig, FormCollection formCollection)
    {
        if (ViewData.ModelState.IsValid)
        {
            GigManager.Save(gig);
            return RedirectToAction("Index", gig.ID);
        }
        PrepareViewDataForAddAction();
        return View(gig);
    }

如您所见,当表单发布其数据时,添加操作使用 GigBinder (IModelBinder 的实现)

在这个活页夹中我有:

 if (int.TryParse(bindingContext.HttpContext.Request.Form["StartDate.Hour"], out hour))
        {
           gig.StartDate.Hour = hour;
        }
        else
        {
            bindingContext.ModelState.AddModelError("Doors", "You need to tell us when the doors open");
        }

表单包含一个 id 为“StartDate.Hour”的文本框”。

正如您在上面看到的,GigBinder 测试以查看用户是否在 id 为“StartDate.Hour”的文本框中输入了一个整数。 如果不是,则使用 AddModelError 将模型错误添加到模型状态。

由于 gigs 属性 gigs.StartDate.Hour 是强类型的,因此如果用户已将其值键入到表单文本框中,我无法将其值设置为“TEST”。

因此,我无法设置 gigs.StartDate.Hour 的值,因为用户输入了字符串而不是整数。

由于“添加操作”返回视图并传递模型(返回 View(gig);),如果模型状态无效,则当使用验证消息重新显示表单时,值“TEST”不会显示在文本框中。 相反,它将是 gig.StartDate.Hour 的默认值。

我该如何解决这个问题? 我真的卡住了!

I have a controller with two actions:

[AcceptVerbs("GET")]
    public ActionResult Add()
    {
        PrepareViewDataForAddAction();
        return View();
    }


[AcceptVerbs("POST")]
    public ActionResult Add([GigBinderAttribute]Gig gig, FormCollection formCollection)
    {
        if (ViewData.ModelState.IsValid)
        {
            GigManager.Save(gig);
            return RedirectToAction("Index", gig.ID);
        }
        PrepareViewDataForAddAction();
        return View(gig);
    }

As you can see, when the form posts its data, the Add action uses a GigBinder (An implemenation of IModelBinder)

In this binder I have:

 if (int.TryParse(bindingContext.HttpContext.Request.Form["StartDate.Hour"], out hour))
        {
           gig.StartDate.Hour = hour;
        }
        else
        {
            bindingContext.ModelState.AddModelError("Doors", "You need to tell us when the doors open");
        }

The form contains a text box with id "StartDate.Hour".

As you can see above, the GigBinder tests to see that the user has typed in an integer into the textbox with id "StartDate.Hour". If not, a model error is added to the modelstate using AddModelError.

Since the gigs property gigs.StartDate.Hour is strongly typed, I cannot set its value to, for example, "TEST" if the user has typed this into the forms textbox.

Hence, I cant set the value of gigs.StartDate.Hour since the user has entered a string rather than an integer.

Since the Add Action returns the view and passes the model (return View(gig);) if the modelstate is invalid, when the form is re-displayed with validation mssages, the value "TEST" is not displayed in the textbox. Instead, it will be the default value of gig.StartDate.Hour.

How do I get round this problem? I really stuck!

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

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

发布评论

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

评论(3

暗恋未遂 2024-07-18 18:11:05

我认为问题在于您的 ViewModel 与您的 View 匹配得不够紧密。 在 MVC 中,ViewModel 与 View 尽可能匹配非常重要。

在您的 ViewModel 中,您假设一个整数,但在您的 View 中,您使用 TextBox 来呈现该属性,这将允许任何类型的文本。 这里存在不匹配,您在尝试映射它们时遇到的困难是不匹配的症状。

我认为你应该:
1. 将 ViewModel 属性的类型更改为字符串,然后在控制器中进行验证以确保输入的字符串实际上是数字或:
2.将视图呈现的控件更改为仅允许通过自定义控件或Javascript验证输入数字的控件(正如@Qun Wang建议的那样)就

我个人而言,我推荐选项1。这样ViewModel就不会依赖于视图的实现。

I think the problem is that your ViewModel does not match closely enough with your View. It's really important in MVC that your ViewModel matches your View as closely as possible.

In your ViewModel you're assuming an integer, but in your View you're using a TextBox to render the property, which will allow any kind of text. There's a mismatch here and the difficulties you are experiencing trying to map them is a symptom of the mismatch.

I think you should either:
1. Change the type of the ViewModel property to string and then do validation in your controller to ensure the string entered is actually a number or:
2. Change the control that the View renders to a control that will only allow a number to be entered via a custom control or Javascript validation (as @Qun Wang recommends)

Personally, I'd recommend option 1. That way the ViewModel is not dependent on the View implementation.

溇涏 2024-07-18 18:11:05

您可以在PrepareViewDataForAddAction 方法中执行此操作吗?...

if (!ViewData.ModelState.IsValid)
    {
        ViewData["StartDate.Hour"] = "Error";
    }

表单上的其他字段仍将根据Gig 对象的属性进行填充。

Could you do this in your PrepareViewDataForAddAction method?..

if (!ViewData.ModelState.IsValid)
    {
        ViewData["StartDate.Hour"] = "Error";
    }

The other fields on the form will still populate based on the properties of the Gig object.

与他有关 2024-07-18 18:11:05

我认为您需要首先进行一些基本的客户端验证。
不允许它发布到服务器。

I think you need to do some basic client side validation first.
don't allow it to post to the server.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文