2009-11-07 7 views
5

Projektuję nową dynamiczną stronę ze statycznej witryny. Mam całą trasę sortowaną, ale mam pytanie dotyczące mojej metody działania.Popraw kod kontrolera dla przekierowania 301

Poniżej znajduje się kod, ale podczas testowania i przeglądania nagłówków raportów Firebug, jeśli wyjmuję Response.End to przekierowanie 302 Zakładam, ponieważ ustawiłem 301, ale potem wywołuję inną akcję, która sprawia, że ​​jest 302 , ale jeśli wstawię Response.End dostaję 301.

Domyślam się, że dodanie Response.RedirectLocation faktycznie wykonuje przekierowanie 301, więc zmienię moją wartość zwracaną na EmptyResult lub null, nawet jeśli ta linia kodu nigdy nie zostanie wykonany tylko po to, aby aplikacja się kompilowała?

public ActionResult MoveOld(string id) 
{ 
    string pagename = String.Empty; 

    if(id == "2") 
    { 
     pagename = WebPage.SingleOrDefault(x => x.ID == 5).URL; 
    } 

    Response.StatusCode = 301; 
    Response.StatusDescription = "301 Moved Permanently"; 
    Response.RedirectLocation = pagename; 
    Response.End(); 

    return RedirectToAction("Details", new { pageName = pagename }); 
} 
+0

Jak wspomniano w komentarzach do mojej odpowiedzi, w efekcie robisz dwa ActionResults tutaj. Przekierowanie 301 samo w sobie jest ActionResult, a następnie podążacie za nim z innym ** PO ** odpowiedzi zostały wysłane. –

Odpowiedz

14

I echo komentarze Levi's. To nie jest zadanie kontrolera. Mam tendencję do używania this niestandardowych ActionResult dla 301-tych. Poniżej znajduje się zmodyfikowana wersja z większą liczbą opcji.

Dla ASP.NET MVC v2 +, użyj RedirectResult.

public class PermanentRedirectResult : ActionResult 
{ 
    public string Url { get; set; } 

    public PermanentRedirectResult(string url) 
    { 
    Url = url; 
    } 

    public PermanentRedirectResult(RequestContext context, string actionName, string controllerName) 
    { 
    UrlHelper urlHelper = new UrlHelper(context); 
    string url = urlHelper.Action(actionName, controllerName); 

    Url = url; 
    } 

    public PermanentRedirectResult(RequestContext context, string actionName, string controllerName, object values) 
    { 
    UrlHelper urlHelper = new UrlHelper(context); 
    string url = urlHelper.Action(actionName, controllerName, values); 

    Url = url; 
    } 

    public PermanentRedirectResult(RequestContext context, string actionName, string controllerName, RouteValueDictionary values) 
    { 
    UrlHelper urlHelper = new UrlHelper(context); 
    string url = urlHelper.Action(actionName, controllerName, values); 

    Url = url; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
    if (context == null) 
    { 
     throw new ArgumentNullException("context"); 
    } 
    context.HttpContext.Response.StatusCode = 301; 
    context.HttpContext.Response.RedirectLocation = Url; 
    context.HttpContext.Response.End(); 
    } 
} 

Wykorzystanie w akcji

//Just passing a url that is already known 
return new PermanentRedirectResult(url); 

//*or* 

//Redirect to a different controller/action 
return new PermanentRedirectResult(ControllerContext.RequestContext, "ActionName", "ControllerName"); 
+0

Dzięki, ale jak Levi mówi wywołanie Response.End zgłasza wyjątek, czy to jest ważne? – Jon

+0

Bez wykonywania kodu, domyślam się, że błąd jest podobny do "Nie można przekierować po wysłaniu nagłówków HTTP". Dzieje się tak, ponieważ wysyłasz odpowiedź, a następnie przekierowujesz użytkownika po wysłaniu odpowiedzi. 'Response.End();' powinno być ostatnią rzeczą, którą robisz. –

+0

Dzieje się tak dlatego, że w próbce kodu podałem ci PermanentRedirectResult ** IS ** ActionResult. W efekcie w twoim kodzie masz dwa ActionResults. –

1

Regulator nie powinien być odpowiedzialny za ustalanie położenia 301 i przekierowanie. Ta logika powinna zostać zamknięta wewnątrz ActionResult, a kontroler powinien zwrócić wystąpienie tego ActionResult. Należy pamiętać, że metoda Response.End() nie zwraca (zgłasza wyjątek); następujące po nim linie nie zostaną wykonane.

0

Od MVC 2.0 znajduje się w wybudowanym klasy wyniku działania tej "RedirectResult". Więcej informacji na ten temat można uzyskać pod następującym adresem: MVC RedirectResult

Powiązane problemy