如何将路由值添加到超链接?
How do I add route values to hyperlink?
使用 VS2013,MVC5,假设模型中有一条 master/header 记录,以及多个相关的详细信息,MVC 视图将在文本框中显示 header 数据,并将显示详细信息在网络网格中。控制器有一个操作方法,它接受要显示的 header 记录的 ID。没有参数列表为空的操作方法。当我单击 resulting/displayed 视图的网络网格 header 超链接时,我收到一条错误...
The parameters dictionary contains a null entry for parameter 'Id' of
non-nullable type 'System.Int32' for method
'System.Web.Mvc.ActionResult Index(Int32)' in
'WebGridTest.Controllers.HomeController'. An optional parameter must
be a reference type, a nullable type, or be declared as an optional
parameter. Parameter name: parameters
这是我的代码...
代码
型号
我的详细信息
namespace WebGridTest.Models
{
public class MyDetail
{
public string Column1 { get; set; }
public string Column2 { get; set; }
public string Column3 { get; set; }
}
}
我的页眉
using System.Collections.Generic;
namespace WebGridTest.Models
{
public class MyHeader
{
public MyHeader()
{
this.MyDetails = new List<MyDetail>();
}
public int Id { get; set; }
public List<MyDetail> MyDetails { get; set; }
}
}
控制器
家庭控制器
using System.Web.Mvc;
namespace WebGridTest.Controllers
{
public class HomeController : Controller
{
public ActionResult Index(int Id)
{
var model = new Models.MyHeader();
model.Id = 2; // HARD CODED VALUES FOR DEMONSTRATING THIS ISSUE
var detail1 = new Models.MyDetail();
detail1.Column1 = "1A";
detail1.Column2 = "1B";
detail1.Column3 = "1C";
model.MyDetails.Add(detail1);
var detail2 = new Models.MyDetail();
detail2.Column1 = "2A";
detail2.Column2 = "2B";
detail2.Column3 = "2C";
model.MyDetails.Add(detail2);
var detail3 = new Models.MyDetail();
detail3.Column1 = "3A";
detail3.Column2 = "3B";
detail3.Column3 = "3C";
model.MyDetails.Add(detail3);
return View(viewName: "Index", model: model);
}
}
}
观看次数
Index.cshtml
@model WebGridTest.Models.MyHeader
@{
ViewBag.Title = "Home Page";
}
@using (Html.BeginForm(actionName: "Index", controllerName: "Home", method: FormMethod.Post))
{
<p></p>
@Html.TextBoxFor(x => x.Id)
<p></p>
WebGrid grid = new WebGrid(null, canPage: false);
grid.Bind(Model.MyDetails);
@grid.GetHtml(tableStyle: "table table-bordered lookup-table", columns:
grid.Columns(
grid.Column(
"Column1"
, "Column 1"
, (item) => (item.Column1)
)
,
grid.Column(
"Column2"
, "Column 2"
, (item) => (item.Column2)
)
,
grid.Column(
"Column3"
, "Column 3"
, (item) => (item.Column3)
)
)
)
}
当我 运行 项目时,我收到上述错误。如果我从操作方法 'Index' 中删除参数,程序将不会生成错误。
当我将鼠标悬停在网页中的 header 上时,我看到了生成的 URL。我可以看到它不包括查询字符串参数列表中的路由值。它仅包括排序值。示例...
我的示例做作且琐碎,但足以说明,我需要 Id 来标识要显示的记录。
如何在 headers 列上指定 id 路由值?
根据网络研究,许多开发人员建议使用 JavaScript 修改 DOM 以包含路由值。这似乎可行,但实际上远离 MVC 结构,转而支持 client-side 评估和操作。该信息在 IIS/MVC 中可用,但缺乏将信息应用到网络网格 header 锚点的能力。
我找到了 JavaScript 的替代方法,该方法将解决方案完全保留在 C# 中。我将以问答形式回答我自己的问题。
解决方案涉及创建一个扩展方法,该方法将在响应原始客户端请求之前将路由值注入结果 HTML。这需要添加扩展方法 class,并在视图中添加方法调用。
示例...
扩展方法Class
using System.Web;
namespace WebGridTest
{
public static class ExtensionMethods
{
public static IHtmlString AddRouteValuesToWebGridHeaders(this IHtmlString grid, string routeValues)
{
var regularString = grid.ToString();
regularString = regularString.Replace("?sort=", "?" + routeValues + "&sort=");
HtmlString htmlString = new HtmlString(regularString);
return htmlString;
}
}
}
增强视图
(注意对扩展方法的调用'AddRouteValuesToWebGridHeaders')...
@model WebGridTest.Models.MyHeader
@{
ViewBag.Title = "Home Page";
}
@using (Html.BeginForm(actionName: "Index", controllerName: "Home", method: FormMethod.Post))
{
<p></p>
@Html.TextBoxFor(x => x.Id)
<p></p>
WebGrid grid = new WebGrid(null, canPage: false);
grid.Bind(Model.MyDetails);
@grid.GetHtml(tableStyle: "table table-bordered lookup-table", columns:
grid.Columns(
grid.Column(
"Column1"
, "Column 1"
, (item) => (item.Column1)
)
,
grid.Column(
"Column2"
, "Column 2"
, (item) => (item.Column2)
)
,
grid.Column(
"Column3"
, "Column 3"
, (item) => (item.Column3)
)
)
).AddRouteValuesToWebGridHeaders("Id=" + Model.Id.ToString())
}
结论
注入 HTML 不是首选解决方案,因为与任何其他解析算法一样,它是高度假设的。除了 HTML 解析之外,我没有找到其他方法。也许下载此 class 的 Microsoft open-source 版本并创建具有所需行为的覆盖将是一个更优雅的解决方案。
** 请求 ** - Microsoft - 请添加 control/augment 网络网格中锚点 header 呈现的能力。
欢迎留言评论...
使用 VS2013,MVC5,假设模型中有一条 master/header 记录,以及多个相关的详细信息,MVC 视图将在文本框中显示 header 数据,并将显示详细信息在网络网格中。控制器有一个操作方法,它接受要显示的 header 记录的 ID。没有参数列表为空的操作方法。当我单击 resulting/displayed 视图的网络网格 header 超链接时,我收到一条错误...
The parameters dictionary contains a null entry for parameter 'Id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32)' in 'WebGridTest.Controllers.HomeController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters
这是我的代码...
代码
型号
我的详细信息
namespace WebGridTest.Models
{
public class MyDetail
{
public string Column1 { get; set; }
public string Column2 { get; set; }
public string Column3 { get; set; }
}
}
我的页眉
using System.Collections.Generic;
namespace WebGridTest.Models
{
public class MyHeader
{
public MyHeader()
{
this.MyDetails = new List<MyDetail>();
}
public int Id { get; set; }
public List<MyDetail> MyDetails { get; set; }
}
}
控制器
家庭控制器
using System.Web.Mvc;
namespace WebGridTest.Controllers
{
public class HomeController : Controller
{
public ActionResult Index(int Id)
{
var model = new Models.MyHeader();
model.Id = 2; // HARD CODED VALUES FOR DEMONSTRATING THIS ISSUE
var detail1 = new Models.MyDetail();
detail1.Column1 = "1A";
detail1.Column2 = "1B";
detail1.Column3 = "1C";
model.MyDetails.Add(detail1);
var detail2 = new Models.MyDetail();
detail2.Column1 = "2A";
detail2.Column2 = "2B";
detail2.Column3 = "2C";
model.MyDetails.Add(detail2);
var detail3 = new Models.MyDetail();
detail3.Column1 = "3A";
detail3.Column2 = "3B";
detail3.Column3 = "3C";
model.MyDetails.Add(detail3);
return View(viewName: "Index", model: model);
}
}
}
观看次数
Index.cshtml
@model WebGridTest.Models.MyHeader
@{
ViewBag.Title = "Home Page";
}
@using (Html.BeginForm(actionName: "Index", controllerName: "Home", method: FormMethod.Post))
{
<p></p>
@Html.TextBoxFor(x => x.Id)
<p></p>
WebGrid grid = new WebGrid(null, canPage: false);
grid.Bind(Model.MyDetails);
@grid.GetHtml(tableStyle: "table table-bordered lookup-table", columns:
grid.Columns(
grid.Column(
"Column1"
, "Column 1"
, (item) => (item.Column1)
)
,
grid.Column(
"Column2"
, "Column 2"
, (item) => (item.Column2)
)
,
grid.Column(
"Column3"
, "Column 3"
, (item) => (item.Column3)
)
)
)
}
当我 运行 项目时,我收到上述错误。如果我从操作方法 'Index' 中删除参数,程序将不会生成错误。
当我将鼠标悬停在网页中的 header 上时,我看到了生成的 URL。我可以看到它不包括查询字符串参数列表中的路由值。它仅包括排序值。示例...
我的示例做作且琐碎,但足以说明,我需要 Id 来标识要显示的记录。
如何在 headers 列上指定 id 路由值?
根据网络研究,许多开发人员建议使用 JavaScript 修改 DOM 以包含路由值。这似乎可行,但实际上远离 MVC 结构,转而支持 client-side 评估和操作。该信息在 IIS/MVC 中可用,但缺乏将信息应用到网络网格 header 锚点的能力。
我找到了 JavaScript 的替代方法,该方法将解决方案完全保留在 C# 中。我将以问答形式回答我自己的问题。
解决方案涉及创建一个扩展方法,该方法将在响应原始客户端请求之前将路由值注入结果 HTML。这需要添加扩展方法 class,并在视图中添加方法调用。
示例...
扩展方法Class
using System.Web;
namespace WebGridTest
{
public static class ExtensionMethods
{
public static IHtmlString AddRouteValuesToWebGridHeaders(this IHtmlString grid, string routeValues)
{
var regularString = grid.ToString();
regularString = regularString.Replace("?sort=", "?" + routeValues + "&sort=");
HtmlString htmlString = new HtmlString(regularString);
return htmlString;
}
}
}
增强视图
(注意对扩展方法的调用'AddRouteValuesToWebGridHeaders')...
@model WebGridTest.Models.MyHeader
@{
ViewBag.Title = "Home Page";
}
@using (Html.BeginForm(actionName: "Index", controllerName: "Home", method: FormMethod.Post))
{
<p></p>
@Html.TextBoxFor(x => x.Id)
<p></p>
WebGrid grid = new WebGrid(null, canPage: false);
grid.Bind(Model.MyDetails);
@grid.GetHtml(tableStyle: "table table-bordered lookup-table", columns:
grid.Columns(
grid.Column(
"Column1"
, "Column 1"
, (item) => (item.Column1)
)
,
grid.Column(
"Column2"
, "Column 2"
, (item) => (item.Column2)
)
,
grid.Column(
"Column3"
, "Column 3"
, (item) => (item.Column3)
)
)
).AddRouteValuesToWebGridHeaders("Id=" + Model.Id.ToString())
}
结论
注入 HTML 不是首选解决方案,因为与任何其他解析算法一样,它是高度假设的。除了 HTML 解析之外,我没有找到其他方法。也许下载此 class 的 Microsoft open-source 版本并创建具有所需行为的覆盖将是一个更优雅的解决方案。
** 请求 ** - Microsoft - 请添加 control/augment 网络网格中锚点 header 呈现的能力。
欢迎留言评论...