10

假设我渲染了一个复选框:

@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 为 Checkbox 输出了两个具有相同名称的输入,因此在提交带有复选框的表单时,我们还在 URL 中获得了两个 GET 参数:

http://...?Checked=true&Checked=false

假设我也在使用 MvcContrib 来显示带有排序的表格。

当我对列进行排序时,MvcContrib 无法理解重复的 GET 参数,而是?Checked=true&Checked=false写入?Checked=true%2Cfalse,而 MVC3 无法将其解析为布尔值。排序后的错误信息是:

String was not recognized as a valid Boolean.

有没有其他人在 MvcContrib 网格中遇到过这个问题?

4

3 回答 3

4

好的,我想我已经想出了解决方案:

创建自己的 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(new CustomTableGridRenderer())

于 2012-10-17T12:09:06.380 回答
1

我遇到了同样的问题,在搜索和尝试了很多不同的解决方案之后,一个简单的改变就解决了。只需确保在“返回视图”之前将其放入控制器中:

 ModelState.Remove("Checked"); 
于 2016-05-23T05:35:36.103 回答
0

糟糕的解决方案,但有效:

 $(function() {
        $("a[href*='true%2Cfalse']").each(function () {
            $(this).attr("href", $(this).attr("href").replace("true%2Cfalse", "true"));
        });
    });

请提供其他服务器端解决方案。

于 2013-09-24T18:00:36.880 回答