Search code examples
c#asp.net-web-api2odata

Web Api 2 string response returns as an array of characters


I have this Controller method:

[HttpGet]
[Route("SystemCheck/PulseCheck")]
public HttpResponseMessage PulseCheck()
{
    //this is a string
    var pulseCheck = PulseCheckHelper.PulseCheck();
    var response = Request.CreateResponse((HttpStatusCode.OK), pulseCheck);
    return response;
}

The response comes back as: [ "2", "2", "9", "9" ] instead of "2299"

Any ideas?

I have also tried different variations like:

[HttpGet]
[Route("SystemCheck/PulseCheck")]
[ResponseType(typeof(string))]
public string PulseCheck()
{
    //this is a string
    var pulseCheck = PulseCheckHelper.PulseCheck();
    return pulseCheck;
}

But same results. Is there any WebApiConfig I'm missing. I have other applications that work fine with the same controller method code but haven't been able to identify the configuration differences.

This is in my WebApiConfig:

    public static void Register(HttpConfiguration config)
    {
        config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
        config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.MessageHandlers.Add(new Security.WebApi.AuthenticationHandler());
        config.Services.GetFilterProviders().ToList().ForEach(provider => config.Services.Remove(typeof(System.Web.Http.Filters.IFilterProvider), provider));
        config.Services.Add(typeof(System.Web.Http.Filters.IFilterProvider), new OrderedFilterProvider());
        config.Filters.Add(new ExceptionHandlingAttribute());
        config.Filters.Add(new InspectActionContextFilter());
        config.Filters.Add(new NewRelicFilter());
        config.Filters.Add(new EnableQueryAttribute
        {
            PageSize = DefaultPageSize,
            EnsureStableOrdering = false
        });
    }

Update: Seems like the culprit is the following code in WebApiConfig Register:

    config.Filters.Add(new EnableQueryAttribute
    {
        PageSize = DefaultPageSize,
        EnsureStableOrdering = false
    });

This is enabling OData queries for all Controller methods. If I remove those lines then I get the right response back "2299". Now my question is, how can I disable OData for my specific controller method?


Solution

  • Looks like it is treating the string as a list of characters so you could possibly query it. You can however force it to think its a single result by changing your action to the following:

    [HttpGet]
    [Route("SystemCheck/PulseCheck")]
    public SingleResult<string> PulseCheck()
    {
        var pulseCheck = PulseCheckHelper.PulseCheck();
    
        return SingleResult.Create(new[]{ pulseCheck }.AsQueryable());
    }