MvcContrib сетки и флажки
Допустим, я отображаю флажок:
@Html.CheckboxFor(x => x.Checked) // Checked is true by default
ASP превратит это как:
<input checked="checked" data-val="true" data-val-required="The field is required." id="Checked" name="Checked" type="checkbox" value="true" />
<input name="Checked" type="hidden" value="false" />
Поскольку ASP выводит два ввода с одинаковым именем для флажка, мы также получаем два параметра GET в URL при отправке формы с флажком:
http://...?Checked=true&Checked=false
Допустим, я также использую MvcContrib для отображения таблицы с сортировкой.
Когда я сортирую столбец, MvcContrib не может понять дубликаты параметров GET, и вместо записи ?Checked=true&Checked=false
пишет ?Checked=true%2Cfalse
, который не может быть проанализирован в bool MVC3. Сообщение об ошибке после сортировки:
String was not recognized as a valid Boolean.
Кто-нибудь еще испытывал эту проблему с сеткой MvcContrib?
3 ответа
Хорошо, думаю, я придумала решение:
Создайте свой собственный HtmlTableGridRenderer:
public class CustomTableGridRenderer<TViewModel> : HtmlTableGridRenderer<TViewModel> where TViewModel : class
{
protected override void RenderHeaderText(GridColumn<TViewModel> column)
{
if (IsSortingEnabled && column.Sortable)
{
string sortColumnName = GenerateSortColumnName(column);
bool isSortedByThisColumn = GridModel.SortOptions.Column == sortColumnName;
var sortOptions = new GridSortOptions
{
Column = sortColumnName
};
if (isSortedByThisColumn)
{
sortOptions.Direction = (GridModel.SortOptions.Direction == SortDirection.Ascending)
? SortDirection.Descending
: SortDirection.Ascending;
}
else //default sort order
{
sortOptions.Direction = column.InitialDirection ?? GridModel.SortOptions.Direction;
}
var routeValues = CreateRouteValuesForSortOptions(sortOptions, GridModel.SortPrefix);
//Re-add existing querystring
foreach (var key in Context.RequestContext.HttpContext.Request.QueryString.AllKeys.Where(key => key != null))
{
if (!routeValues.ContainsKey(key))
{
routeValues[key] = Context.RequestContext.HttpContext.Request.QueryString[key];
}
}
var link = HtmlHelper.GenerateLink(Context.RequestContext, RouteTable.Routes, column.DisplayName, null, null, null, routeValues, null);
RenderText(link);
}
else
{
base.RenderHeaderText(column);
}
}
}
... и просто заменить
if(! routeValues.ContainsKey(key))
{
routeValues[key] = Context.RequestContext.HttpContext.Request.QueryString[key];
}
... с routeValues[key] = Context.RequestContext.HttpContext.Request.QueryString[key];
И используйте ваш новый рендеринг так:
@ Html.Grid ()... RenderUsing (новый CustomTableGridRenderer())
У меня была та же самая проблема, и после поиска и опробования множества различных решений, простое изменение решило ее. Просто убедитесь, что поместили это в свой контроллер прямо перед "обратным просмотром":
ModelState.Remove("Checked");
Плохое решение, но работает:
$(function() {
$("a[href*='true%2Cfalse']").each(function () {
$(this).attr("href", $(this).attr("href").replace("true%2Cfalse", "true"));
});
});
Пожалуйста, предоставьте другое решение на стороне сервера.