c# - Handling array's in post back data - MVC3 -


i'm current webforms developer trying move mvc. i'm super excited mvc , i'm have fun i'm running weird issue. i'm trying create advanced editor "widget". i've posted code below.

everything appears work fine when add first 4-5 items problem occurs when delete 2nd item. here visual example.

first add 4 values.

enter image description here

but problem occurs when delete 2nd value. end this...

enter image description here

what cannot seem understand why property act different between 2 following lines of code.

@model.values[i] @html.textboxfor(m => m.values[i]) 

my guess @model , (m =>m) not reference same object?

here widget class.

public class widget {     #region constructor      public widget()     {         id = 0;         name = string.empty;         values = new list<string>();     }      #endregion      #region properties      [required]     [display(name = "id")]     public int id { get; set; }      [required]     [display(name = "name")]     public string name { get; set; }      [required]     [display(name = "values")]     public list<string> values { get; set; }      #endregion } 

my controller looks this.

public viewresult editwidget(int id) {     return view(_widgets.getwidgetbyid(id)); }  [httppost] public actionresult editwidget(widget widget) {     if (!tryupdatemodel(widget))     {         viewbag.message = "error...";         return view(widget);     }      if (request.form["addwidgetvalue"] != null)     {         widget.values.add(request.form["textboxwidgetvalue"]);         return view("editwidget", widget);     }      if (request.form["deletewidgetvalue"] != null)     {         widget.values.remove(request.form["listboxwidgetvalues"]);         return view("editwidget", widget);     }      _widgets.updatewidget(widget);     _widgets.save();      return redirecttoaction("index"); } 

and view.

@model mvctestapplication.models.widget  @{     viewbag.title = "editwidget"; }  <h2>editwidget</h2>  <script src="@url.content("~/scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@url.content("~/scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>  @using (html.beginform()) {     @html.validationsummary(true)     <fieldset>         <legend>widget</legend>          @html.hiddenfor(model => model.id)          <div class="editor-label">             @html.labelfor(model => model.name)         </div>         <div class="editor-field">             @html.editorfor(model => model.name)             @html.validationmessagefor(model => model.name)         </div>          @for (var = 0; < model.values.count; i++)         {             @model.values[i]             @html.textboxfor(m => m.values[i])             @html.hiddenfor(m => m.values[i])             <br />         }          @html.listbox("listboxwidgetvalues", new selectlist(model.values), new { style = "width: 100%" })<br />         @html.textbox("textboxwidgetvalue", string.empty, new { style = "width: 100%" })         <input type="submit" value="add" id="addwidgetvalue" name="addwidgetvalue" class="submitbutton" />         <input type="submit" value="delete" id="deletewidgetvalue" name="deletewidgetvalue" class="submitbutton" />          <p>             <input type="submit" value="save" />         </p>     </fieldset> }  <div>     @html.actionlink("back list", "index") </div> 

the reason happening because html helpers first @ modelstate posted values when binding , in model. means if inside post controller action try modify value , same value part of initial post request html helper use initial value , not 1 modified.

for example in editwidget action doing this:

if (request.form["deletewidgetvalue"] != null) {     widget.values.remove(request.form["listboxwidgetvalues"]);     return view("editwidget", widget); } 

you should remove posted value model state:

if (request.form["deletewidgetvalue"] != null) {     var itemtoremove = request.form["listboxwidgetvalues"];     var index = widget.values.indexof(itemtoremove);     modelstate.remove("values[" + index + "]");     widget.values.remove(itemtoremove);     return view("editwidget", widget); } 

so post request contained:

values[0] = 1 values[1] = 2 values[2] = 3 values[3] = 4 

inside post action removed example second item should remove model state or textboxfor helper still use old one.

you may find following blog post useful. it's asp.net mvc 2 webforms trivial adapt razor.


Comments

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -