简体   繁体   English

如何保护Edit操作路线中的Asp.Net MVC 5不会引发未处理的异常?

[英]How can protect the Asp.Net MVC 5 in the Edit action route from throwing unhandled exception?

I have a standard Edit action in Asp.Net MVC 5 and I want to avoid throwing the unhandled exception when a get request is made without the id like ~/food/edit , so I did this. 我在Asp.Net MVC 5中有一个标准的Edit操作,并且我想避免在没有诸如~/food/edit类的id的情况下发出get请求时抛出未处理的异常,所以我这样做了。

    public ActionResult Edit(int id = 0)
    {
        if (id == 0)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        string result = _foodAppService.GetById(id);
        FoodVm food = string.IsNullOrEmpty(result) 
            ? null 
            : JsonConvert.DeserializeObject<FoodVm>(result);

        if (food == null)
        {
            return RedirectToAction("Index");
        }

        return View(food);
    }

My question is: Is it a good practice to handled it in this way or there are more suitable strategies ? 我的问题是:以这种方式处理它是一种好的做法,还是有更合适的策略?

I'm new to this asking question thing, if a should I ask in another way, just let me know, thank you for your time. 我是这个问题的新手,如果我应该以其他方式询问,请告诉我,谢谢您的时间。

In case zero could be valid its better to do 如果零可能是有效的,那最好做

public ActionResult Edit(int? id)
{
    if (!id.HasValue)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
}

Or there can be more overall way to handle exceptions in MVC. 或者,可以有更多整体方法来处理MVC中的异常。 You can use override of method OnException this gives you abbility to debug all exception in controllers in one method and handle them. 您可以使用方法OnException覆盖,这使您能够在一个方法中调试控制器中的所有异常并进行处理。 Just add base class to all your controllers like this: 只需将基类添加到所有控制器中,如下所示:

 public class BaseController : Controller
 {
    protected override void OnException(ExceptionContext filterContext)
    {
        string redirectUrl;
        var exception = filterContext.Exception;

        if (exception is EntityException)
        {
            redirectUrl = "/Content/error.html";
        }
        else
        {
            redirectUrl = "/Info/Index";
        }

        //do whatever you wont

        Response.Redirect(redirectUrl);
    }

Also use input parameters verification as Paul Swetz saied. 还要像Paul Swetz所说的那样使用输入参数验证。 This method is more genera, allows to intercept all exceptions, and don`t show errors to users. 这种方法比较通用,可以拦截所有异常,并且不会向用户显示错误。

Following @Fran 's advice. 遵循@Fran的建议。 I built a action filter attribute called MissingParam 我建立了一个名为MissingParam的动作过滤器属性

public class MissingParamAttribute : ActionFilterAttribute
{
   public string ParamName { get; set; }

   public override void OnActionExecuting(ActionExecutingContext filterContext)
   {
      if (filterContext.ActionParameters.ContainsKey(ParamName))
      {
         if (filterContext.ActionParameters[ParamName] == null)
         {
            filterContext.ActionParameters[ParamName] = 0;
         }
      }

   base.OnActionExecuting(filterContext);
  }
}

in the action I did this: 在动作中,我这样做:

[MissingParam(ParamName="id")]
public ActionResult Edit(int id)

That way I don't need to mess with method parameter, any validating happens before. 这样,我就无需弄乱方法参数,之前可以进行任何验证。 This implementation follows the Open/Close principle. 此实现遵循打开/关闭原则。 I extended its functionality, but I didn't changed like the code in the question. 我扩展了它的功能,但是并没有像问题中的代码那样进行更改。

First and foremost its a good practice to use Try-Catch. 首先,最重要的是使用Try-Catch。

public ActionResult Edit(int id)
 {
     try
     {
            if (id != 0 || id!=null)
           {
            string result = _foodAppService.GetById(id);
            FoodVm food = string.IsNullOrEmpty(result) ? null:JsonConvert.DeserializeObject<FoodVm>(result);

            if (food == null)
            {
                return RedirectToAction("Index");
            }
            else
            {    
            return View(food);
            }
          }
         else
          {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
          }
    }
    catch (exception ex)
    {
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM