2009-11-07 13 views
5

Sto progettando un nuovo sito dinamico da un sito statico. Ho ordinato il percorso, ma ho una domanda sul mio metodo di azione.Codice controller corretto per 301 Redirect

Di seguito è riportato il codice, ma quando si esegue il test e si guardano le intestazioni che Firebug segnala, se prendo la Response.End è un reindirizzamento 302 presumo perché imposto il 301 ma poi chiamo un'altra azione che lo rende un 302 , ma se inserisco la Response.End ottengo un 301.

Sto supponendo che aggiungendo Response.RedirectLocation stia facendo effettivamente il reindirizzamento 301 così faccio quindi a cambiare il mio valore di ritorno su EmptyResult o null anche se quella riga di codice non verrà mai eseguito solo così l'applicazione compila?

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

Come menzionato nei commenti alla mia risposta, in questo caso stai facendo due ActionResults. Il reindirizzamento 301 è di per sé un ActionResult, quindi lo segui con un altro ** DOPO ** la risposta è stata inviata. –

risposta

14

I eco I commenti di Levi. Questo non è il lavoro del controller. Ho avuto la tendenza a utilizzare this ActionResult personalizzato per 301. Di seguito è una versione modificata con più opzioni.

Per ASP.NET MVC v2 +, utilizzare 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(); 
    } 
} 

Uso nell'azione

//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

Grazie, ma come Levi dice chiamando Response.End lancia un'eccezione, è valido? – Jon

+0

Senza eseguire il codice, suppongo che l'errore sia qualcosa di simile a "Impossibile reindirizzare dopo l'invio di intestazioni HTTP". Questo perché stai inviando una risposta e poi reindirizzare l'utente dopo aver inviato la risposta. 'Response.End();' dovrebbe essere l'ultima cosa che fai. –

+0

Questo perché nell'esempio di codice che ti ho dato, PermanentRedirectResult ** IS ** the ActionResult. In effetti, nel tuo codice, hai due ActionResults. –

1

Il controller non dovrebbe essere responsabile per l'impostazione della posizione 301 e reindirizzare. Questa logica deve essere incapsulata all'interno di ActionResult e il controller deve restituire un'istanza di ActionResult. Tenere presente che il metodo Response.End() non restituisce (genera un'eccezione); le linee che seguono non verranno eseguite.

0

Da MVC 2.0 v'è una costruito in classe di risultato azione per questa "RedirectResult". Leggi questo post per maggiori informazioni - MVC RedirectResult