15

C#関数内の@ Html.ActionLinkメソッドを呼び出して、リンクが設定された文字列を返したいとします。このようなMVC 3 @ Html.ActionLinkをC#コード内で使用する方法

何か:

public static string GetUnlockText(this HtmlHelper helper) 
{ 
    string a = "Email is locked, click " + helper.ActionLink("here to unlock.", "unlock"); 
    return a; 
} 

か、aspxページの範囲の外では、このリンクを生成することを意味する場合は、必要があります:あなたはHtmlHelperの拡張メソッドを作成することができ

string a = "Email is locked, click " + @Html.ActionLink("here to unlock.", "unlock") ; 
+0

どのようなユースケースですか? – tvanfosson

+0

私が望むのは、エラーを解決するためにリンクに「ModelState.AddModelError」を追加することです。 – roncansan

答えて

7

コントローラでこれを実現したいと仮定すると、いくつかのジャンプがあります。 ViewDataDictionaryTempDataDictionaryをインスタンス化する必要があります。次に、ControllerContextを取得し、IViewを作成する必要があります。最後に、これらすべての要素(プラスRouteCollection)を使用してHtmlHelperを作成する準備が整いました。

これをすべて完了したら、LinkExtensions.ActionLinkを使用してカスタムリンクを作成できます。あなたの視点では、リンクがHTMLエンコードされないようにするには、@Html.Raw()を使用する必要があります。ここで必要なコードは次のとおりです。

var vdd = new ViewDataDictionary(); 
var tdd = new TempDataDictionary(); 
var controllerContext = this.ControllerContext; 
var view = new RazorView(controllerContext, "/", "/", false, null); 
var html = new HtmlHelper(new ViewContext(controllerContext, view, vdd, tdd, new StringWriter()), 
    new ViewDataContainer(vdd), RouteTable.Routes); 
var a = "Email is locked, click " + LinkExtensions.ActionLink(html, "here to unlock.", "unlock", "controller").ToString(); 

このすべてを示したので、私はあなたのビューでこれを行うには非常に良いアイデアであることを警告します。 ViewModelにエラーやその他の情報を追加し、ビューをコーディングしてリンクを作成します。これが複数のビューで必要な場合は、リンク作成を行うHtmlHelperを作成します。 one.beat.consumer対処するため

UPDATE

、私の最初の答えは何ができるかの例でした。開発者はこの技術を再利用する必要がある場合、複雑さはそうように、静的なヘルパーに隠すことができる。

public static class ControllerHtml 
{ 
    // this class from internal TemplateHelpers class in System.Web.Mvc namespace 
    private class ViewDataContainer : IViewDataContainer 
    { 
     public ViewDataContainer(ViewDataDictionary viewData) 
     { 
      ViewData = viewData; 
     } 

     public ViewDataDictionary ViewData { get; set; } 
    } 

    private static HtmlHelper htmlHelper; 

    public static HtmlHelper Html(Controller controller) 
    { 
     if (htmlHelper == null) 
     { 
      var vdd = new ViewDataDictionary(); 
      var tdd = new TempDataDictionary(); 
      var controllerContext = controller.ControllerContext; 
      var view = new RazorView(controllerContext, "/", "/", false, null); 
      htmlHelper = new HtmlHelper(new ViewContext(controllerContext, view, vdd, tdd, new StringWriter()), 
       new ViewDataContainer(vdd), RouteTable.Routes); 
     } 
     return htmlHelper; 
    } 

    public static HtmlHelper Html(Controller controller, object model) 
    { 
     if (htmlHelper == null || htmlHelper.ViewData.Model == null || !htmlHelper.ViewData.Model.Equals(model)) 
     { 
      var vdd = new ViewDataDictionary(); 
      vdd.Model = model; 
      var tdd = new TempDataDictionary(); 
      var controllerContext = controller.ControllerContext; 
      var view = new RazorView(controllerContext, "/", "/", false, null); 
      htmlHelper = new HtmlHelper(new ViewContext(controllerContext, view, vdd, tdd, new StringWriter()), 
       new ViewDataContainer(vdd), RouteTable.Routes); 
     } 
     return htmlHelper; 
    } 
} 

次に、コントローラに、それはそうように使用されている:

