ASP.NET MVC denetleyici yöntemlerinden JSON.NET tarafından serileştirilmiş camelCase JSON nasıl dönebilirim?


246

Benim sorunum, JSON.NET tarafından serileştirilmiş ASP.NET MVC denetleyici yöntemlerinden ActionResult s aracılığıyla camelCased (standart PascalCase aksine) JSON verileri döndürmek istiyor olmasıdır .

Örnek olarak aşağıdaki C # sınıfını göz önünde bulundurun:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Varsayılan olarak, bu sınıfın bir örneğini MVC denetleyicisinden JSON olarak döndürürken, aşağıdaki şekilde serileştirilir:

{
  "FirstName": "Joe",
  "LastName": "Public"
}

Ben (JSON.NET tarafından) serileştirmek istiyorum:

{
  "firstName": "Joe",
  "lastName": "Public"
}

Bunu nasıl yaparım?

Yanıtlar:


389

veya basitçe şunu belirtin:

JsonConvert.SerializeObject(
    <YOUR OBJECT>, 
    new JsonSerializerSettings 
    { 
        ContractResolver = new CamelCasePropertyNamesContractResolver() 
    });

Örneğin:

return new ContentResult
{
    ContentType = "application/json",
    Content = JsonConvert.SerializeObject(new { content = result, rows = dto }, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }),
    ContentEncoding = Encoding.UTF8
};

2
Her denetleyici yöntemi için bir ContentResult yapılandırmanız gerektiğinden, bunun kullanımı daha karmaşıktır.
Mayıs

2
Evet, cevabınızın yeniden kullanılabilir bir çözüm olduğunu anlıyorum, amacım bunun sadece Serialize yönteminde bir parametre olduğunu daha açık hale getirmektir.
WebDever

1
JSON'u bir Controlleryöntemden döndürüyorsanız , büyük olasılıkla bir kullanmalısınız ApiController, bu durumda bu cevap harika çalışır.
Simon Hartcher

1
@SimonHartcher Sorunun kapsamını genel durum değil, düşünün.
aknuds1

1
JSON için geçerli içerik türü application/jsondeğil text/plain.
Fred

94

Mats Karlsson'un blogunda bu soruna mükemmel bir çözüm buldum . Çözüm, JSON.NET aracılığıyla verileri serileştiren ve ikincisini camelCase kuralını izleyecek şekilde yapılandıran bir ActionResult alt sınıfı yazmaktır:

public class JsonCamelCaseResult : ActionResult
{
    public JsonCamelCaseResult(object data, JsonRequestBehavior jsonRequestBehavior)
    {
        Data = data;
        JsonRequestBehavior = jsonRequestBehavior;
    }

    public Encoding ContentEncoding { get; set; }

    public string ContentType { get; set; }

    public object Data { get; set; }

    public JsonRequestBehavior JsonRequestBehavior { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
        }

        var response = context.HttpContext.Response;

        response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType : "application/json";
        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }
        if (Data == null)
            return;

        var jsonSerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
        response.Write(JsonConvert.SerializeObject(Data, jsonSerializerSettings));
    }
}

Ardından bu sınıfı MVC denetleyici yönteminizde aşağıdaki gibi kullanın:

public ActionResult GetPerson()
{
    return new JsonCamelCaseResult(new Person { FirstName = "Joe", LastName = "Public" }, JsonRequestBehavior.AllowGet)};
}

3
Mükemmel cevap: temiz ve tekrar kullanılabilir! Teşekkür ederim.
zımpara

1
Bu çözüm hala çalışırken. ancak 4 yıl önce önerildi. Daha iyi bir çözümümüz var mı?
SharpCoder

59

WebAPI için şu bağlantıya göz atın : http://odetocode.com/blogs/scott/archive/2013/03/25/asp-net-webapi-tip-3-camelcasing-json.aspx

Temel olarak, bu kodu şu adrese ekleyin Application_Start:

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();

4
Web API ve MVC, ASP.NET 6
AlexFoxGill

1
Kolaylık sağlamak için bağlantı; Bu kurulum bu cevapla gerçekten güzel oynuyor: stackoverflow.com/a/26068063/398630 (farklı soru, ancak bunları birlikte kullanıyorum ve bu bağlantı beni ve diğerlerini gelecekte kurtarabilir).
BrainSlugs83

37

Bence bu aradığınız basit cevap. Bu geliyor Shawn Wildermuth bireyin blogda:

// Add MVC services to the services container.
services.AddMvc()
  .AddJsonOptions(opts =>
  {
    opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
  });

2
Özür dilerim çocuklar. Bu gönderiyi çok hızlı okudum. ASP.NET 5 içindir.
Quantium

