JSON.net kullanılarak aynı özellik için hem tek bir öğe hem de bir dizi nasıl işlenir


108

SendGridPlus kitaplığımı SendGrid olaylarıyla başa çıkacak şekilde düzeltmeye çalışıyorum, ancak API'deki kategorilerin tutarsız işlenmesiyle ilgili bazı sorunlar yaşıyorum.

SendGrid API başvurusundan alınan aşağıdaki örnek yükte , categoryher öğenin özelliğinin tek bir dize veya bir dize dizisi olabileceğini fark edeceksiniz .

[
  {
    "email": "john.doe@sendgrid.com",
    "timestamp": 1337966815,
    "category": [
      "newuser",
      "transactional"
    ],
    "event": "open"
  },
  {
    "email": "jane.doe@sendgrid.com",
    "timestamp": 1337966815,
    "category": "olduser",
    "event": "open"
  }
]

JSON.NET'i bu şekilde yapma seçeneklerim, dizeyi gelmeden önce düzeltmek veya JSON.NET'i yanlış verileri kabul edecek şekilde yapılandırmak gibi görünüyor. Ben paçayı sıyırabilirsem, herhangi bir dizge ayrıştırmayı tercih etmem.

Bunu Json.Net kullanarak halledebilmemin başka bir yolu var mı?

Yanıtlar:


211

Bu durumu halletmenin en iyi yolu bir gelenek kullanmaktır JsonConverter.

Dönüştürücüye gitmeden önce, verilerin serisini kaldıracak bir sınıf tanımlamamız gerekecek. CategoriesTek bir öğe ve bir dizi arasında değişebilen özellik için, onu bir olarak tanımlayın List<string>ve bir [JsonConverter]öznitelikle işaretleyin, böylece JSON.Net bu özellik için özel dönüştürücüyü kullanacağını bilecektir. Ayrıca [JsonProperty], üye özelliklerine JSON'da tanımlanandan bağımsız olarak anlamlı adlar verilebilmesi için özniteliklerin kullanılmasını da tavsiye ederim .

class Item
{
    [JsonProperty("email")]
    public string Email { get; set; }

    [JsonProperty("timestamp")]
    public int Timestamp { get; set; }

    [JsonProperty("event")]
    public string Event { get; set; }

    [JsonProperty("category")]
    [JsonConverter(typeof(SingleOrArrayConverter<string>))]
    public List<string> Categories { get; set; }
}

Dönüştürücüyü nasıl uygulayacağım burada. Dikkat edin, dönüştürücüyü jenerik yaptım, böylece gerektiğinde dizilerle veya diğer nesne türleriyle kullanılabilir.

class SingleOrArrayConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(List<T>));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        if (token.Type == JTokenType.Array)
        {
            return token.ToObject<List<T>>();
        }
        return new List<T> { token.ToObject<T>() };
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

İşte dönüştürücünün örnek verilerinizle nasıl çalıştığını gösteren kısa bir program:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        [
          {
            ""email"": ""john.doe@sendgrid.com"",
            ""timestamp"": 1337966815,
            ""category"": [
              ""newuser"",
              ""transactional""
            ],
            ""event"": ""open""
          },
          {
            ""email"": ""jane.doe@sendgrid.com"",
            ""timestamp"": 1337966815,
            ""category"": ""olduser"",
            ""event"": ""open""
          }
        ]";

        List<Item> list = JsonConvert.DeserializeObject<List<Item>>(json);

        foreach (Item obj in list)
        {
            Console.WriteLine("email: " + obj.Email);
            Console.WriteLine("timestamp: " + obj.Timestamp);
            Console.WriteLine("event: " + obj.Event);
            Console.WriteLine("categories: " + string.Join(", ", obj.Categories));
            Console.WriteLine();
        }
    }
}

Ve son olarak, işte yukarıdakilerin çıktısı:

email: john.doe@sendgrid.com
timestamp: 1337966815
event: open
categories: newuser, transactional

email: jane.doe@sendgrid.com
timestamp: 1337966815
event: open
categories: olduser

Keman: https://dotnetfiddle.net/lERrmu

DÜZENLE

