it-swarm.com.de

Richtige JSON-Serialisierung in MVC 4

Ich möchte, dass JSON ordnungsgemäß serialisiert wird (camelCase) und dass bei Bedarf die Datumsformate geändert werden können.

Für die Web-API ist es sehr einfach - in der Global.asax führe ich den folgenden Code aus

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

Dieser Code behandelt auf Pipeline-Ebene die Serialisierung wie gewünscht.

Ich möchte dasselbe in MVC 4 erreichen - alle JSON-Befehle, die von Controller-Aktionsmethoden zurückgegeben wurden, müssen ordnungsgemäß serialisiert werden. Mit ein wenig Suchen fand ich den folgenden Code, um den Start der Anwendung Global.asax auszulösen:

HttpConfiguration config = GlobalConfiguration.Configuration;
Int32 index = config.Formatters.IndexOf(config.Formatters.JsonFormatter);
config.Formatters[index] = new JsonMediaTypeFormatter
{
     SerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
};

Es scheint gut zu funktionieren, aber wenn ich JSON von einem Controller zurückgebe, ist alles PascalCased. Ein einfaches Beispiel für meine Aktionsmethode:

private JsonResult GetJsonTest()
{
    var returnData = dataLayer.GetSomeObject();
    return Json(returnData, JsonRequestBehavior.AllowGet);
}

Mache ich das falsch? Irgendeine Idee, wie dies auf Pipeline-Ebene erreicht werden kann?

43
Mario

Ich würde empfehlen, etwas wie ServiceStack oder Json.NET für die Verarbeitung der Json-Ausgabe in Ihrer MVC-Anwendung zu verwenden. Sie können jedoch problemlos eine Klasse schreiben und die Json-Methode mithilfe einer Basisklasse überschreiben. Siehe mein Beispiel unten.

HINWEIS: Damit benötigen Sie nichts in Ihrer Datei Global.ascx.cs.

Benutzerdefinierte JsonDotNetResult-Klasse:

public class JsonDotNetResult : JsonResult
{
    private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        Converters = new List<JsonConverter> { new StringEnumConverter() }
    };

    public override void ExecuteResult(ControllerContext context)
    {
        if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
            string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("GET request not allowed");
        }

        var response = context.HttpContext.Response;

        response.ContentType = !string.IsNullOrEmpty(this.ContentType) ? this.ContentType : "application/json";

        if (this.ContentEncoding != null)
        {
            response.ContentEncoding = this.ContentEncoding;
        }

        if (this.Data == null)
        {
            return;
        }

        response.Write(JsonConvert.SerializeObject(this.Data, Settings));
    }
}

Basis-Controller-Klasse:

public abstract class Controller : System.Web.Mvc.Controller
{
    protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
    {
        return new JsonDotNetResult
            {
                Data = data,
                ContentType = contentType,
                ContentEncoding = contentEncoding,
                JsonRequestBehavior = behavior
            };
    }
}

Jetzt können Sie auf Ihrer Controller-Aktion einfach so etwas zurückgeben.

return Json(myObject, JsonRequestBehavior.AllowGet);

BAM. Sie haben jetzt camelcase Objects mit Json zurückgegeben :)

HINWEIS: Es gibt Möglichkeiten, dies mit den Serializer-Einstellungen für jedes Objekt zu tun, das Sie mit Json erstellen. Aber wer würde das jedes Mal abtippen wollen, wenn Sie Json zurückgeben wollen?

88
technicallyjosh

Während die Web-API JSON.NET verwendet, verwendet MVC4 standardmäßig den JavaScriptSerializer, und ich glaube nicht, dass er den Wechsel zur Camel Case-Serialisierung unterstützt. Überprüfen Sie Folgendes: Festlegen des Standard-JSON-Serializers in ASP.NET MVC

Mein Vorschlag ist, dass Sie ein benutzerdefiniertes JsonNetResult wie hier beschrieben erstellen JSON.NET als Standard-JSON-Serializer in ASP.NET MVC 3 verwenden - ist das möglich? und ändere die letzte Zeile in:

var serializedObject = JsonConvert.SerializeObject(
      Data,
      Formatting.Indented, ,
      new JsonSerializerSettings { MappingResolver = new CamelCaseMappingResolver() });
6
fcuesta
Note that below information is for Asp .Net core

Das .Net-Team hat kürzlich bekannt gegeben, dass MVC JSON nun standardmäßig mit Kamelfallnamen serialisiert.

Mit ein paar Zeilen darunter könnten Sie diese Funktionalität aktivieren:

services
.AddMvc()
.AddJsonOptions(options =>
options.SerializerSettings.ContractResolver = new DefaultContractResolver());

Ich habe ein kleines Blog darüber geschrieben, das ist hier .

5
Neel