2008-08-08 3 views
19

一部のリンクにフラグメント識別子を含める必要があります。このサイト上のURLの一部のように:Asp.Net MVC ActionLink、RedirectToActionなどを使用するときにフラグメント識別子を含める方法はありますか?

Debugging: IE6 + SSL + AJAX + post form = 404 error#5626

MVCに組み込まれているのいずれかの方法でこれを行う方法はありますか?または、自分のHTMLヘルパーをロールバックする必要がありますか?

答えて

5

次のリリースでこれをサポートすることを検討しています。

+0

これはdev10でリリースされる予定ですか? – ajma

1

短い答えは:いいえ。ASP.NET MVC Preview 3には、アクションリンクにアンカーを含めるためのファーストクラスの方法はありません。 Railsのurl_for:アンカーとは異なり、UrlHelper.GenerateUrl(およびそれを使用するActionLink、RedirectToActionなど)には、アンカーをエンコードできる魔法のプロパティ名はありません。

あなたが指摘しているように、あなたは自分自身をロールバックすることができます。これはおそらく最もクリーンなソリューションです。

Hackily、あなただけのルートでアンカーを含めると、あなたのパラメータのハッシュに値を指定することができます。

routes.MapRoute("WithTarget", "{controller}/{action}/{id}#{target}"); 
... 
<%= Html.ActionLink("Home", "Index", new { target = "foo" })%> 

これは/ホーム/インデックス/#fooのようなURLを生成します。残念ながら、これはURLの最後に表示されるURLパラメータではうまくいきません。したがって、このハックは、すべてのパラメータがURLパスコンポーネントとして表示される非常に単純な状況でのみ有効です。

+1

動作しません。 #は%23に変換されます。 – jpbochi

3

@Dominic、

私はルートのそれを置くことは、ルーティングの問題を引き起こすことはほとんど肯定的です。

@Ricky、

MVCは、このためのサポートをするまで、あなたはあなたのルートを作る方法についてもう少し「古い学校」することができます。たとえば、あなたが変換することができます:

<%= Html.ActionLink("Home", "Index") %> 

へ:

<a href='<%= Url.Action("Index") %>#2345'>Home</a> 

それともあなたは、本質的に同じことを行い、独自のヘルパーを書くことができます。

+1

私は、ASP.NET MVC Preview 3でルート内のターゲットを試しましたが、ルーティングに問題はありませんでした。ですから、あなたは「ほぼポジティブ」ですが、どんな問題があるのか​​を詳しく説明することは有用です。 –

18

Brad Wilsonが書いたように、文字列を連結するだけで、ビュー内に独自のリンクを構築することができます。しかし、RedirectToAction(または類似)を経由して生成されたリダイレクトにフラグメント名を追加することができ、このようなものが必要です:

public class RedirectToRouteResultEx : RedirectToRouteResult { 

    public RedirectToRouteResultEx(RouteValueDictionary values) 
     : base(values) { 
    } 

    public RedirectToRouteResultEx(string routeName, RouteValueDictionary values) 
     : base(routeName, values) { 
    } 

    public override void ExecuteResult(ControllerContext context) { 
     var destination = new StringBuilder(); 

     var helper = new UrlHelper(context.RequestContext); 
     destination.Append(helper.RouteUrl(RouteName, RouteValues)); 

     //Add href fragment if set 
     if (!string.IsNullOrEmpty(Fragment)) { 
      destination.AppendFormat("#{0}", Fragment); 
     } 

     context.HttpContext.Response.Redirect(destination.ToString(), false); 
    } 

    public string Fragment { get; set; } 
} 

public static class RedirectToRouteResultExtensions { 
    public static RedirectToRouteResultEx AddFragment(this RedirectToRouteResult result, string fragment) { 
     return new RedirectToRouteResultEx(result.RouteName, result.RouteValues) { 
      Fragment = fragment 
     }; 
    } 
} 

をそして、あなたのコントローラでは、あなたが呼びたい:

return RedirectToAction("MyAction", "MyController") 
     .AddFragment("fragment-name"); 

をURLが正しく生成されるはずです。

+3

これは素晴らしいことです。 MVC3には、 'RedirectToAction'ではなく、' ActionLink'へのオーバーロードがあります。 – kamranicus

+0

あなたは、私のヒーローです。 :) –

0

これはクライアント側の解決策ですが、jqueryが利用可能な場合は、このようなことができます。

<script language="javascript" type="text/javascript"> 
    $(function() { 
     $('div.imageHolder > a').each(function() { 
      $(this).attr('href', $(this).attr('href') + '#tab-works'); 
     }); 
    }); 
</script> 
4

MVC3(おそらく私がチェックしていない)では、UrlHelper.GenerateUrlをfragmentパラメータで渡すことができます。ここで

public static string Action(this UrlHelper url, string actionName, string controllerName, string fragment, object routeValues) 
{ 
    return UrlHelper.GenerateUrl(
     routeName: null, 
     actionName: actionName, 
     controllerName: controllerName, 
     routeValues: new System.Web.Routing.RouteValueDictionary(routeValues), 
     fragment: fragment, 
     protocol: null, 
     hostName: null, 
     routeCollection: url.RouteCollection, 
     requestContext: url.RequestContext, 
     includeImplicitMvcValues: true /*helps fill in the nulls above*/ 
    ); 
} 
+0

ちょっとぎこちないですが、ここの答えは最高です。たぶん、他の人はちょうど時代遅れです。 – jpbochi

関連する問題