2010-07-01 3 views
6

J'ai un ActionResult personnalisé pour renvoyer certaines erreurs HTTP, comme NotFoundResult et ForbiddenResult, ils dérivent tous de ViewResult.La définition du statut HTTP dans les résultats du contrôleur ASP.NET MVC ne rend pas la vue

Je les utilise pour des instances comme des actions de court-circuit avec un 404 si une entité n'a pas été trouvée dans la base de données au cours d'une action.

Dans ces objets de résultat, j'ai défini le statut HTTP sur le nombre approprié. Lorsque je fais cela, la vue que cette référence ViewResults ne rend pas. Je dois laisser le statut 200 OK pour que ma vue soit rendue.

Comment définir un état approprié ET afficher une vue dans ASP.NET MVC 2.0?

+0

Voulez-vous dire "la vue ne rend pas" ou "mon navigateur ne l'affiche pas?" Parce que ce ne sont pas les mêmes choses. –

+0

La réponse de l'application est 0 octets. Aucune vue n'est écrite dans la réponse. –

Répondre

8

J'ai un ActionResult personnalisé pour retourner certaines erreurs HTTP, comme NotFoundResult et ForbiddenResult, ils dérivent tous ViewResult.

Permettez-moi de vous proposer une gestion des erreurs alternatives:

Commencez par créer un contrôleur d'erreur et les vues correspondantes:

public class ErrorController : Controller 
{ 
    public ActionResult General() 
    { 
     return View(); 
    } 

    public ActionResult HttpError404() 
    { 
     return View(); 
    } 

    public ActionResult HttpError500() 
    { 
     return View(); 
    } 
} 

Dans Global.asax définissent la méthode Application_Error:

protected void Application_Error(object sender, EventArgs e) 
{ 
    var exception = Server.GetLastError(); 
    // TODO: Log the exception with your favorite logging framework 

    Response.Clear(); 
    var httpException = exception as HttpException; 

    var routeData = new RouteData(); 
    // Take the ErrorController 
    routeData.Values.Add("controller", "error"); 

    if (httpException == null) 
    { 
     // Use the General action for any unhandled error 
     routeData.Values.Add("action", "general"); 
    } 
    else 
    { 
     switch (httpException.GetHttpCode()) 
     { 
      case 404: 
       routeData.Values.Add("action", "httpError404"); 
       break; 
      case 500: 
       routeData.Values.Add("action", "httpError500"); 
       break; 
      default: 
       routeData.Values.Add("action", "general"); 
       break; 
     } 
    } 

    // Add the exception to route data so that the error controller 
    // could use it with RouteData.Values["error"] 
    routeData.Values.Add("error", exception); 

    Server.ClearError(); 
    IController errorController = new ErrorController(); 
    errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); 
} 

Enfin jeter des exceptions appropriées:

public class HomeController: Controller 
{ 
    public ActionResult Index(int id) 
    { 
     var model = _repository.GetModel(id); 
     if (model == null) 
     { 
      throw new HttpException(404, "Model not found with id = " + id); 
     } 
     return View(model); 
    } 
} 
+0

Seemes comme un moyen cool de consolider le code de gestion des erreurs. Je reviens à vous merci! –

+0

Toujours pas sûr de savoir pourquoi les réponses étaient vides, mais cela a résolu mon problème tout en consolidant un code d'erreur ensemble. Merci d'avoir fourni une implémentation! Une chose que j'ajouterais, c'est que les erreurs personnalisées devraient être désactivées en faisant cela. –

+0

@BC, difficile à dire car vous n'avez fourni aucun code source. –

Questions connexes