Alex Gordon
Alex Gordon

Reputation: 60751

Controller refuses to return 404

How do I force my controller to return a 404?

        [HttpGet]
        [Route("account({accountid})/printgroup", Name = "Get")]
        public HttpResponseMessage Get(int accountid)
        {
            var query = Request.RequestUri.Query;
            var uri = new Uri(Client.Instance.BaseAddress.ToString().Replace("[accountid]", accountid.ToString()) + query);
            var request = new HttpRequestMessage {RequestUri = uri, Method = HttpMethod.Get};
            var clientResponse = Client.Instance.SendAsync(request).Result;
            return clientResponse;
        }

When the clientResponse is 404, the method does not return a response. It just times out.

What am I doing wrong? How do I force it to return a 404 if the client response is 404?

EDIT:

Per macceturra's helpful comments, I've created my own object:

enter image description here

Yet the behavior is the same! The method will go out of scope, yet the client does not see anything. It just times out.

My latest update is:

    [HttpGet]
    [Route("account({accountid})/bill({billingRunId})", Name = "GetInvoiceSummary")]
    public async Task<IHttpActionResult> GetInvoiceSummary(int accountid, int billingRunId)
    {
        var query = Request.RequestUri.Query;
        var uri = new Uri(Client.Instance.BaseAddress.ToString() + accountid + "/" + billingRunId + query);
        var request = new HttpRequestMessage { RequestUri = uri, Method = HttpMethod.Get };
        var response = await Client.Instance.SendAsync(request);
        if (response.StatusCode == HttpStatusCode.NotFound)
            return NotFound();

        return ResponseMessage(response);

    }

The behavior is once again the same.

Upvotes: 1

Views: 150

Answers (2)

Nkosi
Nkosi

Reputation: 247153

Update

Based on discussion in comments it was advised that you review the response pipeline as it was determined that the code in the action was handling/executing the request as intended. The issue was being encountered by the response on its way out the pipeline which cause the client to time out. Check your message handlers and middle-ware in the pipeline that may be causing the response to block on its way out the pipeline based on how it was handled by your controllers.


Original answer

Consider the following, using the preferred Web API 2.* syntax along with proper use of async/await.

[HttpGet]
[Route("account({accountid})/printgroup", Name = "Get")]
public async Task<IHttpActionResult> Get(int accountid) {
    var query = Request.RequestUri.Query;
    var uri = new Uri(Client.Instance.BaseAddress.ToString().Replace("[accountid]", accountid.ToString()) + query);
    var request = new HttpRequestMessage { RequestUri = uri, Method = HttpMethod.Get };
    var clientResponse = await Client.Instance.SendAsync(request);
    if (clientResponse.StatusCode == System.Net.HttpStatusCode.NotFound)
        return NotFound();

    return ResponseMessage(clientResponse);
}

Upvotes: 1

Alex Gordon
Alex Gordon

Reputation: 60751

After adding this piece of middleware, the problem has been resolved:

public class NotFoundMiddleware : OwinMiddleware
{
    public NotFoundMiddleware(OwinMiddleware next) : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        await Next.Invoke(context);
        if (context.Response.StatusCode == (int)HttpStatusCode.NotFound
            && !context.Response.Headers.ContainsKey("X-ServiceFabric")
        )
            context.Response.Headers.Add("X-ServiceFabric", new[] { "ResourceNotFound" });
    }
}

Upvotes: 1

Related Questions