NET'te json anahtarlarının küçük harf olmasını sağlama


103

Anahtarların küçük harf olarak gönderilmesini sağlamak için .NET'te JSON kullanmanın basit bir yolu var mı?

Şu anda newtonsoft'un Json.NET kitaplığını kullanıyorum ve sadece

string loginRequest = JsonConvert.SerializeObject(auth);

Bu durumda authsadece aşağıdaki nesne

public class Authority
{
    public string Username { get; set; }
    public string ApiToken { get; set; }
}

Bu sonuçlanır

{"Username":"Mark","ApiToken":"xyzABC1234"}

usernameVe apitokentuşlarının küçük harf olarak gelmesini sağlamanın bir yolu var mı ?

String.ToLower()Elbette basitçe geçmek istemiyorum çünkü için usernameve apitokenbüyük / küçük harfe yönelik değerler karışık.

Bunu programlı olarak yapabileceğimi ve JSON dizesini manuel olarak oluşturabileceğimin farkındayım, ancak buna yaklaşık 20 kadar JSON veri dizisi için ihtiyacım var ve kendime biraz zaman kazandırabilir miyim diye bakıyorum. Anahtar oluşturma için küçük harf kullanmanıza izin veren önceden oluşturulmuş kitaplıklar olup olmadığını merak ediyorum.


Belki json serileştirme kitaplığı, özelliklerinizin json serileştirilmiş adlarını değiştirmek için kullanabileceğiniz bir tür serileştirme öznitelikleri sunar?
tdammers

@tdammers, teşekkürler Bunu yapan bir şey bulmaya çalışıyorum, ancak şu ana kadar başarısız oldu. Buradaki birinin beni işaret etmesini umuyorum.
Mark

1
Bu , uygunluk tek bir kelimeden oluştuğunda faydalı olabilir.
Lipotam

Huh. Tam tersi bir problem yaşıyorum ... ayrıca - "Kullanıcı adı" nın karışık durumda olduğundan bahsetmeniz komik. "Kullanıcı Adı" mı demek istediniz?
BrainSlugs83

Hayır basitçe, karışık kalması gereken değerler, sadece dokunmam gereken tuşlardı. Değer yalnız bırakın.
Mark

Yanıtlar:


176

Bunun için özel bir sözleşme çözümleyici oluşturabilirsiniz. Aşağıdaki sözleşme çözümleyici, tüm anahtarları küçük harfe dönüştürür:

public class LowercaseContractResolver : DefaultContractResolver
{
    protected override string ResolvePropertyName(string propertyName)
    {
        return propertyName.ToLower();
    }
}

Kullanım:

var settings = new JsonSerializerSettings();
settings.ContractResolver = new LowercaseContractResolver();
var json = JsonConvert.SerializeObject(authority, Formatting.Indented, settings);

Wil sonuç:

{"username":"Mark","apitoken":"xyzABC1234"}

Her zaman kullanarak serileştirmek istiyorsanız LowercaseContractResolver, kendinizi tekrar etmekten kaçınmak için onu bir sınıfa sarmayı düşünün:

public class LowercaseJsonSerializer
{
    private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        ContractResolver = new LowercaseContractResolver()
    };

    public static string SerializeObject(object o)
    {
        return JsonConvert.SerializeObject(o, Formatting.Indented, Settings);
    }

    public class LowercaseContractResolver : DefaultContractResolver
    {
        protected override string ResolvePropertyName(string propertyName)
        {
            return propertyName.ToLower();
        }
    }
}

Hangisi şu şekilde kullanılabilir:

var json = LowercaseJsonSerializer.SerializeObject(new { Foo = "bar" });
// { "foo": "bar" }

ASP.NET MVC4 / WebAPI

ASP.NET MVC4 / WebAPI kullanıyorsanız CamelCasePropertyNamesContractResolver, varsayılan olarak dahil edilen bir Newtonsoft.Json kitaplığını kullanabilirsiniz .


bunu tersine yapmanın makul bir yolu var mı? Seriyi kaldırma için mi?
Shaun Rowan

1
@Anzeo Bunu kendim yapmaya çalışmadım ve bununla ilgili dokümantasyonda herhangi bir bilgi bulamadım. Bir çözüm, JsonConvert.SerializeObject'i kendi sınıfınıza sarmak olacaktır. Güncellememe bakın.
alexn

3
Görünüşe göre, bu özel sözleşme çözücü, istisnaları belirtmek istiyorsanız JsonProperty özniteliğini hesaba katmıyor ... örneğin [JsonProperty ("alternateName")] yine de küçük harfle yazılıyor veya bunu yapmanın başka bir yolu var mı?
rekna

2
+1 CamelCasePropertyNamesContractResolver. Şimdi bulduğum System.Net.Http.Formatting.JsonContractResolvervarsayılan WebAPI ve bu sınıf dahili. Sonunda JsonContractResolverdeve davasıyla yeniden yazıyorum . Birisi bunun herkese açık olduğunu bildirdi aspnetwebstack.codeplex.com/workitem/228
CallMeLaNN

10
CamelCasePropertyNamesContratResolverözellikleri küçük harfe dönüştürmeyin, yalnızca ilk karakteri.
ToXinE

23
protected void Application_Start() {
    JsonConfig.Configure();   
}

public static class JsonConfig
{
    public static void Configure(){
        var formatters = GlobalConfiguration.Configuration.Formatters;
        var jsonFormatter = formatters.JsonFormatter;
        var settings = jsonFormatter.SerializerSettings;

        settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }
}

10

In Json.NET 9.0.1 ve daha sonra tüm özellik adları özel bir kullanarak küçük harfe dönüştürülür sağlamak mümkündür NamingStrategy. Bu sınıf, sözleşme çözümleyiciden özellik adlarının algoritmik olarak yeniden eşlenmesi mantığını ayarlanabilen ayrı, hafif bir nesneye çıkarır DefaultContractResolver.NamingStrategy. Bunu yapmak, bir özelContractResolver oluşturma ihtiyacını ortadan kaldırır ve bu nedenle, halihazırda kendi sözleşme çözümleyicileri olan çerçevelere entegre edilmesi daha kolay olabilir.

Aşağıdaki LowercaseNamingStrategygibi tanımlayın :

public class LowercaseNamingStrategy : NamingStrategy
{
    protected override string ResolvePropertyName(string name)
    {
        return name.ToLowerInvariant();
    }
}

Ardından aşağıdaki gibi serileştirin:

var settings = new JsonSerializerSettings
{
    ContractResolver = new DefaultContractResolver { NamingStrategy = new LowercaseNamingStrategy() },
};
string loginRequest = JsonConvert.SerializeObject(auth, settings);

Notlar -


8

"JsonProperty" kullanabilirsiniz:

Kullanım:

public class Authority
{
    [JsonProperty("userName")] // or [JsonProperty("username")]
    public string Username { get; set; }
    [JsonProperty("apiToken")] // or [JsonProperty("apitoken")]
    public string ApiToken { get; set; }
}

var json  = JsonConvert.SerializeObject(authority);

0

Benim için diğer bazı cevapların bir kombinasyonunu kullandım ve bunu elde ettim

        return JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });

kendi çözümümü yaratmak istemediğim için aradıklarıma bir çözüme daha yakındı

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.