var a = "Email is locked, click " + 
    ControllerHtml.Html(this).ActionLink("here to unlock.", "unlock", "controller").ToString(); 

等そう:

var model = new MyModel(); 
var text = ControllerHtml.Html(this, model).EditorForModel(); 

それはUrl.Actionを使用する方が簡単ですが、これは今(フルインテリセンスと)HtmlHelpersのすべてを使用して、コントローラ内の任意のマークアップを生成するための強力なツール内に延びています。

電子メール、pdf生成、オンラインドキュメント配信などのモデルとエディタテンプレートを使用してマークアップを生成することが可能です。

+0

counsellorben、@roncansan ...私の編集された答えと思われます。私はこれがまったく必要ではないと思う。 –

+0

@ one.beat.consumer、私の更新を参照してください。 – counsellorben

+1

大規模なソリューションとよく書かれたコード。私はそれをまったく批判していない。私はコントローラが "マークアップを生成する"適切な場所ではないと考えています。おそらくあまりにも純粋ですが、コントローラの役割は、ルートコールを処理し、必要なリソース(モデル、サービス)を収集し、ビューに注入することです。ビューの主な目的はテンプレートモデルです。私はコントローラが他のオプションがない限り、プレゼンテーション層の機能性のために使用されるべきではないと思います。コントローラにマークアップを保存する必要があるシナリオを考えてみましょうか? –

5

HtmlHelperへの参照を作成して生成します。私はUrlUtility静的クラスでこれを行います(静的クラスとユーティリティという単語は嫌いですが、フォーカスしようとします)。必要に応じて、過負荷:

public static string ActionLink(string linkText, string actionName, string controllerName) 
{ 
    var httpContext = new HttpContextWrapper(System.Web.HttpContext.Current); 
    var requestContext = new RequestContext(httpContext, new RouteData()); 
    var urlHelper = new UrlHelper(requestContext); 

    return urlHelper.ActionLink(linkText, actionName, controllerName, null); 
} 

次に、あなたはあなたの心が望むどこから以下のように書くことができます。

string a = "Email is locked, click " + UrlUtility.ActionLink("here to unlock.", "unlock", "controller"); 
+1

これは受け入れられた答えでなければなりません...他の答えはあなたのリンクがモデルで生成されるのを許可しないので... –

1

多分これ試してください:あなたの最善の策は、手動でリンクを構築することである

string a = "Email is locked, click " + System.Web.Mvc.Html.LinkExtensions.ActionLink("here to unlock.", "unlock"); 
+3

私がこのようなActionLinkを呼び出すと、3つのパラメータを渡す必要があります。タイプ(このHtmlHelper htmlHelper)、2番目のlinkText、3番目のコントローラです。私が試した最初のパラメータでは、nullを無効にして新しいHtmlHelperを作成します。 – roncansan

+0

この拡張メソッドはHtmlHelperインスタンスが必要です – RezaRahmati

4

をコントローラで使用可能なUrlHelperを使用します。それを言いましたが、共有やその他の方法でビューや部分的なビューでこれを処理する方が良いかもしれないというのは疑いがあります。

string a = "Email is locked, click <a href=\"" 
       + Url.Action("unlock") 
       + "\">here to unlock.</a>"; 
5
シャークス答えが間違っていないのC#、にLinkExtensions名前空間を持参する必要があります

これらの他の回答についての悪いカップルの事があります

...、しかし、私には望ましくありません。

ヘルパーを作成するというアイデアは優れていますが、1つのURLに対してヘルパー機能を作成するのは面倒です。私は複雑さのために理由を見ない

var link = "Email is... click, <a href=\"" + Url.Action("action") + "\"> to unlock.</a>"; 

@counsellorben、

;:あなたはパラメータを受け入れた文字列を構築するためにヘルパーを書くことができ、またはあなたは単に昔ながらの方法で行うことができますユーザはアクションのルーティングをアンカータグを含むハードストリングにレンダリングするだけでよい。さらに、ハードリンクされた連結された文字列のActionLink()は何も購入せず、開発者にViews用のLinkExtensionsを使用させます。

ユーザがActionLink()を使用しているとか、何らかの理由でコンストラクタでこの文字列を計算する必要がない場合は、ビューで行うほうがはるかに優れています。

私はまだ立ち、tvanfossonと私は答えをお勧めします。

関連する問題