Aynı formatı korurken diğer yoldan gitmeniz, yani serileştirmeniz gerekirse WriteJson(), dönüştürücünün yöntemini aşağıda gösterildiği gibi uygulayabilirsiniz. ( CanWriteGeçersiz kılmayı kaldırdığınızdan veya geri dönecek şekilde değiştirdiğinizden emin olun true, aksi WriteJson()takdirde asla çağrılmayacaktır.)

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        List<T> list = (List<T>)value;
        if (list.Count == 1)
        {
            value = list[0];
        }
        serializer.Serialize(writer, value);
    }

Keman: https://dotnetfiddle.net/XG3eRy


5
Mükemmel! Sen adamsın. Neyse ki, özellikleri daha anlamlı hale getirmek için JsonProperty'yi kullanmakla ilgili diğer tüm şeyleri zaten yapmıştım. İnanılmaz derecede eksiksiz bir cevap için teşekkür ederim. :)
Robert McLaws

Sorun değil; yararlı bulduğuna sevindim.
Brian Rogers

1
Mükemmel! Bu aradığım şey. @BrianRogers, eğer Amsterdam'da olursanız, içecekler benden!
Deli Köpek Tannen'in

2
@israelaltar Yukarıdaki cevapta gösterildiği gibi, sınıfınızdaki list özelliğindeki özniteliği DeserializeObjectkullanırsanız , dönüştürücüyü çağrıya eklemenize gerek yoktur [JsonConverter]. Eğer varsa yok özelliğini kullanın sonra, evet, hiç dönüştürücü geçmesi gerekir DeserializeObject.
Brian Rogers

1
@ShaunLangley, dönüştürücü kullanımı listesi yerine bir dizi yapmak için tüm başvuruları değiştirmek için List<T>konvertördeki T[]ve değişim .Countiçin .Length. dotnetfiddle.net/vnCNgZ
Brian Rogers

7

Yıllardır bunun üzerinde çalışıyordum ve cevabı için Brian'a teşekkürler. Tüm eklediğim vb.net yanıtı !:

Public Class SingleValueArrayConverter(Of T)
sometimes-array-and-sometimes-object
    Inherits JsonConverter
    Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
        Throw New NotImplementedException()
    End Sub

    Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
        Dim retVal As Object = New [Object]()
        If reader.TokenType = JsonToken.StartObject Then
            Dim instance As T = DirectCast(serializer.Deserialize(reader, GetType(T)), T)
            retVal = New List(Of T)() From { _
                instance _
            }
        ElseIf reader.TokenType = JsonToken.StartArray Then
            retVal = serializer.Deserialize(reader, objectType)
        End If
        Return retVal
    End Function
    Public Overrides Function CanConvert(objectType As Type) As Boolean
        Return False
    End Function
End Class

