2012-12-12 7 views
12

Dodałem właściwość niestandardową, aby niektóre z moich przedmiotów tak:Jak dodać niestandardowy węzeł główny podczas serializacji obiektu za pomocą JSON.NET?

[JsonCustomRoot("status")] 
public class StatusDTO 
{ 
    public int StatusId { get; set; } 
    public string Name { get; set; } 
    public DateTime Created { get; set; } 
} 

Atrybut jest bardzo prosta:

public class JsonCustomRoot :Attribute 
{ 
    public string rootName { get; set; } 

    public JsonCustomRoot(string rootName) 
    { 
     this.rootName = rootName; 
    } 
} 

Domyślne wyjście z Json.NET podczas szeregowania instancję obiektu jest to:

{"StatusId":70,"Name":"Closed","Created":"2012-12-12T11:50:56.6207193Z"} 

teraz pytanie brzmi: Jak mogę dodać korzeń-węzeł do JSON z wartością niestandardowego attrib Ute jak tak:

{status:{"StatusId":70,"Name":"Closed","Created":"2012-12-12T11:50:56.6207193Z"}} 

Znalazłem kilka artykułów przywołujące interfejs IContractResolver, ale nie mogę zrozumieć, jak to zrobić. Moje próby obejmują ten niedokończony fragment kodu:

protected override JsonObjectContract CreateObjectContract(Type objectType) 
{ 
    JsonObjectContract contract = base.CreateObjectContract(objectType); 

    var info = objectType.GetCustomAttributes() 
        .SingleOrDefault(t => (Type)t.TypeId==typeof(JsonCustomRoot)); 
    if (info != null) 
    { 
     var myAttribute = (JsonCustomRoot)info; 
     // How can i add myAttribute.rootName to the root from here? 
     // Maybe some other method should be overrided instead? 
    } 

    return contract; 
} 
+0

Też szukam czegoś takiego, nie chcę zawijać moich odpowiedzi na kontrolerach dla każdego 'GET', szukałem sposobu, aby to zrobić jako ustawienie lub niestandardowy atrybut na każdym modelu. – MilkyWayJoe

+0

Idealnie, chciałbym zrobić prawie tak samo jak twój, ale wrócę jako tablica, nawet jeśli zwracany jest tylko jeden obiekt, np .: '{status: [{" StatusId ": 70," Name ":" Closed "," Utworzono ":" 2012-12-12 T11: 50: 56.6207193Z "}]}'. Próbuję również z 'IContractResolver' i JSON.NET – MilkyWayJoe

+0

Blogowałem o rozwiązaniu specyficznym dla api internetowej na http://www.emadibrahim.com/2014/04/09/emberjs-and-asp-net-web-api-and -json-serialization/ – Emad

Odpowiedz

5

Oto rozwiązanie specjalnie dla sieci Web API, które używam również: RootFormatter.cs

pisałem go na podstawie Creating a JSONP Formatter for ASP.NET Web API.

Zamiast używać niestandardowego atrybutu, ponownie korzystam z pola Tytuł JsonObjectAttribute. Oto kod Wykorzystanie:

using Newtonsoft.Json 

[JsonObject(Title = "user")] 
public class User 
{ 
    public string mail { get; set; } 
} 

Następnie dodać RootFormatter do App_Start i zarejestrować go w następujący WebApiConfig:

GlobalConfiguration.Configuration.Formatters.Insert(0, new RootFormatter()); 

udało mi się dostać zawinięty odpowiedź podobną do WCF na WebMessageBodyStyle.Wrapped:

{"user":{ 
    "mail": "[email protected]" 
}} 
+1

To jest naprawdę fajne! Byłoby jednak epickie, gdyby miało rozwiązanie dla kolekcji. – Levitikon

8

Co się stanie, jeśli użyjesz anonimowego obiektu?

JSON.Serialize(new { status = targetObject}); 
+3

Używam JSON.Net jako serializera w projekcie .NET 4.0 WebAPI, więc staram się unikać pisania niestandardowego kodu podczas zwracania danych. Chcę, żeby zostało to zrobione dla mnie, gdy atrybut zostanie zastosowany. – Espo

4

Bardzo prostym sposobem na osiągnięcie tego jest umieszczenie obiektu wewnątrz innego obiektu. być może było to zbyt proste, ale działa to podczas pracy z kolekcjami i pojedynczymi obiektami.

public class StatusDTO 
    { 
     public int StatusId { get; set; } 
     public string Name { get; set; } 
     public DateTime Created { get; set; } 
    } 

    public class statusJasonModel 
    { 
     public StatusDTO status { get; set; } 
    } 

Teraz możesz umieścić StatusDTO wewnątrz obiektu statusJsonModel i serializować go jako Json. Powinien dać ci pożądaną odpowiedź.

-1

Miałem podobne wyzwanie w jednym z moich projektów. Poniżej znajduje się krok, który podjąłem w celu rozwiązania problemu.

1. Podmiot, klasa

public class Product 
    { 
     [Key] 
     public string Id { get; set; } 
     public string Title { get; set; } 
     public string Album { get; set; } 
     public string Artist { get; set; } 
     public string Genre { get; set; } 

    } 

2. Utworzono innej klasy, który jest zdefiniowany w tej formie.

public class KindOfMedia 
     { 
      public KindOfMedia() 
      { 
       Product = new List<Product>(); 
      } 
      public List<Product> Product { get; set; } 
     } 

3.Sterownik Web API, że powróci json

  public HttpResponseMessage Products() 
      { 
       var kind = new KindOfMedia(); 
       kind.Products = new List<Product>(); 
       kind.Products.Add(new Product 
       { 
        Id = Guid.NewGuid().ToString(), 
        Title = "I am A Winner", 
        Album = "", 
        Artist = "Project Fame", 
        Genre = "Contemporal"     
       }); 
       kind.Products.Add(new Product 
       { 
        Id = Guid.NewGuid().ToString(), 
        Title = "Great Nation", 
        Album = "Oceans", 
        Artist = "Timi Dakolo", 
        Genre = "Gospel" 
       }); 

       return Request.CreateResponse(HttpStatusCode.OK, kind); 
      } 

4. Dodaj następujący wiersz kodu do mojego pliku WebAPI Config w folderze App_Start

 var json = config.Formatters.JsonFormatter; 
       json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None; 

należy pamiętać, że Newtonsoft.Json.PreserveReferencesHandling .Nie, nie zachowuje odniesienia do serializującego typu:

Wynikowy Json to

{ 
    "Musics": [ 
    { 
     "Id": "bf9faeee-7c39-4c33-a0ea-f60333604061", 
     "Title": "I am A Winner", 
     "Album": "", 
     "Artist": "Project Fame", 
     "Genre": "Contemporal" 
    }, 
    { 
     "Id": "243edd32-7ba2-4ac4-8ab9-bba6399cb0a6", 
     "Title": "Great Nation", 
     "Album": "Oceans", 
     "Artist": "Timi Dakolo", 
     "Genre": "Gospel" 
    } 
    ] 
} 
+0

Skąd się bierze obiekt główny Musics? – Caltor

Powiązane problemy