ASP.NET MVC2——模型绑定和 Html.Textbox() 的问题

发布于 2024-09-24 23:08:15 字数 2994 浏览 4 评论 0原文

ASP.NET MVC 模型绑定对我来说仍然很陌生,我正在尝试确切地了解它是如何工作的。现在,我似乎对 Html.Textbox() 的功能有问题。

具体来说,我有一个视图,我将 Html.Textbox 设置为“Get”和“Post”中的值。它在“获取”中设置得很好,但在用户在“发布”期间提交值后,我让类根据提交的另一个值在内部更改其中一个值。

(我基本上是根据另一个值验证一个值......我不确定这是否是正确的方法......)

通过追踪,我可以看到该值实际上已经按照预期发生了变化模型和视图中,但是当它在“发布”之后显示在我的屏幕上时,该值不会显示为更改后的值。相反,它是最初设置的。

这是我的简化示例:

视图显示:

  • 下拉菜单,其中包含 SelectList 中的项目(预选为“其他”)
  • 只读文本框(预加载值为 0)
  • 提交按钮

用户应选择一个新的从下拉列表中选择值,然后单击提交。控制器中的“Post”方法从下拉列表中选取新值,并更改只读文本框中的值并重新显示。

(是的,我最终也会使用 JQuery 来完成此操作...)

这是我的示例模型类:

public class SampleSubmission
{
    public string Name { get; set; }
    public int Volume { get; set; }
    public readonly SortedList<string, int> NameVolumeList = new SortedList<string, int>();
    // Standard Constructor
    public SampleSubmission()
    {
        NameVolumeList.Add("Sample1", 10);
        NameVolumeList.Add("Sample2", 20);
        NameVolumeList.Add("Sample3", 50);
        NameVolumeList.Add("Other", 0);
        this.Name = NameVolumeList.Keys[0];
        this.Volume = NameVolumeList[Name];
    }
    // Copy Constructor
    public SampleSubmission(SampleSubmission samSub) : this()
    {
        this.Name = samSub.Name;
        this.Volume = NameVolumeList[Name];
    }
}

这是控制器:

public class SampleSubmissionController : Controller
{
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Index()
    {
        SampleSubmission sampleSub = new SampleSubmission();
        return View(sampleSub);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(SampleSubmission sampleSub)
    {
        SampleSubmission samSub = new SampleSubmission(sampleSub);
        return View(samSub);
    }
}

这是视图:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<MvcModelBindTest.Models.SampleSubmission>" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm()) {  %>
<%= Html.DropDownList("Name", new SelectList(Model.NameVolumeList.Keys.ToList())) %>
<%= Html.TextBox("Volume",Model.Volume) %>
<input type="submit" name="pick" id="pick" value="Pick" /> <% } %>
</asp:Content>

关于为什么新值不显示的任何想法?

编辑:

为了解决该问题,我阅读了“jfar”给出的链接并进行了 1 行更改。

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(SampleSubmission sampleSub)
    {
        SampleSubmission samSub = new SampleSubmission(sampleSub);
        // Reset Model Value
        ModelState.SetModelValue("Volume", new ValueProviderResult(
           samSub.Volume, "", System.Globalization.CultureInfo.CurrentCulture));
        return View(samSub);
    }

这绝对有效。不幸的是,这对我来说就像是一次严重的黑客攻击。如果我必须更新多个字段的值怎么办?必须有更好(更简单?)的方法来做到这一点。

编辑2:找到了我的答案。见下文...

ASP.NET MVC Model Binding is still new to me and I'm trying to understand exactly how it works. Right now, I appear to be having problems with a feature of Html.Textbox()

Specifically, I have a View where I set Html.Textbox to a value both in the "Get" and the "Post". It sets fine in the "Get", but after the user submits a value during the "Post", I have the class change one of the values internally based on the other value submitted.

(I'm basically validating one value based on the other... I'm not sure if this is the right way to do this...)

Tracing through, I can see that the value has actually changed as expected both in the Model and in the View, but when it displays on my screen after the "Post", the value does not display as it was changed. Instead it is what it was set to originally.

Here's my simplified example:

The View shows a:

  • Drop-down with items from a SelectList (pre-selected as "Other")
  • a Read-only Text Box (with a pre-loaded value of 0)
  • Submit Button

