开发者

ASP.NET MVC2 -- Trouble with Model Binding and Html.Textbox()

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<MvcModelBind开发者_运维问答Test.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...


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.


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.


Another simple workaround is instead of

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

Use HTML input tag

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