簡體   English   中英

如何將路由值添加到超鏈接?

[英]How do I add route values to hyperlink?

使用VS2013,MVC5,假設模型中存在主/標題記錄以及多個相關詳細信息,則MVC視圖將在文本框中顯示標題數據,並在Web網格中顯示詳細信息。 控制器具有一個動作方法,該方法接受要顯示的標題記錄的ID。 沒有帶空參數列表的操作方法。 當我單擊結果/顯示的視圖的Web網格標題超鏈接時,出現錯誤...

參數字典包含“ WebGridTest.Controllers.HomeController”中方法“ System.Web.Mvc.ActionResult Index(Int32)”的非空類型“ System.Int32”的參數“ Id”的空條目。 可選參數必須是引用類型,可為空的類型,或者必須聲明為可選參數。 參數名稱:參數

這是我的代碼...

楷模

我的細節

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)
            )
        )
    )
}

當我運行項目時,我收到上述錯誤。 如果我從操作方法“索引”中刪除參數,程序將不會產生錯誤。

將鼠標懸停在網頁的標題上時,會看到生成的URL。 我可以看到它在查詢字符串參數列表中不包含路由值。 它僅包含排序值。 例...

http:// localhost:62802 / Home / Index?sort = Column1&sortdir = ASC

我的示例是人為的且瑣碎的,但足以說,我需要ID來標識要顯示的記錄。

如何在列標題上指定ID路由值?

在網上進行研究后,許多開發人員建議使用JavaScript修改DOM以包含路由值。 這似乎可行,但實際上已脫離MVC結構,轉而支持客戶端評估和操作。 該信息在IIS / MVC中可用,但是缺乏應用該信息(特別是應用於Web網格標題錨)的功能。

我找到了JavaScript的替代方法,可以將解決方案完全保留在C#中。 我將以問答形式回答我自己的問題。

該解決方案涉及創建一個擴展方法,該方法將在響應原始客戶端請求之前將路由值注入到生成的HTML中。 這需要添加擴展方法類,並在視圖中添加方法調用。

例...

擴展方法類

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解析之外,我沒有找到其他方法。 也許下載此類的Microsoft開源版本並創建具有所需行為的替代將是一個更優雅的解決方案。

**請求**-Microsoft-請在Web網格標題渲染中添加控制/增強錨點的功能。

請隨意發表評論...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM