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