sonra sınıfınızda:

 <JsonProperty(PropertyName:="JsonName)> _
 <JsonConverter(GetType(SingleValueArrayConverter(Of YourObject)))> _
    Public Property YourLocalName As List(Of YourObject)

Umarım bu sana biraz zaman kazandırır


Yazım hataları: <JsonConverter (GetType (SingleValueArrayConverter (Of YourObject)))> _ Public Property YourLocalName As List (Of YourObject)
GlennG

3

Bir küçük farklılıklarla olarak büyük bir cevap ile Brian Rogers , burada iki ince ayarların sürümleri bulunmaktadır SingleOrArrayConverter<T>.

İlk olarak, burada kendisi bir koleksiyon olmayan List<T>her tür için herkes için çalışan bir sürüm var T:

public class SingleOrArrayListConverter : JsonConverter
{
    // Adapted from this answer https://stackoverflow.com/a/18997172
    // to /programming/18994685/how-to-handle-both-a-single-item-and-an-array-for-the-same-property-using-json-n
    // by Brian Rogers https://stackoverflow.com/users/10263/brian-rogers
    readonly bool canWrite;
    readonly IContractResolver resolver;

    public SingleOrArrayListConverter() : this(false) { }

    public SingleOrArrayListConverter(bool canWrite) : this(canWrite, null) { }

    public SingleOrArrayListConverter(bool canWrite, IContractResolver resolver)
    {
        this.canWrite = canWrite;
        // Use the global default resolver if none is passed in.
        this.resolver = resolver ?? new JsonSerializer().ContractResolver;
    }

    static bool CanConvert(Type objectType, IContractResolver resolver)
    {
        Type itemType;
        JsonArrayContract contract;
        return CanConvert(objectType, resolver, out itemType, out contract);
    }

    static bool CanConvert(Type objectType, IContractResolver resolver, out Type itemType, out JsonArrayContract contract)
    {
        if ((itemType = objectType.GetListItemType()) == null)
        {
            itemType = null;
            contract = null;
            return false;
        }
        // Ensure that [JsonObject] is not applied to the type.
        if ((contract = resolver.ResolveContract(objectType) as JsonArrayContract) == null)
            return false;
        var itemContract = resolver.ResolveContract(itemType);
        // Not implemented for jagged arrays.
        if (itemContract is JsonArrayContract)
            return false;
        return true;
    }

    public override bool CanConvert(Type objectType) { return CanConvert(objectType, resolver); }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        Type itemType;
        JsonArrayContract contract;

        if (!CanConvert(objectType, serializer.ContractResolver, out itemType, out contract))
            throw new JsonSerializationException(string.Format("Invalid type for {0}: {1}", GetType(), objectType));
        if (reader.MoveToContent().TokenType == JsonToken.Null)
            return null;
        var list = (IList)(existingValue ?? contract.DefaultCreator());
        if (reader.TokenType == JsonToken.StartArray)
            serializer.Populate(reader, list);
        else
            // Here we take advantage of the fact that List<T> implements IList to avoid having to use reflection to call the generic Add<T> method.
            list.Add(serializer.Deserialize(reader, itemType));
        return list;
    }

    public override bool CanWrite { get { return canWrite; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var list = value as ICollection;
        if (list == null)
            throw new JsonSerializationException(string.Format("Invalid type for {0}: {1}", GetType(), value.GetType()));
        // Here we take advantage of the fact that List<T> implements IList to avoid having to use reflection to call the generic Count method.
        if (list.Count == 1)
        {
            foreach (var item in list)
            {
                serializer.Serialize(writer, item);
                break;
            }
        }
        else
        {
            writer.WriteStartArray();
            foreach (var item in list)
                serializer.Serialize(writer, item);
            writer.WriteEndArray();
        }
    }
}

public static partial class JsonExtensions
{
    public static JsonReader MoveToContent(this JsonReader reader)
    {
        while ((reader.TokenType == JsonToken.Comment || reader.TokenType == JsonToken.None) && reader.Read())
            ;
        return reader;
    }

    internal static Type GetListItemType(this Type type)
    {
        // Quick reject for performance
        if (type.IsPrimitive || type.IsArray || type == typeof(string))
            return null;
        while (type != null)
        {
            if (type.IsGenericType)
            {
                var genType = type.GetGenericTypeDefinition();
                if (genType == typeof(List<>))
                    return type.GetGenericArguments()[0];
            }
            type = type.BaseType;
        }
        return null;
    }
}

Aşağıdaki şekilde kullanılabilir:

var settings = new JsonSerializerSettings
{
    // Pass true if you want single-item lists to be reserialized as single items
    Converters = { new SingleOrArrayListConverter(true) },
};
var list = JsonConvert.DeserializeObject<List<Item>>(json, settings);

Notlar:

  • Dönüştürücü, JSON değerinin tamamını belleğe bir JTokenhiyerarşi olarak önceden yükleme ihtiyacını ortadan kaldırır .

  • Dönüştürücü, öğeleri aynı zamanda koleksiyon olarak serileştirilen listeler için geçerli değildir, örn. List<string []>

  • Yapıcıya canWriteiletilen Boole bağımsız değişkeni, tek öğeli listelerin JSON değerleri olarak mı yoksa JSON dizileri olarak mı yeniden serileştirileceğini denetler.

  • Dönüştürücüler ReadJson(), existingValueyalnızca-elde edilen liste üyelerinin doldurulmasını desteklemek için önceden tahsis edilmişse kullanır .

İkincisi, işte diğer genel koleksiyonlarla çalışan bir sürüm ObservableCollection<T>:

public class SingleOrArrayCollectionConverter<TCollection, TItem> : JsonConverter
    where TCollection : ICollection<TItem>
{
    // Adapted from this answer https://stackoverflow.com/a/18997172
    // to /programming/18994685/how-to-handle-both-a-single-item-and-an-array-for-the-same-property-using-json-n
    // by Brian Rogers https://stackoverflow.com/users/10263/brian-rogers
    readonly bool canWrite;

    public SingleOrArrayCollectionConverter() : this(false) { }

    public SingleOrArrayCollectionConverter(bool canWrite) { this.canWrite = canWrite; }

    public override bool CanConvert(Type objectType)
    {
        return typeof(TCollection).IsAssignableFrom(objectType);
    }

    static void ValidateItemContract(IContractResolver resolver)
    {
        var itemContract = resolver.ResolveContract(typeof(TItem));
        if (itemContract is JsonArrayContract)
            throw new JsonSerializationException(string.Format("Item contract type {0} not supported.", itemContract));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        ValidateItemContract(serializer.ContractResolver);
        if (reader.MoveToContent().TokenType == JsonToken.Null)
            return null;
        var list = (ICollection<TItem>)(existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator());
        if (reader.TokenType == JsonToken.StartArray)
            serializer.Populate(reader, list);
        else
            list.Add(serializer.Deserialize<TItem>(reader));
        return list;
    }

    public override bool CanWrite { get { return canWrite; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        ValidateItemContract(serializer.ContractResolver);
        var list = value as ICollection<TItem>;
        if (list == null)
            throw new JsonSerializationException(string.Format("Invalid type for {0}: {1}", GetType(), value.GetType()));
        if (list.Count == 1)
        {
            foreach (var item in list)
            {
                serializer.Serialize(writer, item);
                break;
            }
        }
        else
        {
            writer.WriteStartArray();
            foreach (var item in list)
                serializer.Serialize(writer, item);
            writer.WriteEndArray();
        }
    }
}

Ardından, modeliniz ObservableCollection<T>bazıları için kullanıyorsa, Taşağıdaki gibi uygulayabilirsiniz:

class Item
{
    public string Email { get; set; }
    public int Timestamp { get; set; }
    public string Event { get; set; }

    [JsonConverter(typeof(SingleOrArrayCollectionConverter<ObservableCollection<string>, string>))]
    public ObservableCollection<string> Category { get; set; }
}

Notlar:

  • Notlar ve için sınırlamaların yanı sıra SingleOrArrayListConverter, TCollectiontip okuma / yazma ve parametresiz yapıcı olması gerekir.

Demo keman burada temel birim testleri ile .


0

Çok benzer bir Sorunum vardı. Json İsteğim benim için tamamen bilinmiyordu. Ben sadece biliyordum.

İçinde bir nesne kimliği ve bazı anonim anahtar değer çiftleri VE dizileri olacaktır.

Yaptığım bir EAV Modeli için kullandım:

JSON İsteğim:

{objectId ": 2," firstName ":" Hans "," email ": [" a@b.de "," a@c.de "]," ad ":" Andre "," bir şey ": [" 232 "," 123 "]}

Sınıfım tanımladım:

[JsonConverter(typeof(AnonyObjectConverter))]
public class AnonymObject
{
    public AnonymObject()
    {
        fields = new Dictionary<string, string>();
        list = new List<string>();
    }

    public string objectid { get; set; }
    public Dictionary<string, string> fields { get; set; }
    public List<string> list { get; set; }
}

ve şimdi bilinmeyen öznitelikleri, değeri ve içindeki dizilerle seriyi kaldırmak istediğime göre, Dönüştürücüm şöyle görünüyor:

   public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        AnonymObject anonym = existingValue as AnonymObject ?? new AnonymObject();
        bool isList = false;
        StringBuilder listValues = new StringBuilder();

        while (reader.Read())
        {
            if (reader.TokenType == JsonToken.EndObject) continue;

            if (isList)
            {
                while (reader.TokenType != JsonToken.EndArray)
                {
                    listValues.Append(reader.Value.ToString() + ", ");

                    reader.Read();
                }
                anonym.list.Add(listValues.ToString());
                isList = false;

                continue;
            }

            var value = reader.Value.ToString();

            switch (value.ToLower())
            {
                case "objectid":
                    anonym.objectid = reader.ReadAsString();
                    break;
                default:
                    string val;

                    reader.Read();
                    if(reader.TokenType == JsonToken.StartArray)
                    {
                        isList = true;
                        val = "ValueDummyForEAV";
                    }
                    else
                    {
                        val = reader.Value.ToString();
                    }
                    try
                    {
                        anonym.fields.Add(value, val);
                    }
                    catch(ArgumentException e)
                    {
                        throw new ArgumentException("Multiple Attribute found");
                    }
                    break;
            }

        }

        return anonym;
    }

Artık her AnonymObject aldığımda, Sözlük üzerinden yineleme yapabiliyorum ve "ValueDummyForEAV" Bayrağım olduğu her zaman listeye geçiyorum, ilk satırı okuyorum ve değerleri bölüyorum. Daha sonra listeden ilk girişi silip sözlükten yinelemeye devam ediyorum.

Belki birinin sorunu aynıdır ve bunu kullanabilir :)

Saygılarımızla Andre


0

JSONConverterAttributeBurada bulunan şekilde kullanabilirsiniz : http://james.newtonking.com/projects/json/help/

Gibi görünen bir sınıfınız olduğunu varsayarsak

public class RootObject
{
    public string email { get; set; }
    public int timestamp { get; set; }
    public string smtpid { get; set; }
    public string @event { get; set; }
    public string category[] { get; set; }
}

Kategori özelliğini burada görüldüğü gibi dekore edersiniz:

    [JsonConverter(typeof(SendGridCategoryConverter))]
    public string category { get; set; }

public class SendGridCategoryConverter : JsonConverter
{
  public override bool CanConvert(Type objectType)
  {
    return true; // add your own logic
  }

  public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  {
   // do work here to handle returning the array regardless of the number of objects in 
  }

  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  {
    // Left as an exercise to the reader :)
    throw new NotImplementedException();
  }
}

Bunun için teşekkürler, ancak yine de sorunu çözmüyor. Gerçek bir dizi geldiğinde, kodum gerçek bir diziye sahip bir nesne için çalışmadan önce hala bir hata atıyor. Ek bilgi: Nesne seri durumdan çıkarılırken beklenmeyen belirteç: Dize. Yol '[2] .kategori [0]', satır 17, konum 27. '
Robert McLaws

+ "\" olay \ ": \" işlendi \ ", \ n" + "} \ n" + "]";
Robert McLaws

