Html.ActionLinkが「?Length = 4」をレンダリングする理由


305

なぜこのコードなのか非常に混乱しています

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" })

このリンクの結果:

<a hidefocus="hidefocus" href="/Home/About?Length=4">About</a>

そのhidefocus部分は私が目指していた?Length=4ものですが、どこから来たのですか?


4
この動作は、Html.BeginForm()メソッドでも発生します。
ジョナソンワトニー

回答:


326

Length = 4は、文字列オブジェクトをシリアル化する試みから来ています。コードはこのActionLinkメソッドを実行しています:

public static string ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes)

これは、stringrouteValuesのオブジェクト「Home」を取得します。MVCはこれをパブリックプロパティを検索してルート値に変換します。stringオブジェクトの場合、唯一のパブリックプロパティはLengthであり、Lengthパラメータでルートが定義されないため、プロパティ名と値がクエリ文字列パラメータとして追加されます。表示されていないページからこれを実行HomeControllerすると、欠落しているAboutアクションメソッドに関するエラーがスローされる可能性があります。以下を使用してみてください:

Html.ActionLink("About", "About", new { controller = "Home" }, new { hidefocus = "hidefocus" })

@Blah_Blah最近、私はこれをまったく使用せず、独自の<a>タグを作成し、Url.Action( "Action"、 "Controller")を使用することを好みます
roryf

@roryf心配する必要はありません...これはコードレビューでベストプラクティスとして使用され、日付を確認しませんでした。本当に
スタックオーバーフローを

すばらしい答えです。これを追加するだけでも、同じ理由でHtml.BeginRouteFormで発生します。Html.BeginRouteForm( "Route"、 "Action"、FormMethod.Post))奇妙な長さのものを取り除くHtml.BeginRouteForm( "Route"、new {action = "AgentSignUp"}、FormMethod.Post)でなければなりません
radm4

でも発生しUrl.Action()ます。からUrl.Action("Action", "Controller", new { area = "" })に変更するとUrl.Action("Action", new { controller = "Controller", area = "" })、Lengthプロパティが表示されなくなります。
ジョンワシャム2014

状況のこれらの種類を避けるために、あなたは常に指定することができますどのようなパラメータを使用すると、同様に、渡している:Html.ActionLink("About", "About", "Home", routeValues: null, htmlAttributes: new { hidefocus = "hidefocus" })
Epiplon

195

これを解決する方法は、匿名宣言(new {})の前の4番目のパラメーターにnullを追加して、次のメソッドオーバーロードを使用することです:(linkText、actionName、controllerName、routeValues、htmlAttributes):

Html.ActionLink("About", "About", "Home", null, new { hidefocus = "hidefocus" })

エリア間をリンクしない場合、これが最良の答えです。あなたがリンクの領域を指定する必要がある場合は、とrouteValues指定する必要があるだろうcontrollerし、areaURLに現れてからのLengthプロパティを維持します。
ジョンワシャム2014

@JohnWasham実際には、コントローラを指定する必要はありませんがrouteValues、エリアのみです。例:Html.ActionLink("About", "About", "Home", new {@area = "Admin"}, new { hidefocus = "hidefocus" })
Epiplon

1
@epiplon、私がそのようにコントローラーを指定する理由は、の最後の引数としてhtmlAttributesを含めない場合ActionLink、MVCがLength=xURLの最後に奇妙なパラメーターを含めるためです。たとえば、これをページに配置してから、ページのソースを表示すると、その意味がわかります。 @Html.ActionLink("About", "About", "Home", new { area = "Admin" }, new { hidefocus = "hidefocus" }) @Html.ActionLink("About", "About", "Home", new { area = "Admin" }) ただし、controllerエントリをにrouteValues配置Length=xすると、URLには配置されません。
John Washam、2015年

@epiplon、あなたも使用する必要はありません@@area = "Admin"、あなたは知っているだけのように。
John Washam

88

HTMLAttributesパラメーターを追加するのを忘れました。

これは変更なしで動作します:

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" },null)

わからない。なぜこれがうまくいかないのか。「new {hidefocus = ""}」を試してみたところ、うまくいく。
Naredla Nithesh Reddy

28

ActionLinkのパラメーターが正しくありません。匿名タイプの代わりに「ホーム」値をルート値として使用しようとしています。

最後のパラメータとして、new { }またはを追加する必要があるだけだと思いnullます。

編集:投稿をもう一度読んで、最後ではなく最後から2番目のパラメーターとしてnullを指定する可能性が高いことに気づいてください。


1
ところでそれを使用することは不可能なので、彼らは1つのメソッドを削除する必要があります!
マーククリメント2009年

5
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" }, new { })

これはオーバーロードを取得します:文字列linkText、文字列actionName、文字列controllerName、オブジェクトrouteValues、オブジェクトhtmlAttributes


3

5つのパラメーターを持つ正しいオーバーロードメソッドを使用してください。例:

@using (@Ajax.BeginForm("Register", "Account", null,
    new AjaxOptions
    {
        HttpMethod = "POST",
        OnSuccess = "OnSuccess",
        OnFailure = "OnFailure",
        OnBegin = "OnBegin",
        OnComplete = "OnComplete"
    }, new { @class = "form-login" }))

コントローラ名の後にnullを追加すると、私の場合に役立ちました。
Munam Yousuf

これは実質的に@Jesseの回答と同じ回答ですが、Ajaxバージョンをカバーするボーナスが追加されています。これはOPが要求したものではありませんが、同じ問題に関連しています。
gcoulby 2017

2

「ホーム」(コントローラーの名前)を削除するだけで、コードは次のようになります。

Html.ActionLink("About", "About", new { hidefocus = "hidefocus" })

1

属性名:

 @Html.ActionLink(linkText: "SomeText", actionName: "SomeAction", controllerName: "SomeControllerName", routeValues: new { parameterName = parameterValue}, htmlAttributes: null)

0

Jonathon Watneyがコメントで指摘したように、これは

Html.BeginForm()

メソッド。私の場合、対応するコントローラー+作成アクションのポストリクエストをターゲットとするCreate.cshtmlにいて

using (Html.BeginForm("Create")) {
  @Html.AntiForgeryToken()
  ...
}

これは、レンダリング時にフォームアクションにクエリ文字列"?Length = 6"を追加していました。roryfの承認された回答にヒントを得て、 "Create"の文字列長が6であると認識したので、明示的なアクション指定を削除することでこれを解決しました。

using (Html.BeginForm()) {
      @Html.AntiForgeryToken()
      ...
    }

0

おそらく他の人にも同じ問題があり、HTMLAttributesパラメーターを介してクラス値を提供する必要があります。これが私の解決策です:

@Html.ActionLink("About", "About", new { controller = "Home", area = "" }, new { hidefocus = "hidefocus", @class = "nav-item nav-link" })


0

私の質問への回答を検索すると、ここに到着しました。基本的には、問題の正しいオーバーロードの選択です@Html.ActionLink ここに画像の説明を入力してください
私は(最後のなしで)存在しないオーバーロードを選択していて、そのようなオーバーロードがなかったため、OPのような偽のURLが発生しました。 nullMVC

個人的なノート:あなたがすることができますuseあなたがoverloads-のいずれかを使用することができます匿名型を意味するものではありません存在しませんの?- 特定の作る: それは 持って定義します!
-MVC 5.2の時代にここに来ました

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.