Hidden input for Dictionary<string, string> in ASP.NET MVC 3

纵饮孤独 提交于 2019-12-07 06:24:27

问题


I need to get my model properties in Post action, so need to hidden element for them, but I have a problem with type of Dictionary <string, string>. this is My model:

public class ViewModel{
 ...
 public ViewPart ViewPart { get; set; }
}

public class ViewPart {
 ...
 public Dictionary<string, string> Flags { get; set; }
}

And My Controller:

Dictionary<string, string> flags = new Dictionary<string, string>();
flags.Add("kind", "Edit");
flags.Add("Command", "Save");
ViewModel model = new ViewModel(){ Flags  = flags };
return View(model);

In View:

@foreach(var item in Model.ViewPart.Flags) { 
 <input type="hidden" id="ViewPart_Flags_@(item.Key)" value="@item.Value" name="ViewPart.Flags[@(item.Key)]" />
}

Also I try This one :

@foreach(var item in Model.ViewPart.Flags) { 
  @Html.HiddenFor(modelItem => item)
}

Update Post Action:

[HttpPost]
public ActionResult MyPostAction(ViewModel model){
  //model.ViewPart.Flags is null
}

But in Post action the Flags is Always null, why? where is my fault? Is there any better way to pass variables from View To Action?


回答1:


You need two hidden fields one for the Key and one for the Value if you want to modelbind to a dictionary:

var index = 0;
foreach (var item in Model.ViewPart.Flags)
{

    <input type="hidden" value="@item.Key" 
                         name="ViewPart.Flags[@(index)].Key"/>
    <input type="hidden" value="@item.Value" 
                         name="ViewPart.Flags[@(index)].Value"/>

    index++;
}
    <input type="submit" value="Save"/>

Note, you will be also need a running index to make the model binder happy.

Or if you don't want to have a running you can solve with an addtional hidden Index field:

foreach (var item in Model.ViewPart.Flags)
{

    <input type="hidden" value="@item.Key" 
                         name="ViewPart.Flags.Index"/>
    <input type="hidden" value="@item.Key" 
                         name="ViewPart.Flags[@(item.Key)].Key" />
    <input type="hidden" value="@item.Value" 
                         name="ViewPart.Flags[@(item.Key)].Value" />
}
    <input type="submit" value="Save"/>
}

You can find a lots of info about modelbinding with collections in this two article:

  • ASP.NET Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries
  • Model Binding To A List



回答2:


Change your post action to this

[HttpPost]
public ActionResult MyPostAction(ViewModel model, ViewPart viewPart)
{
    model.ViewPart.Flags = viewPart.Flags;
}

and in the view use

@foreach(var item in Model.ViewPart.Flags) { 
  @Html.HiddenFor(modelItem => item)
}

If this doesn't work, check the source of the rendered HTML and see if the the Hidden information is rendered. I'm not sure if @Html.HiddenFor will work with a Dictionary you may need to write it out like you had done previously if it doesn't.



来源:https://stackoverflow.com/questions/11374097/hidden-input-for-dictionarystring-string-in-asp-net-mvc-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!