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?
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
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.