简体   繁体   中英

How to write custom actionResult in asp.net core

In webApi2 i could write a custom ActionResult by inheriting IHttpActionResult.

Sample :

public class MenivaActionResult : IHttpActionResult
    {
        private readonly HttpRequestMessage _request;
        private readonly ServiceResponseBase _response;

        public MenivaActionResult(HttpRequestMessage request, ServiceResponseBase response)
        {
            _request = request;
            _response = response;
        }


        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken token)
        {

            HttpResponseMessage httpresponseMessage = _response.Exception != null
                ? _request.CreateErrorResponse((HttpStatusCode)_response.HttpCode,
                    _response.Exception.Message+":"+_response.Exception.HelpCode)
                : _request.CreateResponse((HttpStatusCode)_response.HttpCode, _response.Data);
            return Task.FromResult(httpresponseMessage);
        }
    }

The ServiceResponseBase class object holds all the exception and data from service layer..

How i can port this code to asp.net core. I tried but i dont know how create a response message from HttpRequestMessage object in .net core. The IActionResult only have Task ExecuteResultAsync(ActionContext context) method. how i can modify the response from this method

Here is an example:

public class TestResult
{
    public Exception Exception { get; set; }
    public object Data { get; set; }
}

public class TestActionResult : IActionResult
{
    private readonly TestResult _result;

    public TestActionResult(TestResult result)
    {
        _result = result;
    }

    public async Task ExecuteResultAsync(ActionContext context)
    {
        var objectResult = new ObjectResult(_result.Exception ?? _result.Data)
        {
            StatusCode = _result.Exception != null
                ? StatusCodes.Status500InternalServerError
                : StatusCodes.Status200OK
        };

        await objectResult.ExecuteResultAsync(context);
    }
}

ObjectResult is the type your results are converted if you return a non- IActionResult from an action. It will do content negotiation for you.

You could also inherit from ObjectResult and setup the status code and data to be written in the constructor.

More on content negotiation in ASP.NET Core: https://docs.microsoft.com/en-us/aspnet/core/mvc/models/formatting#content-negotiation

Despite @juunas answer is technically correct, what you really try to achieve is a custom error handling. And the better way is to decouple this logic using Action Filter, Middleware filter or the separate Middleware (depends on what scope you what to cover).

The main idea is that controller should not be responsible for handling exceptions. It should return expected result with OK status or say that something wrong (throw exception) and delegate to other parts of pipeline what to do with problem.

Look into SO: Error handling in ASP.NET Core 1.0 Web API (Sending ex.Message to the client) for examples. Also Error Handling in ASP.NET Core doc may be useful.

Why not just use the StatusCode method? Something like this as an example:

public async Task<IActionResult> ExamleEndpoint()
{
    // ... some code here which concatenates result string and selects a status code
    var statusCode = HttpStatusCode.OK;
    var message = "Some string response here but StatusCode also accepts Object value";
    return StatusCode((int) statusCode, message);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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