İlk nesneyi iyi işledi ve hiçbir dizi olmadan güzelce ele aldı. Ancak 2. nesne için bir dizi oluşturduğumda başarısız oldu.
Robert McLaws

@AdvancedREI Kodunuzu görmeden JSON'u okuduktan sonra okuyucuyu yanlış bir konumda bıraktığınızı tahmin ediyorum. Okuyucuyu doğrudan kullanmaya çalışmak yerine okuyucudan bir JToken nesnesi yüklemek ve oradan gitmek daha iyidir. Dönüştürücünün çalışan bir uygulaması için cevabımı görün.
Brian Rogers

Brian'ın cevabında çok daha ayrıntılı. Bunu kullan :)
Tim Gabrhel

0

Bunu halletmek için özel bir JsonConverter kullanmanız gerekir. Ama muhtemelen aklınızda zaten vardı. Hemen kullanabileceğiniz bir dönüştürücü arıyorsunuz. Ve bu, açıklanan durum için bir çözümden daha fazlasını sunar. Sorulan soru ile bir örnek veriyorum.

Dönüştürücümü nasıl kullanırım:

Özelliğin üstüne bir JsonConverter Özniteliği yerleştirin. JsonConverter(typeof(SafeCollectionConverter))

public class SendGridEvent
{
    [JsonProperty("email")]
    public string Email { get; set; }