8
İronik olarak, buraya cevapladığınız soruya bir cevap aramaya geldim, bu yüzden OP'nin sorusunun cevabı olmasa da, yine de bana yardımcı oldu. Teşekkürler! :)
porcus

1
@Porcus ne dedi ikinci! Teşekkürler @Quantium!
Gromer

4
ASP.NET Core 1.0 için varsayılan olarak deve durumda OOTB
Chris Marisic

3
Sonuçta bu, .NET Core 1.0 için (tam olarak) varsayılan değil. Bu çözüm dinamik özellikleri etkiler ve varsayılan olarak etkilenmezler. stackoverflow.com/questions/41329279/…
Niels Brinch

13

Özel filtreye bir alternatif, herhangi bir nesneyi JSON'a serileştirmek için bir uzantı yöntemi oluşturmaktır.

public static class ObjectExtensions
{
    /// <summary>Serializes the object to a JSON string.</summary>
    /// <returns>A JSON string representation of the object.</returns>
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new List<JsonConverter> { new StringEnumConverter() }
        };

        return JsonConvert.SerializeObject(value, settings);
    }
}

Ardından denetleyici eyleminden dönerken arayın.

return Content(person.ToJson(), "application/json");

Zarif ve basit.
markau

1
Ayarları statik bir salt okunur alana aktarabilir ve bir FromJson tamamlayıcı yöntemi ekleyebilirsiniz.
Sokakta buhar

8

Daha basit daha iyi IMO!

Bunu neden yapmıyorsun?

public class CourseController : JsonController
{
    public ActionResult ManageCoursesModel()
    {
        return JsonContent(<somedata>);
    }
}

Basit temel sınıf kontrolörü

public class JsonController : BaseController
{
    protected ContentResult JsonContent(Object data)
    {
        return new ContentResult
        {
            ContentType = "application/json",
             Content = JsonConvert.SerializeObject(data, new JsonSerializerSettings { 
              ContractResolver = new CamelCasePropertyNamesContractResolver() }),
            ContentEncoding = Encoding.UTF8
        };
    }
}

7

ASP.NET Core MVC'de.

    public IActionResult Foo()
    {
        var data = GetData();

        var settings = new JsonSerializerSettings 
        { 
            ContractResolver = new CamelCasePropertyNamesContractResolver() 
        });

        return Json(data, settings);
    }

Ve daha da iyisi, Startup.cs dosyasına koyun.
FatAlbert

6

Aşağıda, bir nesne dizisini serileştirerek bir json dizesi (cameCase) döndüren bir eylem yöntemidir.

public string GetSerializedCourseVms()
    {
        var courses = new[]
        {
            new CourseVm{Number = "CREA101", Name = "Care of Magical Creatures", Instructor ="Rubeus Hagrid"},
            new CourseVm{Number = "DARK502", Name = "Defence against dark arts", Instructor ="Severus Snape"},
            new CourseVm{Number = "TRAN201", Name = "Transfiguration", Instructor ="Minerva McGonal"}
        };
        var camelCaseFormatter = new JsonSerializerSettings();
        camelCaseFormatter.ContractResolver = new CamelCasePropertyNamesContractResolver();
        return JsonConvert.SerializeObject(courses, camelCaseFormatter);
    }

İkinci parametre olarak iletilen JsonSerializerSettings örneğine dikkat edin. CamelCase'i böyle yapar.


4

Bunu beğendim:

public static class JsonExtension
{
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            NullValueHandling = NullValueHandling.Ignore,
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize
        };
        return JsonConvert.SerializeObject(value, settings);
    }
}

Bu MVC çekirdeğinde basit bir uzatma yöntemi, projenizdeki her nesneye ToJson () yeteneği verecek, Bence bir MVC projesinde, nesnenin çoğu json olma yeteneğine sahip olmalı, tabii ki bağlıdır :)


ToJson yöntemi her çağrıldığında yeni bir değişken başlatmamanız için, "settings" değişkenini yöntemin dışında (özel statik alan "camelCaseSettings" olarak) ayıklamayı düşünün.
Ekus

4

'Startup.cs' dosyasındaki ayarları ayarlamanız gerekir

Ayrıca JsonConvert'in varsayılan değerlerinde tanımlamanız gerekir, bu daha sonra bir nesneyi serileştirmek için doğrudan kütüphaneyi kullanmak istiyorsanız.

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options => {
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });
        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    }

Bu cevabın ASP.NET Core için doğru olduğunu, ancak ASP.NET (bu sorudaki çerçeve) için doğru olmadığını unutmayın.
Nate Barbettini

0

ActionResult'u .net core web api veya IHttpAction sonucuna döndürüyorsanız, modelinizi ön ucunuzdaki durumla eşleşecek ve sizin için serileştirecek bir Ok () yöntemiyle tamamlayabilirsiniz. JsonConvert kullanmaya gerek yok. :)

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.