控制器返回错误消息而不是视图?

时间:2011-12-07 06:54:28

标签: asp.net-mvc

我是ASP.NET MVC的新手,并不确定如何最好地处理以下情况。

我的控制器中的方法需要根据ID参数加载一些数据。在正常情况下,此ID参数将设置为数据库中实体的有效ID。我构造了一些数据并将其放在ViewBag中,视图用它来渲染页面。

但是,我想要一些基本的错误处理,以防ID参数有效。虽然我可以在视图中编写一堆错误处理代码,但如果网站出现严重误用或故障,则不显示视图会更加简单。

控制器是否可以简单地返回“找不到项目”字符串或类似字符串,并显示该字符串而不是普通视图?或者也许有人可以建议一个更好的主意?

4 个答案:

答案 0 :(得分:28)

if (itemId == null)
{
    return Content("Item not found");
}

或者如果您想要返回HTTP 404:

throw new HttpException(404, "Item Not Found");

答案 1 :(得分:7)

如果从数据库中获取模型(如Darin的答案所述)有些复杂且无法通用,这就是我处理未找到的资源的方法。

实施基础控制器

    public abstract class MyBaseController : Controller
    {
        [NonAction]
        protected virtual void EnsureResourceFound(object resource)
        {
            if (resource == null)
            {
                HttpStatusCode statusCode = HttpStatusCode.NotFound;
                throw new HttpException((int)statusCode, statusCode.ToString());
            }
        }
    }

在派生控制器中 - 使用该方法

    [HttpGet]
    public virtual ActionResult Edit(int id)
    {
        SomeModel model = null;
        EnsureResourceFound(model = _someModelService.Get(id));
        return View(question);
    }

您将对结果http异常做什么,返回自定义视图,记录错误,取决于配置的HandleErrorAttribute

答案 2 :(得分:4)

public ActionResult Foo(int id)
{
    MyModel model = ...
    if (model == null)
    {
        return HttpNotFound();
    }
    return View(model);
}

由于在您的操作中一遍又一遍地编写相同的代码可能会很快变得无聊更好的解决方案是编写一个自定义模型绑定器,它将从数据库中获取模型,如果找不到则只会抛出一个新的HttpException并设置状态代码为404.然后您的控制器操作将如下所示:

public ActionResult Foo(MyModel model)
{
    return View(model);
}

和模型活页夹本身:

public class MyModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var id = bindingContext.ValueProvider.GetValue("id");
        if (id == null)
        {
            throw new HttpException(404, "Not found");
        }

        MyModel model = FetchTheModel(id.AttemptedValue);
        if (model == null)
        {
            throw new HttpException(404, "Not found");
        }

        return model;
    }

    private MyModel FetchTheModel(string id)
    {
        throw new NotImplementedException();
    }
}

这种模型绑定器显然可以更通用。

答案 3 :(得分:4)

您可以通过从Controller中抛出异常来实现。

您需要编写以下代码,并需要添加ErrorController及其各自的视图。

Global.asax中

Exception exception = Server.GetLastError();

Response.Clear();

HttpException httpException = exception as HttpException;

//Add controller name
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");

//we will add controller's action name 
routeData.Values.Add("action", "Index");

// Pass exception details to the target error View.
routeData.Values.Add("error", exception.Message);

// Clear the error on server.
Server.ClearError();

// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));


//and throw the exception from the Controller ny simply writing
throw new Exception()

ErrorController:

public class ErrorController : BaseController
    {
        #region Function Declaration
        /// <summary>
        /// Shows application error
        /// </summary>
        /// <param name="error">error description</param>
        public ActionResult Index(string error)
        {
            ViewBag.Description = Resources.ErrorMessage.GeneralError;
            if (string.IsNullOrEmpty(error))
            {
                ViewBag.DetailError = error;
            }
            else
            {
                ViewBag.DetailError = string.Empty;
            }

            return View("ErrorIndex");
        }
        #endregion
    }

另一种方法:

如果要为特定错误编写视图,而不是编写followig代码。您只需添加DivByZero视图。

    [HandleError(View = "DivByZero", ExceptionType = typeof(System.DivideByZeroException))]
    public ActionResult About()
    {
        List<Alok> alokList = new List<Alok>();
        var al = from aa in alokList.Distinct()
                 select aa;

        ViewData["Errorname"] = "Divide By Zero Exception";
        ViewBag.ErrorName = "Divide By Zero Exception";
        //throw new DivideByZeroException();

        return View();
    }

DivByZero查看:

@model System.Web.Mvc.HandleErrorInfo
@{
    ViewBag.Title = "Error";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@*<h2>
    @ViewData["Errorname"].ToString()
    @ViewBag.ErrorName</h2>*@
<p>
    Controller : @Model.ControllerName
</p>
<p>
    Action : @Model.ActionName
</p>
<p>
    Error Message : @Model.Exception
</p>