【问题标题】:How to return HTTP Status Codes for errors from Asp.Net Core View Component如何从 Asp.Net Core View 组件返回错误的 HTTP 状态代码
【发布时间】:2017-04-13 00:34:15
【问题描述】:

我正在尝试从我在 Asp.Net Core 中的视图组件返回 HTTP 500 或 BadRequest() 结果,但是此返回类型似乎不适用于视图组件。状态码返回类型应该可用于视图组件还是我的设计有误?

我正在通过 ajax 调用我的控制器操作,如下所示...

<a asp-controller="Client" asp-action="LoadVisit" asp-route-id="@item.VisitID" data-ajax="true" data-ajax-method="GET" data-ajax-update="#ClientVisit" data-ajax-mode="replace" data-ajax-failure="AjaxOnFailure(xhr, status, error)" role="button"><i class="fa fa-folder-open-o"></i></a>

我的控制器操作正在调用/返回我的视图组件,如下所示...

public IActionResult LoadVisit(int? id)
{

    if (id == null || id == 0)
    {
        return NotFound();
    }

    return ViewComponent("ClientVisit", new { visitID = id.GetValueOrDefault() });

}

我的 ClientVisit 视图组件有以下...

public async Task<IViewComponentResult> InvokeAsync(int? clientID, int? visitID)
{

    try
    {
        var model = new VisitViewModel();
        model = await visitAPI.GetVisit(clientID, visitID);
        return View(model);
    }
    catch (Exception ex)
    {
        return Content(ex.Message);
    }

}

当我的数据库调用 model = await visitAPI.GetVisit(clientID, visitID) 失败时,我想返回 return StatusCode(500, ex.ToString()) 但它不可用,所以我的 ajax 调用认为我的请求成功,这是错误的。

【问题讨论】:

    标签: c# asp.net-core asp.net-core-viewcomponent


    【解决方案1】:

    只要你有 HttpResponse 在访问它应该工作。或者,由于返回 ViewComponent 先决条件检查然后设置状态。

    try
    {
        var model = new VisitViewModel();
        model = await visitAPI.GetVisit(clientID, visitID);
        return View(model);
    }
    catch (Exception ex)
    {
         Response.StatusCode = (int)HttpStatusCode.BadRequest;
         return null;
    }
    

    【讨论】:

    • 很遗憾 HttpResponse 在视图组件中不可用。编译错误名称'Response'在当前上下文中不存在
    • 当您检查来自 ´ViewComponent("ClientVisit", new { visitID = id.GetValueOrDefault() });´ 的结果时怎么样:var view = ViewComponent("ClientVisit", new { visitID = id.GetValueOrDefault() }); if(view == null) { Response.StatusCode = (int)HttpStatusCode.BadRequest; return null; } return view;
    • 您可以在HttpContext 中找到Response 例如:HttpContext.Response.StatusCode = ???;,但它仍然不起作用,因为“视图组件从不直接处理请求”。
    【解决方案2】:

    来自View Components 文档:

    视图组件从不处理请求,

    查看组件方法在签名上重载,而不是来自当前 HTTP 请求的任何细节,

    据我了解,您将无法在视图组件中创建 HTTP 响应(如 StatusCode()BadRequest())。

    您可以访问HttpContext.Response.StatusCode,但这也无法如您所愿。

    您不能从视图组件返回 null - 您将看到异常:

    InvalidOperationException: A view component must return a non-null value.
    

    由于上述原因,我不知道如何从视图组件返回状态码。

    也许,您可以将视图组件转换为简单的“帮助器”方法,这样您就可以捕获异常,然后根据需要返回StatusCode(500)

    【讨论】:

      【解决方案3】:

      包含控制器应该拥有决定是否返回状态代码的逻辑,然后只有在没有问题的情况下才将所需的数据传递给视图组件。这应该消除视图组件与管道交互的任何需要。

      视图组件不使用模型绑定,只依赖于调用它时提供的数据

      因此,将调用移动到视图组件的 api out 并进入控制器,然后如果对 api 的调用正常,则将结果数据传递到视图组件。

      参考https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-2.1

      你的例子是这样的:

      public IActionResult LoadVisit(int? id)
      {
      
          if (id == null || id == 0)
          {
              return NotFound();
          }
          var model = new VisitViewModel();
          try
          {
              model = await visitAPI.GetVisit(clientID, visitID);
          }
          catch (Exception ex)
          {
              return Content(ex.Message);
          }
      
          return ViewComponent("ClientVisit", model });
      
      }
      

      public async Task<IViewComponentResult> InvokeAsync(VisitViewModel model)
      {
              return View(model);
      }
      

      【讨论】:

      • 在这种情况下使用视图组件有什么好处?如果所有的工作都在控制器中完成,那么为什么不只返回一个比视图组件更容易设置的局部视图呢?我认为视图组件的目的是它可以处理逻辑以避免通过控制器进行管道。
      • 视图组件可以共享为 dll / nuget 包。部分不能不诉诸预编译视图。可能还有其他原因,但这是我们目前感兴趣的原因。
      猜你喜欢
      • 2012-11-14
      • 2018-11-28
      • 2016-09-16
      • 2020-02-14
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      • 2014-10-26
      • 2017-02-25
      相关资源
      最近更新 更多