2014-10-20 19 views
11

Próbuję zwrócić wielbłąda cased JSON z kontrolera ASP.Net Web API 2. Stworzyłem nową aplikację internetową z tylko bitami ASP.Net MVC i Web API. I porwali ValuesController tak:Powrót camelCased JSON z Web API

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

Running to w IE, otrzymuję następujące wyniki:

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

Obserwuje K. Scott Allen's post na temat, dodałem następujące metody rejestracji w WebApiConfig. cs file:

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

Jednak wciąż otrzymuję to samo, kapitalizuje moje wyniki. Czy jest coś, czego mi brakuje? Próbowałem już kilku innych podejść, ale nic nie działa.

+0

Czy jest to tak oczywista odpowiedź, że ludzie myślą, że powinienem sam to sobie wyobrazić? Nie mam jeszcze skubać. Zacząłem od nowego projektu i nadal nie byłem w stanie tego zrobić. – beaudetious

+0

Nadal uważam, że odpowiedź z innego postu jest najbardziej przyzwoita: http://stackoverflow.com/a/22130487/1915401 – Xinan

Odpowiedz

9

Wygląda na to, że głównym problemem było to, że za pomocą skrótu JsonResult Json() metoda wynik działania:

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

To najwyraźniej miał pełną kontrolę nad formatowaniem wyniki. Jeśli mogę przełączyć na powrocie HttpResponseMessage to działa zgodnie z oczekiwaniami:

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

I nie kończy się za pomocą fragmentu kodu w pliku WebApiConfig jak Omar.Alani zasugerował (w przeciwieństwie do znacznie dłuższego kodu miałem w moim OP) . Ale prawdziwym winowajcą była metoda działania JsonResult. Mam nadzieję, że to pomoże komuś innemu.

+5

Wiem, że jest to raczej spóźniony komentarz, ale stwierdziłem, że użycie 'Ok (authInfo)' stosuje formatowanie, natomiast użycie 'Json (authInfo)' nie działa. Metoda 'Ok' zastosowałaby odpowiedni formatujący w oparciu o nagłówek' Accept', a następnie mógłbyś powrócić do 'IHttpActionResult'. –

15

W swoim WebApiConfig.cs upewnij się, aby dodać te dwie linie

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

upewnić się, że zainstalowane biblioteki Newtonsoft.

Nadzieję, że pomaga.

+0

Nie, już wypróbowałem to i Newtonsoft jest już zainstalowany. :( – beaudetious

+0

Miałem podobny problem, musisz pobrać formater z httpconfig dla owin nie GlobalConfiguration –

+0

@LukeDeFeo czy możesz pokazać kod, w jaki sposób dostałeś formatyzator z ht httpconfig of owin? – Dmitry

1

Używałem Owin i DI (AutoFac w moim przypadku), więc rzuca kolejny klucz do prac. Moja Startup.cs zawiera:

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

Następnie w moich WebApiConfig.cs mam:

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

Trzeba użyć OK() zamiast Json() w swoich metodach działania.

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

w Rejestrze sposobu WebApiConfig, dodaj

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

Pełna Kodeks 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(); 

     } 
    } 


Upewnij się, że zainstalowano najnowszą wersję Json.Net/Newtonsoft.Json zainstalowana a API Metoda Action zwraca dane w następujący sposób:

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

Spróbuj również.

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