5

コントローラ(MVC 4 RC)からJsonを返すときに、プロパティにキャメルケースを使用するようにJsonを変更したいと思います。これを行うには、GlobalConfiguration.Formatters.JsonFormatterを設定してみました(これが正しいかどうかはわかりません... don私の前にコードはありません)が、これはController.Jsonメソッドによって出力されるJsonに影響を与えていないようです。

周りを見回したところ、このアプローチはWeb APIコントローラーなどにのみ影響するようです。これは本当ですか?また、これを達成するためにController.Json()メソッドを変更することは可能ですか?

4

3 に答える 3

7

@rouenが提案するように、独自のJsonDotNetResultを作成しました。

これは私のプロジェクトにあるものです:

public class JsonNetResult : ActionResult
{
    public Encoding ContentEncoding { get; set; }
    public string ContentType { get; set; }
    public object Data { get; set; }
    public int StatusCode { get; set; }

    public JsonSerializerSettings SerializerSettings { get; set; }

    public JsonNetResult()
    {
        SerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        var response = context.HttpContext.Response;

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

        if ((StatusCode >= 400) && (StatusCode <= 599))
            response.TrySkipIisCustomErrors = true;

        if (ContentEncoding != null)
            response.ContentEncoding = ContentEncoding;

        if (Data == null)
            return;

        var formatting = Formatting.None;

#if DEBUG
        formatting = Formatting.Indented;
#endif

        var writer = new JsonTextWriter(response.Output) { Formatting = formatting };

        var serializer = JsonSerializer.Create(SerializerSettings);
        serializer.Serialize(writer, Data);

        writer.Flush();
    }
}

次に、JsonDotNet(object viewModel)タイプのメソッドを提供するために継承する独自のbaseControllerがあります。

例えば

protected JsonNetResult JsonNet(object data = null, int statusCode = (int)HttpStatusCode.OK, string contentType = null)
{
    return new JsonNetResult
               {
                   Data = data,
                   StatusCode = statusCode,
                   ContentType = contentType
               };
}

protected JsonNetResult JsonNetForbidden()
{
    return JsonNet(statusCode: (int)HttpStatusCode.Forbidden);
}

protected JsonNetResult JsonNetNotFound()
{
    return JsonNet(statusCode: (int)HttpStatusCode.NotFound);
}

protected JsonNetResult JsonNetNoContent()
{
    return JsonNet(statusCode: (int)HttpStatusCode.NoContent);
}

protected JsonNetResult JsonNetCreated(object data)
{
    return JsonNet(data, (int)HttpStatusCode.Created);
}

protected JsonNetResult JsonNetReload()
{
    return JsonNet(new { reload = true });
}

protected JsonNetResult JsonNetRedirect(string url = null, string contentType = null)
{
    return JsonNet(new { redirectUrl = url }, contentType: contentType);
}

protected JsonNetResult JsonNetClientError(ErrorDictionary errors)
{
    return JsonNet(new { Errors = errors }, (int)HttpStatusCode.BadRequest);
}

protected JsonNetResult JsonNetUnauthorized()
{
    return JsonNet(null, (int)HttpStatusCode.Unauthorized);
}

protected JsonNetResult JsonNetFlashMessage(string message)
{
    return JsonNet(new { flashMessage = message });
}
于 2012-07-24T18:14:27.460 に答える
2

デフォルトの JavaScriptSerializer の動作を変更する方法はありません。

個人的には、すべての json アクションに独自の JsonDotNetResult (および BaseController のショートカット メソッド) を使用しています。さまざまな方法で設定を変更できるだけでなく、JSON.NET を使用するとパフォーマンスが大幅に向上します。 beta-1-big-performance-improvements-compact-framework-support-and-more.aspx

さらに、循環依存関係の自動解決 (より大きなプロジェクトでは常にヒットします) など、多くの小さな素敵なボーナスがあります。

5 分を自分の JsonDotNetResult に投資してください。

于 2012-07-24T14:33:02.837 に答える
0

asp.net MVC 3のソースによると(4番目のバージョンのソースは手元にありませんが、そこで何かが変更された可能性はほとんどありません)、それはできません。

Controller.Jsonを使用しnew JsonResult直接JsonResult.ExecuteResult使用します。new JavaScriptSerializer

少し前に、この動作に影響を与える方法を探していましたが、見つかりませんでした。

于 2012-07-24T14:21:27.667 に答える