从Web API返回camelCased JSON

时间:2014-10-20 20:33:11

标签: json serialization asp.net-web-api

我正在尝试从ASP.Net Web API 2控制器返回camel cased JSON。我创建了一个新的Web应用程序,其中只包含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. Scott Allen's post之后,我将以下内容添加到WebApiConfig.cs文件中的Register方法中:

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 }
        );
    }

然而,我仍然得到同样的结果,在我的结果中。有什么我想念的吗?我尝试了其他一些方法,但还没有任何工作。

6 个答案:

答案 0 :(得分:15)

在你的WebApiConfig.cs中,确保添加这两行

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

确保您安装了Newtonsoft库。

希望有所帮助。

答案 1 :(得分:9)

看起来主要问题是我使用的是JsonResult快捷方式Json()动作结果方法:

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文件中的代码块,正如Omar.Alani所建议的那样(与我在OP中使用的代码相比更长)。但真正的罪魁祸首是JsonResult行动方法。我希望这可以帮助别人。

答案 2 :(得分:4)

您需要在操作方法中使用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);
}

答案 3 :(得分:1)

我正在使用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");
        }
    }

答案 4 :(得分:1)

在WebApiConfig的Register方法中,添加此

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new 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已安装,并且您的API Action Method按以下方式返回数据:

    [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);
        }
    }

答案 5 :(得分:0)

也试一试。

[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);
            }
}