﻿# 在 ASP.NET MVC 使用 @Html.ActionLink 所發生的詭異現象

上上禮拜同事在開發一個 ASP.NET MVC 專案時遇到一個詭異問題，就是在 View 裡面輸出超連結時竟然會多出詭異的查詢字串(QueryString)，他使用標準的 @Html.ActionLink 輔助方法輸出 <A> 超連結時，竟然有些超連結的尾巴會加上 ?Length=4 這個查詢字串，但是在 ASP.NET MVC 的 View 裡根本就沒這樣設定。然而上週在台中教授 ASP.NET MVC 課程，竟然也有學員再次遇到相同的問題，我猜想這可能是初學者都會遇到的常見問題，特別寫文章來提醒各位。

首先，我們先來看看一個基本的 @Html.ActionLink 用法，如下圖示：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e79ecfe22ad950c52901-image_1678.png)

基於網頁設計師提供的 HTML 版型，工程師必須在輸出 <A> 超連結時加上 class 屬性 (HTML Attribute) 來套用 CSS 樣式，一般來說我們會直接選用 @Html.ActionLink 輔助方法的另一個多載來用，在 Visual Studio 中你當然會很自然的在參數最後面按下逗號 (,) 然後接著查看 Intellisense 的提示來輸入參數，這時你第一眼看到的參數便是 **htmlAttributes** 這項，也就繼續輸入下去了，如下圖示 (點圖可放大)：

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c4489c66fc341f80669d-image_thumb_97.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/eb06895c8819f2176a2d-image_1679.png)

輸入完成後如下圖示：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/9d254a720560f0f4d393-image_1680.png)

**註**：因 class 本身是 C# 關鍵字，所以當使用關鍵字當屬性名稱時，必須在屬性名稱之前加上 @ 符號才行，相關文章請參考 [如何在 C# 中使用關鍵字當屬性名稱 ( ASP.NET MVC )](/post/2008/12/28/How-to-use-CSharp-keyword-as-a-property-name) 文章。

這時我們將網站執行起來，你將會發現一個很詭異的事情發生，這個超連結確實已經家上了 CSS 樣式所需的 class 屬性，不過超連結的地方卻多加上了 **?Length=7** 這個查詢字串，是不是非常的詭異呢！

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b551eabdfbeda3248d02-image_1681.png)

經過一番研究後才發現，在這個 @Html.ActionLink 輔助方法中，總共有 10 個之多，很少人會把這些多載都看完，而是有用到才去看他。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/1af52d7704c3afe5a30e-image_1682.png)

原來我們剛剛輸入逗號 (,) 後所選擇到的是第 5 個多載，雖然我們輸入的第 4 個參數是 **htmlAttributes** 這項，但是第 3 個參數卻是 **routeValues** 啊！

我們原本輸入的第 3 個參數輸入的是 Controller 名稱才對且參數是字串型別，但如今被辨識為如下圖的這個 **routeValues** 參數了，而且被視為是 **object** 型別。

[![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/a0265b7faeb582c357f1-image_thumb_98.png "image")](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c6d9633bafcd14be4150-image_1683.png)

也因此我們的 "Home" 字串參數，卻變成了 **物件** (object) 被傳入，而該 **物件** 其實是 **字串型別**([System.String](http://msdn.microsoft.com/zh-tw/library/system.string.aspx))，字串型別唯一的屬性就是 **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 個多載才對！

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/042743f31bfdc10e0c1b-image_thumb_99.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e39f209b1d5c02268e37-image_1684.png)

但是，第 7 個多載的第 4 個參數是 routeValue，第 5 個參數才是 htmlAttributes，所以我們應該在第 4 個參數先傳入 null，然後再接著輸入第 5 個 htmlAttributes 參數才對，如下圖示：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/4c21dad5a1c6c336a21a-image_1685.png)

如此一來，ASP.NET MVC 輸出的超連結才會是正確的版本！

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/adfece369a4c55dec089-image_1686.png)

各位 ASP.NET MVC 開發人員可要小心囉！ ^\_^

**相關連結**

-   [如何在 C# 中使用關鍵字當屬性名稱 ( ASP.NET MVC )](/post/2008/12/28/How-to-use-CSharp-keyword-as-a-property-name)
-   [LinkExtensions.ActionLink 方法](http://msdn.microsoft.com/zh-tw/library/system.web.mvc.html.linkextensions.actionlink.aspx)

-   [LinkExtensions.ActionLink 方法 (HtmlHelper, String, String, Object, Object)](http://msdn.microsoft.com/zh-tw/library/dd492124.aspx)
-   [LinkExtensions.ActionLink 方法 (HtmlHelper, String, String, String, Object, Object)](http://msdn.microsoft.com/zh-tw/library/dd504972.aspx)
