Вернуть CamelCased JSON из Web API

Я пытаюсь вернуть JSON с верблюдом из контроллера ASP.Net Web API 2. Я создал новое веб-приложение только с битами ASP.Net MVC и Web API. Я захватил ValuesController следующим образом:

public class ValuesController : ApiController
{
    public class Thing
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string ISBN { get; set; }
        public DateTime ReleaseDate { get; set; }

        public string[] Tags { get; set; }
    }

    // GET api/values
    public IHttpActionResult Get()
    {
        var thing = new Thing
        {
            Id = 123,
            FirstName = "Brian",
            ISBN = "ABC213", 
            ReleaseDate = DateTime.Now,
            Tags = new string[] { "A", "B", "C", "D"}
        };

        return Json(thing);
    }
}

Запустив это в IE, я получаю следующие результаты:

{"Id":123,"FirstName":"Brian","ISBN":"ABC213","ReleaseDate":"2014-10-20T16:26:33.6810554-04:00","Tags":["A","B","C","D"]}

Следуя K. Скотт Аллен по этому вопросу, я добавил следующее в метод Register в файле WebApiConfig.cs:

public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        var formatters = GlobalConfiguration.Configuration.Formatters;
        var jsonFormatter = formatters.JsonFormatter;
        var settings = jsonFormatter.SerializerSettings;
        settings.Formatting = Formatting.Indented;
        settings.ContractResolver = new CamelCasePropertyNamesContractResolver();

        // Web API routes
        config.MapHttpAttributeRoutes();

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

Однако я все равно получаю то же самое, капиляция в моих результатах. Есть что-то, что мне не хватает? Я пробовал несколько других подходов, но пока ничего не работает.

Ответ 1

Похоже, основная проблема заключалась в том, что я использовал метод результата Json() для JsonResult:

public IHttpActionResult Get([FromUri] string domain, [FromUri] string username)
{
    var authInfo = BLL.GetAuthenticationInfo(domain, username);
    return Json(authInfo);
}

По-видимому, он полностью контролировал форматирование результатов. Если я переключусь на возвращаемый HttpResponseMessage, он будет работать как ожидалось:

public HttpResponseMessage Get([FromUri] string domain, [FromUri] string username)
{
    var authInfo = BLL.GetAuthenticationInfo(domain, username);
    return Request.CreateResponse(HttpStatusCode.OK, authInfo);
}

В конце концов я использовал блок кода в файле WebApiConfig, как предположил Омар Алани (против более длинного кода, который у меня был в моем OP). Но настоящим виновником был метод JsonResult. Надеюсь, это поможет кому-то другому.

Ответ 2

В вашем WebApiConfig.cs обязательно добавьте эти две строки

// Serialize with camelCase formatter for JSON.
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

убедитесь, что вы установили библиотеку Newtonsoft.

Надеюсь, что это поможет.

Ответ 3

Вам нужно использовать OK() вместо Json() в ваших методах действий.

// GET api/values
public IHttpActionResult Get()
{
    var thing = new Thing
    {
        Id = 123,
        FirstName = "Brian",
        ISBN = "ABC213", 
        ReleaseDate = DateTime.Now,
        Tags = new string[] { "A", "B", "C", "D"}
    };

    // Use 'Ok()' instead of 'Json()'
    return Ok(thing);
}

Ответ 4

Я использовал Owin и DI (AutoFac в моем случае), чтобы выталкивать еще один ключ в работу. Мой Startup.cs содержит:

var apiconfig = new HttpConfiguration
{
    DependencyResolver = new AutofacWebApiDependencyResolver(container)
};
WebApiConfig.Register(apiconfig);

Затем в моем WebApiConfig.cs у меня есть:

using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();

        //  Setup json.Net for pretty output, easy human reading AND this formatter
        //  does that ONLY for browsers - best of both worlds: useful AND efficient/performant!
        config.Formatters.Clear();
        config.Formatters.Add(new BrowserJsonFormatter());
    }

    public class BrowserJsonFormatter : JsonMediaTypeFormatter
    {
        //  Since most browser defaults do not include an "accept type" specifying json, this provides a work around
        //  Default to json over XML - any app that wants XML can ask specifically for it  ;)
        public BrowserJsonFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            SerializerSettings.Formatting = Formatting.Indented;
            SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            // Convert all dates to UTC
            SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
        }

        //  Change the return type to json, as most browsers will format correctly with type as text/html
        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
    }

Ответ 5

В методе регистрации WebApiConfig добавьте это

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = новый CamelCasePropertyNamesContractResolver();

Полный код WebApiConfig:

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

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

            config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

        }
    }


Убедитесь, что установлена ​​последняя версия Json.Net/Newtonsoft.Json Installed, и ваш метод действий API возвращает данные следующим образом:

    [HttpGet]
    public HttpResponseMessage List()
    {
        try
        {
            var result = /*write code to fetch your result*/;
            return Request.CreateResponse(HttpStatusCode.OK, result);
        }
        catch (Exception ex)
        {
            return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
        }
    }

Ответ 6

Попробуйте также.

[AllowAnonymous]
[HttpGet()]
public HttpResponseMessage GetAllItems(int moduleId)
{
            HttpConfiguration config = new HttpConfiguration();
            config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;

            try
            {
                List<ItemInfo> itemList = GetItemsFromDatabase(moduleId);
                return Request.CreateResponse(HttpStatusCode.OK, itemList, config);
            }
            catch (System.Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
}