MyFunction(MyFunctionInput input) { if (inp" /> MyFunction(MyFunctionInput input) { if (inp" /> MyFunction(MyFunctionInput input) { if (inp"/>

How to get ActionResult StatusCode in ASP.NET Core

6.2k Views Asked by At

I have an API whose return type is ActionResult:

[HttpPost("UploadFiles")]
public async Task<ActionResult> MyFunction(MyFunctionInput input) 
{
    if (input.Id == null) 
    {
        retrun BadRequest("Id must exist");
    }

    // Do some stuff

    return Ok();
}

I am calling this function from another API in same class and storing the result in a variable. But when ever I am trying to get the StatusCode from the result, it says ActionResult does not contain a definition for StatusCode like this

var response = await MyFunction(attInput);

if (response.StatusCode == System.Net.HttpStatusCode.NotFound || 
    response.StatusCode == System.Net.HttpStatusCode.BadRequest)
{
    //To Do
}

I googled it but almost everyone said to convert the result to OkObjectResult.

What should I do now?

4

There are 4 best solutions below

1
Zanyar Jalal On

Your question need more explain !!! How to call ? you use HttpClient ? or call by Ajax ? Please edit your question by answer me questions.

Generally explain how to get states code in below

If you want request anther api in backend use HttpClient

// TODO: make request
var response = await client.GetAsync(url);

// get status code 
if(response.StatusCode == StatusCode.Ok) // when your endpoint success state
{
    //TODO: write code here 
}

Make HTTP requests using IHttpClientFactory in ASP.NET Core

0
Yiyi You On

Firstly,as you said,ActionResult does not contain a definition for StatusCode.If you want to get StatusCode with response.StatusCode,you can try to use HttpClient as Zanyar J.Ahmed shown.If you want to get StatusCode with await MyFunction(attInput);,you can try to set statuscode with Session in MyFunction.

Startup.cs:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromSeconds(10);
            options.Cookie.HttpOnly = true;
            options.Cookie.IsEssential = true;
        });

       ...
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...
        app.UseAuthentication();
        app.UseAuthorization();

        app.UseSession();

        ...
    }

api:

[HttpPost("UploadFiles")]
public async Task<ActionResult> MyFunction(MyFunctionInput input) 
{
    if (input.Id == null) 
    {
        HttpContext.Session.SetInt32("StatusCode", 400);
        retrun BadRequest("Id must exist");
    }

    // Do some stuff
    if (HttpContext.Session.GetInt32("StatusCode") == null)
            {
                HttpContext.Session.SetInt32("StatusCode", 200);
            }
    return Ok();
}

get status code:

var response = await MyFunction(attInput);

if (HttpContext.Session.GetInt32("StatusCode")=400)
{
    //To Do
}
0
Julian On

When looking at the source code of ActionResult<T>, we could see this:

public sealed class ActionResult<TValue> : IConvertToActionResult

and

IActionResult IConvertToActionResult.Convert()
{
    if (Result != null)
    {
        return Result;
    }

    int statusCode;
    if (Value is ProblemDetails problemDetails && problemDetails.Status != null)
    {
        statusCode = problemDetails.Status.Value;
    }
    else
    {
        statusCode = DefaultStatusCode;
    }

    return new ObjectResult(Value)
    {
        DeclaredType = typeof(TValue),
        StatusCode = statusCode
    };
}

So it's there, but you need some code to get it:

private static int? GetStatusCode<T>(ActionResult<T?> actionResult)
{
    IConvertToActionResult convertToActionResult = actionResult; // ActionResult implicit implements IConvertToActionResult
    var actionResultWithStatusCode = convertToActionResult.Convert() as IStatusCodeActionResult;
    return actionResultWithStatusCode?.StatusCode;
}

Example usage:

ActionResult<MyResponse> actionResult = await controller.Get(request);
var statuscode = GetStatusCode(actionResult);

Please note, this seem to be implemented in .NET 6

0
Stephen Melben Corral On

Julian's answer is quite helpful in my case. Based from the sample code provided by Julian, what I did is I explicitly casted the response to IStatusCodeActionResult for me to gain access to the StatusCode property. I was able to cast the response because the method signature of my controller method is of type Task and IStatusCodeActionResult interface depends on IActionResult.

ie:

var response = await controller.GetJob(_id);
// Should be 200 or 404
int? statusCode = ((IStatusCodeActionResult)response).StatusCode; 

Method Signature:

public async Task<IActionResult> GetJob(Guid id) { ... }