    [JsonProperty("timestamp")]
    public long Timestamp { get; set; }

    [JsonProperty("category"), JsonConverter(typeof(SafeCollectionConverter))]
    public string[] Category { get; set; }

    [JsonProperty("event")]
    public string Event { get; set; }
}

Ve bu benim dönüştürücüm:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;

namespace stackoverflow.question18994685
{
    public class SafeCollectionConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return true;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            //This not works for Populate (on existingValue)
            return serializer.Deserialize<JToken>(reader).ToObjectCollectionSafe(objectType, serializer);
        }     

        public override bool CanWrite => false;

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
}

Ve bu dönüştürücü aşağıdaki sınıfı kullanır:

using System;

namespace Newtonsoft.Json.Linq
{
    public static class SafeJsonConvertExtensions
    {
        public static object ToObjectCollectionSafe(this JToken jToken, Type objectType)
        {
            return ToObjectCollectionSafe(jToken, objectType, JsonSerializer.CreateDefault());
        }

        public static object ToObjectCollectionSafe(this JToken jToken, Type objectType, JsonSerializer jsonSerializer)
        {
            var expectArray = typeof(System.Collections.IEnumerable).IsAssignableFrom(objectType);

            if (jToken is JArray jArray)
            {
                if (!expectArray)
                {
                    //to object via singel
                    if (jArray.Count == 0)
                        return JValue.CreateNull().ToObject(objectType, jsonSerializer);

                    if (jArray.Count == 1)
                        return jArray.First.ToObject(objectType, jsonSerializer);
                }
            }
            else if (expectArray)
            {
                //to object via JArray
                return new JArray(jToken).ToObject(objectType, jsonSerializer);
            }

