Odpowiedz

7

Zakładając, że chcesz to zrobić w kontrolerze, możesz przeskoczyć kilka obręczy. Należy utworzyć instancję ViewDataDictionary i TempDataDictionary. Następnie musisz wziąć ControllerContext i utworzyć IView. Na koniec możesz przygotować swoje HtmlHelper używając wszystkich tych elementów (plus twój RouteCollection).

Po wykonaniu wszystkich czynności można użyć numeru LinkExtensions.ActionLink, aby utworzyć własny odsyłacz. W twoim widoku będziesz musiał użyć @Html.Raw(), aby wyświetlić linki, aby zapobiec ich zakodowaniu w HTML.Oto niezbędne kod:

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(); 

Wykazawszy to wszystko, będę cię ostrzec, że jest to o wiele lepszy pomysł, aby zrobić to w widoku. Dodaj błąd i inne informacje do swojego ViewModel, a następnie zakoduj swój widok, aby utworzyć łącze. Jeśli jest to potrzebne w wielu widokach, utwórz program HtmlHelper, aby utworzyć łącze.

UPDATE

Aby rozwiązać one.beat.consumer, moja wstępna odpowiedź była przykładem tego, co jest możliwe. Jeśli deweloper musi ponownie wykorzystać tę technikę, złożoność może być ukryte w statycznym pomocnika, tak:

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; 
    } 
} 

Następnie w kontroler, jest on stosowany tak:

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

lub podobny tak:

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

Choć jest łatwiejszy w użyciu Url.Action, to teraz rozciąga się w potężne narzędzie do generowania jakichkolwiek narzut zasięgu kontrolera przy użyciu wszystkich HtmlHelpers (z pełnym IntelliSense).

Możliwości zastosowania obejmują generowanie mark-up przy użyciu modeli i szablonów edytor e-maile, generowania pdf, dostarczania dokumentów on-line, itp

+0

counsellorben, @roncansan ... Wydawaj się edytować. Myślę, że to zupełnie niepotrzebne. –

+0

@ one.beat.consumer, zobacz moją aktualizację. – counsellorben

+1

Rozbudowane rozwiązanie i dobrze napisany kod. W ogóle tego nie krytykuję; Po prostu nie uważam, że kontroler jest właściwym miejscem do "generowania znaczników". Być może zbyt purystycznie, ale rolą kontrolerów jest obsługiwanie wywołań trasy, gromadzenie niezbędnych zasobów (modeli, usług) i wprowadzanie ich do widoku. Podstawowym celem View jest modelowanie szablonów. Nie sądzę, że kontrolery powinny być używane do funkcji warstwy prezentacji, chyba że nie ma innych opcji. Czy możesz wymyślić scenariusz, w którym POTRZEBUJESZ zachować znaczniki w kontrolerze? –

5

Można by utworzyć metodę rozszerzenia HtmlHelper:

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

lub jeśli masz na myśli, aby wygenerować link poza zakresem strony aspx będziesz potrzebować utworzyć odniesienie do HtmlHelper, a następnie wygenerować. Robię to w klasie statycznej UrlUtility (Wiem, ludzie nienawidzą klas statycznych i narzędzia Word, ale starają się skupić). Przeciążenie w miarę potrzeby:

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); 
} 

Następnie można napisać następujące od gdziekolwiek dusza zapragnie:

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

ta powinna być przyjęta odpowiedź ... bo inne odpowiedzi nie pozwalają na Twój link, aby być generowane w modelu ... –

1

Może spróbuj tego:

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

Gdybym wywołać actionlink funkcji takiego, muszę zdać 3 parametry, pierwszy powinien być typu (ten htmlHelper htmlHelper), drugi linkText, trzeci kontroler. Na pierwszym parametrze próbowałem, null i utworzyć nowy HtmlHelper bez powodzenia. – roncansan

+0

Ta metoda rozszerzenia wymaga instancji HtmlHelper – RezaRahmati

4

Najprościej jest ręcznie skonstruować link za pomocą UrlHelper dostępnego w kontrolerze. Powiedziawszy to, jestem podejrzliwy, że prawdopodobnie istnieje lepszy sposób na poradzenie sobie z tym w widoku lub częściowym widoku, udostępnionym lub innym.

string a = "Email is locked, click <a href=\"" 
       + Url.Action("unlock") 
       + "\">here to unlock.</a>"; 
5

Jest kilka rzeczy źle o tych innych odpowiedzi ...

odpowiedź rekina wymaga doprowadzenia nazw LinkExtensions do C#, który nie jest źle, ale niepożądany ze mną.

Pomysł Huntera na zrobienie pomocnika jest lepszy, ale wciąż pisanie funkcji pomocnika dla pojedynczego adresu URL jest uciążliwe. Można napisać pomocnika, aby pomóc budować ciągi przyjętych parametrów, lub może po prostu zrobić w staromodny sposób:

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

@counsellorben,

widzę żadnego powodu złożoności; użytkownik chce tylko renderować routing Akcji do twardego łańcucha zawierającego znacznik zakotwiczenia. Co więcej, ActionLink() w ciężko napisanym łańcuchu nie kupuje niczego i zmusza programistę do korzystania z LinkExtensions, które są przeznaczone dla widoków.

Jeśli użytkownik nie chce używać ActionLink() lub nie potrzebuje (z jakiegoś powodu) do obliczenia tego ciągu w konstruktorze, robi to znacznie lepiej.

Nadal czekam i polecam odpowiedzi udzielone przez tvanfosson i mnie.

Powiązane problemy