User should pick a new value from the Drop-Down and click submit. The "Post" method in the controller picks up the new value from the Drop-Down and changes the Value in the Read-only text-box and re-displays.

(Yes, I'll eventually be doing this with JQuery, too...)

Here's my sample Model class:

public class SampleSubmission
{
    public string Name { get; set; }
    public int Volume { get; set; }
    public readonly SortedList<string, int> NameVolumeList = new SortedList<string, int>();
    // Standard Constructor
    public SampleSubmission()
    {
        NameVolumeList.Add("Sample1", 10);
        NameVolumeList.Add("Sample2", 20);
        NameVolumeList.Add("Sample3", 50);
        NameVolumeList.Add("Other", 0);
        this.Name = NameVolumeList.Keys[0];
        this.Volume = NameVolumeList[Name];
    }
    // Copy Constructor
    public SampleSubmission(SampleSubmission samSub) : this()
    {
        this.Name = samSub.Name;
        this.Volume = NameVolumeList[Name];
    }
}

Here's the Controller:

public class SampleSubmissionController : Controller
{
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Index()
    {
        SampleSubmission sampleSub = new SampleSubmission();
        return View(sampleSub);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(SampleSubmission sampleSub)
    {
        SampleSubmission samSub = new SampleSubmission(sampleSub);
        return View(samSub);
    }
}

Here's the View:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<MvcModelBindTest.Models.SampleSubmission>" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm()) {  %>
<%= Html.DropDownList("Name", new SelectList(Model.NameVolumeList.Keys.ToList())) %>
<%= Html.TextBox("Volume",Model.Volume) %>
<input type="submit" name="pick" id="pick" value="Pick" /> <% } %>
</asp:Content>

Any ideas as to why the new value does not display?

EDIT:

In order to fix the problem, I read the link given by "jfar" and made a 1-line change.

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(SampleSubmission sampleSub)
    {
        SampleSubmission samSub = new SampleSubmission(sampleSub);
        // Reset Model Value
        ModelState.SetModelValue("Volume", new ValueProviderResult(
           samSub.Volume, "", System.Globalization.CultureInfo.CurrentCulture));
        return View(samSub);
    }

This definitely works. Unfortunately, this feels like a gross hack to me. What if I had to update the values of multiple fields? There must be a better (simpler?) way of doing this.

EDIT2: Found my answer. See below...

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

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

发布评论

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

评论(3

就像说晚安 2024-10-01 23:08:15

来自:如何清除使用 MVC HTML 帮助程序定义的文本框

“HTMLHelper 第一次看到
ModelState和ViewData看看有没有
值与它们的键匹配,然后
最后使用你提供的任何价值
他们。

如果您需要重置文本框
您还需要清除该值
具有匹配的 ModelState 条目
钥匙。另一种选择是
重定向到同一页面
简单地通过渲染视图
JavaScript 或 MVC。

From: How to clear textboxes defined with MVC HTML helpers

"The HTMLHelper's first look at the
ModelState and ViewData to see if any
values match their key and then
finally use whatever value you provide
them.

If you need to reset the textboxe's
value you also need to clear the
ModelState entry with the matching
key. Another alternative is
redirecting to the same page instead
of simply rendering a view via
javascript or with MVC.

栖迟 2024-10-01 23:08:15

当我偶然发现另一个需要重置的变量时,我找到了自己问题的答案。当我查看数据结构时,我意识到我想要的是 ModelState 中没有键的原始状态。

        ModelState.Remove(key);

其中“key”是您尝试重置的值。

I figured out the answer to my own question when I stumbled upon another variable that needed to be reset. As I was looking at the data structure, I realized what I wanted was the pristine state where there were no Keys in the ModelState.

        ModelState.Remove(key);

Where "key" is the value you're trying to reset.

格子衫的從容 2024-10-01 23:08:15

另一个简单的解决方法是

<%= Html.TextBox("Volume",Model.Volume) %>

使用 HTML 输入标签

<input id="Volume" name ="Volume" value="@Model.Volume" />

Another simple workaround is instead of

<%= Html.TextBox("Volume",Model.Volume) %>

Use HTML input tag

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