2014-03-26 5 views
6

Wenn ich eine Controller-Aktion wie diese habe.MVC Aktion ungültige Argumente gibt ArgumentException 500 statt 404

public ActionResult _Files(long parentid) 
     { 

Wenn Sie die Aktion von einem Browser ohne eine Parentid aufrufen. Es wirft ein System.ArgumentException und eine 500-Antwort

Der Parameter Wörterbuch Parameter ‚parentid‘ von nicht-NULL festlegbaren Typ ‚System.Int64‘ für Verfahren ‚einen Nulleintrag enthält System.Web.Mvc.ActionResult _Files

Die Aktion soll NICHT ohne Design von PARENTID aufgerufen werden. Gibt es eine Möglichkeit, eine Ausnahme nicht zu werfen (und 500 Antwort zurückgeben) und stattdessen eine 400 schlechte Anfrage oder eine 404 nicht gefunden (von denen beide mehr Sinn IMO Sinn machen würde). Auf der Suche nach einer Lösung, die dies in der gesamten Webanwendung auf generische Weise tun würde?

Antwort

2

, was Sie tun können, ist folgende:

public ActionResult _Files(long ? parentid) 
    { 

parentId NULL-Werte zulässt.

Dann in Ihrer Aktion, müssen Sie es handhaben wie folgt:

public ActionResult _Files(long ? parentid) 
    { 
     if(parentId.HasValue == false) {return some http status code;} 
     // Then you can use parentId with its Value property. 
+1

Werfen Sie es nicht, geben Sie ein 'neues HttpStatusCodeResult' zurück ... – Haney

+0

@DavidHaney Ja das ist, was ich meinte. – DarthVader

+0

wie gesagt, ich suche nach einer Lösung, die die Anwendung überspannt. Designell sollte Parentid nicht null sein. Und ich werde das in den 100's der Aktionen, die ich habe, tun müssen, die Longs oder Ints von Design akzeptiert! – MoXplod

3

Referenz: http://prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc

Einen Fehler Controller-Klasse und entsprechende Ansichten:

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

in Global.asax.cs:

protected void Application_Error(object sender, EventArgs e) 
{ 
    var httpContext = ((MvcApplication)sender).Context; 
    var currentController = " "; 
    var currentAction = " "; 
    var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext)); 
    if (currentRouteData != null) 
    { 
     if (currentRouteData.Values["controller"] != null && 
      !String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString())) 
     { 
      currentController = currentRouteData.Values["controller"].ToString(); 
     } 
     if (currentRouteData.Values["action"] != null && 
      !String.IsNullOrEmpty(currentRouteData.Values["action"].ToString())) 
     { 
      currentAction = currentRouteData.Values["action"].ToString(); 
     } 
    } 
    var ex = Server.GetLastError(); 
    var controller = new ErrorController(); 
    var routeData = new RouteData(); 
    var action = "Index"; 
    var statusCode = 500; 
    if (ex is ArgumentException) 
    { 
     action = "NotFound"; 
     statusCode = 404; 
    } 
    httpContext.ClearError(); 
    httpContext.Response.Clear(); 
    httpContext.Response.StatusCode = statusCode;    
    httpContext.Response.TrySkipIisCustomErrors = true; 
    routeData.Values["controller"] = "Error"; 
    routeData.Values["action"] = action; 
    controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction); 
    ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData)); 
} 
4

Ich schlage vor, Sie betrachten die Einschränkungen der Route. Das Erstellen einer Routeneinschränkung würde erfordern, dass eine Ganzzahl als Parent-ID übergeben wird. Wenn sie nicht angegeben wird, stimmt die Route nicht überein, und 404 wird standardmäßig zurückgegeben.

Hier ist ein Beispiel:

routes.MapRoute(
    name: "MyController", 
    url: "MyController/{parentid}", 
    defaults: new { controller = "MyController", action = "Index" }, 
    constraints: new { parentid = @"\d+" } 
); 

diesen Artikel finden Sie weitere Informationen über route constraints.

Der einzige Nachteil dieses Ansatzes ist, dass die Regex nicht überprüft, ob der Eingabewert ein long oder etwas größer ist. Wenn dies jedoch ein Problem darstellt, können Sie problemlos eine benutzerdefinierte Routenbeschränkung erstellen, die überprüft, ob der Eingabewert als long analysiert werden kann.

+0

das müsste für jede aktion gemacht werden .. was ich nicht will. Da wir 100 Aktionen haben. – MoXplod

Verwandte Themen