web-dev-qa-db-ja.com

MVC JsonResultキャメルケースのシリアル化

すべてのプロパティがcamelCaseにあるJsonResultをアクションに返すようにしています。

私は単純なモデルを持っています:

public class MyModel
{
    public int SomeInteger { get; set; }

    public string SomeString { get; set; }
}

そして、シンプルなコントローラーアクション:

public JsonResult Index()
    {
        MyModel model = new MyModel();
        model.SomeInteger = 1;
        model.SomeString = "SomeString";

        return Json(model, JsonRequestBehavior.AllowGet);
    }

このアクションメソッドを呼び出すと、次のデータを含むJsonResultが返されるようになりました。

{"SomeInteger":1,"SomeString":"SomeString"}

私の用途では、キャメルケースのデータを返すアクションが必要です、どういうわけか次のように:

{"someInteger":1,"someString":"SomeString"}

これを行うエレガントな方法はありますか?

私はこの辺りで可能な解決策を探していました MVC3 JSONシリアル化:プロパティ名を制御する方法? DataMember定義をモデルのすべてのプロパティに設定しましたが、私はこれを本当にしたくありません。

また、まさにこの種の問題を解決できると彼らが言うリンクを見つけました: http://www.asp.net/web-api/overview/formats-and-model-binding/json- and-xml-serialization#json_camelcasing 。それは言います:

データモデルを変更せずにキャメルケースでJSONプロパティ名を記述するには、シリアライザーでCamelCasePropertyNamesContractResolverを設定します:

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

このブログの1つのエントリ http://frankapi.wordpress.com/2012/09/09/going-camelcase-in-asp-net-mvc-web-api/ もこのソリューションに言及し、述べていますこの問題を修正するには、単にRouteConfig.RegisterRoutesに追加します。試しましたが、うまくいきませんでした。

あなたは私が何か間違ったことをしていた場所を知っていますか?

31
Thomas Mondel

コントローラーのJson関数は、JsonResultsを作成するための単なるラッパーです。

protected internal JsonResult Json(object data)
{
    return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
}

protected internal JsonResult Json(object data, string contentType)
{
    return Json(data, contentType, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
}

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding)
{
    return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet);
}

protected internal JsonResult Json(object data, JsonRequestBehavior behavior)
{
    return Json(data, null /* contentType */, null /* contentEncoding */, behavior);
}

protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior)
{
    return Json(data, contentType, null /* contentEncoding */, behavior);
}

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
    return new JsonResult
    {
        Data = data,
        ContentType = contentType,
        ContentEncoding = contentEncoding,
        JsonRequestBehavior = behavior
    };
}

JsonResultは内部的にJavaScriptSerializerを使用しているため、シリアル化プロセスを制御できません。

public class JsonResult : ActionResult
{
    public JsonResult()
    {
        JsonRequestBehavior = JsonRequestBehavior.DenyGet;
    }

    public Encoding ContentEncoding { get; set; }

    public string ContentType { get; set; }

    public object Data { get; set; }

    public JsonRequestBehavior JsonRequestBehavior { get; set; }

    /// <summary>
    /// When set MaxJsonLength passed to the JavaScriptSerializer.
    /// </summary>
    public int? MaxJsonLength { get; set; }

    /// <summary>
    /// When set RecursionLimit passed to the JavaScriptSerializer.
    /// </summary>
    public int? RecursionLimit { 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(MvcResources.JsonRequest_GetNotAllowed);
        }

        HttpResponseBase response = context.HttpContext.Response;

        if (!String.IsNullOrEmpty(ContentType))
        {
            response.ContentType = ContentType;
        }
        else
        {
            response.ContentType = "application/json";
        }
        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }
        if (Data != null)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            if (MaxJsonLength.HasValue)
            {
                serializer.MaxJsonLength = MaxJsonLength.Value;
            }
            if (RecursionLimit.HasValue)
            {
                serializer.RecursionLimit = RecursionLimit.Value;
            }
            response.Write(serializer.Serialize(Data));
        }
    }
}

独自のJsonResultを作成し、独自のJson Controller関数を作成する必要があります(必要な場合/必要な場合)。新しいものを作成するか、既存のものを上書きすることができます。それはあなた次第です。この link も興味があるかもしれません。

13
Dresel

キャメルケース表記に準拠したアクションからjson文字列を返したい場合は、JsonSerializerSettingsインスタンスを作成し、JsonConvert.SerializeObject(a、b)メソッドの2番目のパラメーターとして渡す必要があります。

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);
    }
15
DanKodi