上上禮拜同事在開發一個 ASP.NET MVC 專案時遇到一個詭異問題,就是在 View 裡面輸出超連結時竟然會多出詭異的查詢字串(QueryString),他使用標準的 @Html.ActionLink 輔助方法輸出 <A> 超連結時,竟然有些超連結的尾巴會加上 ?Length=4 這個查詢字串,但是在 ASP.NET MVC 的 View 裡根本就沒這樣設定。然而上週在台中教授 ASP.NET MVC 課程,竟然也有學員再次遇到相同的問題,我猜想這可能是初學者都會遇到的常見問題,特別寫文章來提醒各位。
首先,我們先來看看一個基本的 @Html.ActionLink 用法,如下圖示:
基於網頁設計師提供的 HTML 版型,工程師必須在輸出 <A> 超連結時加上 class 屬性 (HTML Attribute) 來套用 CSS 樣式,一般來說我們會直接選用 @Html.ActionLink 輔助方法的另一個多載來用,在 Visual Studio 中你當然會很自然的在參數最後面按下逗號 (,) 然後接著查看 Intellisense 的提示來輸入參數,這時你第一眼看到的參數便是 htmlAttributes 這項,也就繼續輸入下去了,如下圖示 (點圖可放大):
輸入完成後如下圖示:
註:因 class 本身是 C# 關鍵字,所以當使用關鍵字當屬性名稱時,必須在屬性名稱之前加上 @ 符號才行,相關文章請參考 如何在 C# 中使用關鍵字當屬性名稱 ( ASP.NET MVC ) 文章。
這時我們將網站執行起來,你將會發現一個很詭異的事情發生,這個超連結確實已經家上了 CSS 樣式所需的 class 屬性,不過超連結的地方卻多加上了 ?Length=7 這個查詢字串,是不是非常的詭異呢!
經過一番研究後才發現,在這個 @Html.ActionLink 輔助方法中,總共有 10 個之多,很少人會把這些多載都看完,而是有用到才去看他。
原來我們剛剛輸入逗號 (,) 後所選擇到的是第 5 個多載,雖然我們輸入的第 4 個參數是 htmlAttributes 這項,但是第 3 個參數卻是 routeValues 啊!
我們原本輸入的第 3 個參數輸入的是 Controller 名稱才對且參數是字串型別,但如今被辨識為如下圖的這個 routeValues 參數了,而且被視為是 object 型別。
也因此我們的 "Home" 字串參數,卻變成了 物件 (object) 被傳入,而該 物件 其實是 字串型別(System.String),字串型別唯一的屬性就是 Length 屬性,以我們輸入的這個 "Home” 字串,這個 Length 的值為 4,所以最後被傳入到 ASP.NET MVC 的 routeValues 參數就變成了 Length = 4 的路由值,最後輸出的超連結就被加上了 ?Length=4 查詢字串了!
所以結論是:我們選錯多載了!
由此可知,這裡 Length 的值,會依據你輸入的 controllerName 字串長度不同而有所不同,所以可能是以下查詢自串都有可能:
- /?Length=1
- /?Length=2
- /?Length=3
- /?Length=4
- /?Length=6
- /?Length=7
- /?Length=8
- /?Length=9
- /?Length=10
- /?Length=11
- /?Length=12
如果我們第 3 個參數要用controllerName 參數的話,那麼我們應該選擇的是第 7 個多載才對!
但是,第 7 個多載的第 4 個參數是 routeValue,第 5 個參數才是 htmlAttributes,所以我們應該在第 4 個參數先傳入 null,然後再接著輸入第 5 個 htmlAttributes 參數才對,如下圖示:
如此一來,ASP.NET MVC 輸出的超連結才會是正確的版本!
各位 ASP.NET MVC 開發人員可要小心囉! ^_^
相關連結