我正在编写一个通用的html帮助程序,它将字典传递回我的控制器。 (也许这已经存在了?)
控制器:
[HttpPost]
public ActionResult Odometer(IDictionary<String, int> Odometers, String UserInputInJson)
{
...
}
这是现在的助手。它的工作没有名称(注释掉)。
助手:
public static MvcHtmlString EditorToSubmitDictionaryEntryFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> item, String key)
{
var url = new UrlHelper(helper.ViewContext.RequestContext);
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(item, helper.ViewData);
string value = metadata.Model.ToString();
// string name = metadata.PropertyName + "s"; // make it plural
Type type = typeof(TProperty);
// build the first hidden Index tag: <input name="Index" id="Index" type="hidden" value="1D6H983G3DL784930"/>
var indexAnchorBuilder = new TagBuilder("input");
indexAnchorBuilder.MergeAttribute("name", "Index");
indexAnchorBuilder.MergeAttribute("id", "Index");
indexAnchorBuilder.MergeAttribute("type", "hidden");
indexAnchorBuilder.MergeAttribute("value", key);
string indexAnchorHtml = indexAnchorBuilder.ToString(TagRenderMode.Normal);
// <input name="[1D6H983G3DL784930].Value" class="text-box single-line" type="number" value="12345"/>
// <input name="Odometers[1D6H983G3DL784930].Value" class="text-box single-line" id="Odometers[1D6H983G3DL784930].Value" type="number" value="12345"/>
var valueAnchorBuilder = new TagBuilder("input");
valueAnchorBuilder.MergeAttribute("name", /*name +*/ "["+ key +"].Value");
valueAnchorBuilder.MergeAttribute("id", /*name +*/ "[" + key + "].Value");
valueAnchorBuilder.MergeAttribute("class", "text-box single-line");
if (type == typeof(int) || type == typeof(int?) || type == typeof(double) || type == typeof(double?) || type == typeof(decimal) || type == typeof(decimal?) || type == typeof(float) || type == typeof(float?))
valueAnchorBuilder.MergeAttribute("type", "number");
else
valueAnchorBuilder.MergeAttribute("type", "text");
valueAnchorBuilder.MergeAttribute("value", value);
string valueAnchorHtml = valueAnchorBuilder.ToString(TagRenderMode.Normal);
// <input name="[1D6H983G3DL784930].Key" id="[1D6H983G3DL784930].Key" type="hidden" value="1D6H983G3DL784930"></input>"
// <input name="Odometers[1D6H983G3DL784930].Key" id="Odometers[1D6H983G3DL784930].Key" type="hidden" value="1D6H983G3DL784930"></input>"
var keyAnchorBuilder = new TagBuilder("input");
keyAnchorBuilder.MergeAttribute("name", /*name +*/ "[" + key + "].Key");
keyAnchorBuilder.MergeAttribute("id", /*name +*/ "[" + key + "].Key");
keyAnchorBuilder.MergeAttribute("type", "hidden");
keyAnchorBuilder.MergeAttribute("value", key);
string keyAnchorHtml = keyAnchorBuilder.ToString(TagRenderMode.Normal);
return MvcHtmlString.Create(indexAnchorHtml + valueAnchorHtml + keyAnchorHtml);
}
以下是我在视图和局部视图中调用此帮助程序的方法。
@using (Html.BeginForm("Odometer", "DEQToo", FormMethod.Post))
{
//this is here so we can keep track of what the user searched for, in case the session times out and we have to re-build the page.
@Html.HiddenFor(model => model.UserInputInJson)
<table class="footable table">
<thead>
<tr>
<th>@Html.DisplayNameFor(model => model.vCollect[""].Odometer)</th>
<th data-hide="phone">@Html.DisplayNameFor(model => model.vCollect[""].VIN)</th>
<th data-hide="phone,tablet" data-type="numeric">@Html.DisplayNameFor(model => model.vCollect[""].VehicleYear)</th>
<th data-hide="phone">@Html.DisplayNameFor(model => model.vCollect[""].Make)</th>
<th data-hide="phone,tablet">@Html.DisplayNameFor(model => model.vCollect[""].Model)</th>
</tr>
</thead>
<tbody>
@if (Model != null)
{
foreach (VehicleWithMostRecentTestOutput v in Model)
{
@Html.Partial("_OdometerRowPartial", v)
}
}
</tbody>
</table>
<input type="submit" value="@DEQTooResource.resCorrectOdometer" id="OdometerListSubmit" />
}
我称之为EditorToSubmitDictionaryEntryFor()的局部视图:
<tr>
<td>@Html.EditorToSubmitDictionaryEntryFor(model => model.Odometer, Model.VIN)</td>
<td>@Html.DisplayFor(model => model.VIN) </td>
<td>@Html.DisplayFor(model => model.VehicleYear)</td>
<td>@Html.DisplayFor(model => model.Make)</td>
<td>@Html.DisplayFor(model => model.Model)</td>
</tr>
我想使用这个名称,因此它更通用,我可以在一个页面上有多个这样的名称。当我取消注释名称,将其添加到键和值的名称和id属性时,模型状态无效,我不会将用户输入传入控制器。
任何人都可以解释为什么会发生这种情况并提出如何应对的建议吗?任何帮助将不胜感激。
答案 0 :(得分:1)
你只需要:
valueAnchorBuilder.MergeAttribute("id", id + "["+ key +"]");
您只希望Odometers[1D6H983G3DL784930]
没有.Value
,而不是Odometers[1D6H983G3DL784930].Value
Item属性是索引器的另一个名称,因此您可以在访问元素时省略其名称。