How to return HTTP Status Codes for errors from Asp.Net Core View Component

梦想与她 提交于 2020-01-03 16:55:53

问题


I am trying to return a HTTP 500 or BadRequest() result from my View Component in Asp.Net Core however this return type does not appear to be available for View Components. Should status code return types be available for View Components or have i got my design wrong?

I am calling my controller action via ajax as per below...

<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>

My controller action is calling/returning my View Component as per below...

public IActionResult LoadVisit(int? id)
{

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

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

}

My ClientVisit View Component has the following...

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);
    }

}

When my database call model = await visitAPI.GetVisit(clientID, visitID) fails I want to return return StatusCode(500, ex.ToString()) but it's not available so my ajax call thinks my request was successful which is wrong.


回答1:


As long as you have the HttpResponse in the access it should work. Alternatively, due to the return of the ViewComponent prerequisite check then set the status.

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



回答2:


From View Components documentation:

A view component never handles a request,

view component methods are overloaded on the signature rather than any details from the current HTTP request,

So as far I understand you will not be able to create HTTP response (like as StatusCode() or BasRequest()) inside your View Component.


Also, you could access HttpContext.Response.StatusCode, but this also will not work as you want.


Also, you cannot return null from View Components - you will see the exception:

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


Due to above, I have no idea how to return status code from View Component.

Perhaps, you can convert View Component into simple 'helper' method, so you could catch an exception in action and then return StatusCode(500) as you want?




回答3:


The containing controller should own the logic deciding whether to return status codes and then only if there isn't a problem should it pass the required data to the view component. This should eliminate any need for the view component to interact with the pipeline.

View components don't use model binding, and only depend on the data provided when calling into it.

So move the call to the api out of the view component and into the controller and then pass the resultant data into the view component if the call to the api was okay.

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

So something like this for your example:

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 });

}

and

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


来源:https://stackoverflow.com/questions/40858676/how-to-return-http-status-codes-for-errors-from-asp-net-core-view-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!