            return jToken.ToObject(objectType, jsonSerializer);
        }

        public static T ToObjectCollectionSafe<T>(this JToken jToken)
        {
            return (T)ToObjectCollectionSafe(jToken, typeof(T));
        }

        public static T ToObjectCollectionSafe<T>(this JToken jToken, JsonSerializer jsonSerializer)
        {
            return (T)ToObjectCollectionSafe(jToken, typeof(T), jsonSerializer);
        }
    }
}

Tam olarak ne yapar? Eğer dönüştürücü niteliğini yerleştirirseniz, dönüştürücü bu özellik için kullanılacaktır. 1 sonuçlu veya sonuçsuz bir json dizisi bekliyorsanız, normal bir nesne üzerinde kullanabilirsiniz. Veya IEnumerablebir json nesnesi veya json dizisi beklediğiniz bir yerde kullanırsınız. (Bir array- object[]- nin bir olduğunu bilin IEnumerable) Bir dezavantaj, bu dönüştürücünün yalnızca bir mülkün üzerine yerleştirilebilmesidir çünkü her şeyi dönüştürebileceğini düşünür. Ve uyarıl . A stringaynı zamanda bir IEnumerable.

Ve soruya bir cevaptan daha fazlasını sunar: Kimliğe göre bir şey ararsanız, bir sonuçla ya da sonuçsuz bir dizi geri alacağınızı bilirsiniz. ToObjectCollectionSafe<TResult>()Yöntem sizin için işleyebilir.

Bu, JSON.net kullanan Tek Sonuçlu Dizi için kullanılabilir ve aynı özellik için hem tek bir öğeyi hem de bir diziyi işleyebilir ve bir diziyi tek bir nesneye dönüştürebilir.

Bunu bir dizide bir sonuç döndüren ancak sonucu kodumda tek bir nesne olarak geri almak isteyen bir sunucuda REST istekleri için yaptım. Ayrıca, bir dizideki bir öğeyle genişletilmiş sonuç içeren bir OData sonuç yanıtı için.

Onunla iyi eğlenceler.


-2

Nesneyi kullanarak kategoriyi dize veya dizi olarak ele alabilen başka bir çözüm buldum. Bu şekilde json serileştiriciyle uğraşmam gerekmiyor.

Lütfen vaktiniz varsa bir göz atın ve bana ne düşündüğünüzü söyleyin. https://github.com/MarcelloCarreira/sendgrid-csharp-eventwebhook

Https://sendgrid.com/blog/tracking-email-using-azure-sendgrid-event-webhook-part-1/ adresindeki çözüme dayanıyor, ancak aynı zamanda zaman damgasından tarih dönüşümü ekledim, değişkenleri yansıtmak için yükselttim mevcut SendGrid modeli (ve kategorileri çalıştırdı).

Ayrıca seçenek olarak temel kimlik doğrulamasına sahip bir işleyici oluşturdum. Ashx dosyalarına ve örneklere bakın.

Teşekkür ederim!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.