none
ASP.NETのMVC4でサイズの大きいJSONをリクエストするとエラーとなる

    質問

  • ASP.NETのMVC4でWEBの開発を行っています。

    クライアントからサイズの大きいJSONデータをサーバにリクエストするとサーバー側で

    「JSON リクエストが大きすぎるため、逆シリアル化できませんでした」

    とのエラーが発生してしまいます。

    Web.ConfigにjsonSerialization maxJsonLengthを設定することで対処ができるとの

    記事を見つけ実施してみましたが改善はされませんでした。

    上記内容を改善できる方法をご存知の方はいらっしゃいませんでしょうか。

    開発環境はVisualStudio2012です。

    2013年8月2日 8:27

回答

  • ASP.NET 4, MVC 3 の環境ですが、クライアントから Web サーバーに送信する JSON データの文字数の制限を変更する方法はないか調べてみました。

    MVC の action メソッドの場合、JavaScriptSerializer.MaxJsonLength プロパティのデフォルト値(2,097,152 文字)を超えて、クライアントからサーバーにJSON データを送信すると、以下のエラーとなります。

    ****** エラーメッセージ(ここから)******
    JSON JavaScriptSerializer を使用したシリアル化または逆シリアル化中にエラーが発生しました。文字列の長さが maxJsonLength プロパティで設定されている値を超えています。
    パラメーター名: input
    説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。

    例外の詳細: System.ArgumentException: JSON JavaScriptSerializer を使用したシリアル化または逆シリアル化中にエラーが発生しました。文字列の長さが maxJsonLength プロパティで設定されている値を超えています。
    パラメーター名: input

    ソース エラー:

    現在の Web 要求の実行中にハンドルされていない例外が生成されました。障害の原因および発生場所に関する情報については、下の例外スタック トレースを使って確認できます。 

    スタック トレース:

    [ArgumentException: JSON JavaScriptSerializer を使用したシリアル化または逆シリアル化中にエラーが発生しました。文字列の長さが maxJsonLength プロパティで設定されている値を超えています。
    パラメーター名: input]
       System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit) +593333
       System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(String input) +13
       System.Web.Mvc.JsonValueProviderFactory.GetDeserializedObject(ControllerContext controllerContext) +190
       System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +19
       System.Web.Mvc.<>c__DisplayClassc.<GetValueProvider>b__7(ValueProviderFactory factory) +34
       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151
       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +177
    ・・・以下省略・・・
    ****** エラーメッセージ(ここまで)******

    JavaScriptSerializer.DeserializeObject メソッドを使用している JsonValueProviderFactory クラスの GetDeserializedObject メソッドは以下のように定義されています。

    private static object GetDeserializedObject(ControllerContext controllerContext)
    {
        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
        {
            // not JSON request
            return null;
        }
    
        StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
        string bodyText = reader.ReadToEnd();
        if (String.IsNullOrEmpty(bodyText))
        {
            // no JSON data
            return null;
        }
    
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        object jsonData = serializer.DeserializeObject(bodyText);
        return jsonData;
    }

    ここで使われている JavaScriptSerializer オブジェクトの MaxJsonLength プロパティの設定を変更する手段はなさそうなので、MVC の action メソッドを呼び出している限りは制限を 2,097,152 文字を超えて設定する手段はなさそうです。

    どうしても 2,097,152 文字を超えて設定する必要があれば、action メソッドではなく、web サービス(.asmx)を作ってそのメソッドを呼び出すようにして、web.config の maxJsonLength の設定を変更するぐらいしか思いつきません。

    <追記>

    一部修正しました。 maxRequestLength ⇒ maxJsonLength



    • 回答としてマーク msddev 2013年8月5日 6:36
    • 編集済み SurferOnWww 2013年8月5日 9:24 一部修正
    2013年8月5日 5:41
  • > MVCを利用している限りはクライアント→Webサーバ時のmaxRequestLengthは変更できなさそうですね。

    MVC でも呼び出す相手を Web サービスのメソッドにすることができます。Web サービスのメソッドなら web.config の maxJsonLength の設定は有効に働きますので、2,097,152 文字を超えて設定することは可能です。

    Int32.MaxValue まで可能かは検証してませんけど、2,097,152 文字を超えて設定することは可能であることは検証しました。(ASP.NET 4, MVC 3 ですが)

    こんな感じで web サービス (MaxJsonLengthTest.asmx) を作ってアプリケーションルートに配置すると。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    
    namespace MvcApplication1
    {
        /// <summary>
        /// MaxJsonLengthTest の概要の説明です
        /// </summary>
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        [System.ComponentModel.ToolboxItem(false)]
        [System.Web.Script.Services.ScriptService]
        public class MaxJsonLengthTest : System.Web.Services.WebService
        {
            [WebMethod]
            public string[] TestMethod(string[] data)
            {
                int totalChar = 0;
                foreach (string s in data)
                {
                    totalChar += s.Length + 3;
                }
                totalChar += 10;
                string[] result = { "data.Length is " + data.Length.ToString(), ", totalChar is " + totalChar.ToString() };
                return result;
            }
        }
    }

    ビューからクライアントスクリプト (jQuery 利用)で以下のように呼び出せます。

    var values = '[';
    for (var i = 0; i < 209715; i++) {
        values += '"1234567",';
    }
    values = values.replace(/,$/, "]");
    
    function getResults2() {
        $.ajax({
            type: "POST",
    
            url: "MaxJsonLengthTest.asmx/TestMethod",
    
            data: '{"data":' + values + '}',
    
            contentType: "application/json; charset=utf-8",
    
            dataType: "json",
    
            success: function (response) {
                var msg = response.d;
                $('#output').empty();
                $('#output').append('<p>' + msg[0] + msg[1] + '</p>');
            },
    
            error: function (jqXHR, textStatus, errorThrown) {
                $('#output').text('textStatus: ' + textStatus + ', errorThrown: ' + errorThrown);
            }
        });
    }

    d パラメータの処置に注意してください。上記のコードでは var msg = response.d; の部分です。

    <追記>

    一部修正しました。 maxRequestLength ⇒ maxJsonLength


    • 回答としてマーク msddev 2013年8月5日 7:40
    • 編集済み SurferOnWww 2013年8月5日 9:25 一部修正
    2013年8月5日 7:06
  • ASP.NET MVCはソースコードが公開されています。

    あと、以前より言われておりました実際の例外は下記になります。
    [InvalidOperationException: JSON リクエストが大きすぎるため、逆シリアル化できませんでした。]
       System.Web.Mvc.EntryLimitedDictionary.Add(String key, Object value) +112
       System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backing...

    で問題になっているSystem.Web.Mvc.JsonValueProviderFactoryのコードを見ますと後半のEntryLimitedDictionaryクラス、GetMaximumDepth()メソッド辺りで私の提示したaspnet:MaxJsonDeserializerMembersを参照し、それをもとに制限をかけているように読めますが。

    • 回答としてマーク msddev 2013年8月5日 3:21
    2013年8月5日 2:28

すべての返信

  • どう書いたのでしょうか?
    2013年8月2日 10:33
  • お世話になります。

    Web.Configに

    <system.web.extensions>
        <scripting>
          <webServices>
            <jsonSerialization maxJsonLength="2147483647">
            </jsonSerialization>
          </webServices>
        </scripting>
    </system.web.extensions>
    と記載しました。
    2013年8月2日 11:15
  • web.config にどう書いたかではなく、Web サービスとそれに要求を出すコードをどのように書いたかの情報を開示できないのですか?
    2013年8月2日 11:32
  • Web サービスに要求を出す方法はブラウザのJavaScriptよりJqueryのAjaxにて変数(list)をそのまま送信しています。

           $.ajax({
                url: server_url
                dataType: 'json',
                type: 'POST',
                contentType: 'application/json',
                data: JSON.stringify(list)
            })

    list(オブジェクト)に格納しているデータが大きい(maxJsonLengthのデフォルト値以上)場合にエラーとなります。

    要はWeb.ConfigのmaxJsonLengthが有効になっていないのではないかと思っています。

    2013年8月2日 12:31
  • > list(オブジェクト)に格納しているデータが大きい(maxJsonLengthのデフォルト
    > 値以上)場合にエラーとなります。

    ブラウザから Web サーバーに送信するデータの大きさのことを言ってますか? であれば、maxRequestLength (デフォルトで 4MB)の制限に引っかかっているのではないですか?

    httpRuntime 要素 (ASP.NET 設定スキーマ)
    http://msdn.microsoft.com/ja-jp/library/e1f13641(v=vs.100).aspx

    2013年8月3日 2:07
  • >ブラウザから Web サーバーに送信するデータの大きさのことを言ってますか?であれば、maxRequestLength (デフォルトで 4MB)の制限に引っかかっているのではないですか?

    そうですが、ちょっと違います。

    もし、maxRequestLengthに制限されているならConfigurationErrorsExceptionが発生するようですが

    そうではなく、先に書きましたように

    「JSON リクエストが大きすぎるため、逆シリアル化できませんでした」

    となります。

    ブラウザのリクエストサイズはクリアされ、サーバ側でJSONをパースする際にエラーとなっているようです。

    2013年8月3日 2:22
  • > ブラウザのリクエストサイズはクリアされ、サーバ側でJSONを
    > パースする際にエラーとなっているようです。

    「ようです」ということですが、実際に maxRequestLength の設定を十分大きくして試してみたのでしょうか?

    また、エラーメッセージは省略しないで、差し支えない範囲で全てコピペしてください。

    2013年8月3日 3:20
  • 少しググって調べてみました。

    ひょっとして、Web サーバー側で要求を受けて処理しているのは Web サービスメソッドではなくて、MVC の action メソッドか controller では?

    そうであれば、以下のページの Answers の 2 つ目に書いてあることが原因として怪しそうです。

    Can I set an unlimited length for maxJsonLength in web.config?
    http://stackoverflow.com/questions/1151987/can-i-set-an-unlimited-length-for-maxjsonlength-in-web-config

    要するに、web.config の maxJsonLength を参照するのは Web サービスメソッドで使用される JavaScriptSerializer だけで、MVC action-method/Controller が使用する JavaScriptSerializer は web.config の maxJsonLength を無視する(JavaScriptSerializer.MaxJsonLength プロパティのデフォルト 2,097,152 文字のままになる?)と言ってます。

    上記のページに MVC 4 で使える Workaround も書いてありますので見てください。

    2013年8月3日 5:19
  • >ひょっとして、Web サーバー側で要求を受けて処理しているのは Web サービスメソッドではなくて、MVC の action メソッドか controller では?

    はい、そうです。

    先にも書きましたがASP.NETのMVC4を使用して、仰いますようにクライアントよりリクエストされたJSONを

    controllerのactionメソッドで処理しています。

    そうであれば、以下のページの Answers の 2 つ目に書いてあることが原因として怪しそうです。

    リンクありがとうございました。

    内容については、サーバからのレスポンスに対しての回避策が記述されていました。

    実はサーバからのレスポンスでも同様のエラーが発生しましたが、リンク内に記述されているJosonResultの

    MaxJsonLengthプロパティを変更してやることにより回避できています。

    やはり、Web.ConfigのMaxJsonLengthはMVC4では使えないようですね。

    サーバからのレスポンスに対しては上記のようにコーディングを行えば回避できるのですが、リクエストは

    ASP.NETのMVCフレームワークが勝手に処理してしまう部分なのでどうしたものかと困っています。

    2013年8月3日 9:33
  • 正確なエラーメッセージも教えてほしいところですが、stackoverflowによるとaspnet:MaxJsonDeserializerMembersの設定もあるそうです。An ASP.NET request that has lots of form keys, files, or JSON payload members fails with an exceptionのKBには具体的なエラーメッセージも載っていますがどうもこれとは違うようなので、何か別の問題かもしれません。
    • 回答の候補に設定 佐祐理 2013年8月5日 3:36
    2013年8月3日 9:46
  • 先のレスの質問、

    > 「ようです」ということですが、実際に maxRequestLength の設定を十分
    > 大きくして試してみたのでしょうか?
     
    > また、エラーメッセージは省略しないで、差し支えない範囲で全てコピペ
    > してください。

    に対する答えはもらえないのですか?

    一方的に自分の書きたいことを書くだけでなく、質問されたらきちんと答えるのがマナーだと思いますけど。

    2013年8月3日 13:53
  • ありがとうございます。

    別問題かもしれませんが、可能性の一つとして考慮させていただきます。

    2013年8月3日 23:34
  • すみません。

    現場じゃないと実施できませんので、明日現場より実施します。


    2013年8月3日 23:37
  • > 現場じゃないと実施できませんので、明日現場より実施します。

    ということは、先の質問者さんからのレスにあったことは実際に検証した結果ではなく、質問者さんの頭の中で考えたことなのですね。

    であれば、是非、実際に検証した上で回答ください。

    エラーメッセージの全文もそうですが、その他、特に、実際に stackoverflow に書いてあった workaround では対応できないか、下記レスは間違いないかを検証していただければと思います。

    > サーバからのレスポンスに対しては上記のようにコーディングを行えば回避できる
    > のですが、リクエストはASP.NETのMVCフレームワークが勝手に処理してしまう部分
    > なのでどうしたものかと困っています。

    それから、佐祐理さんのレスにあった「aspnet:MaxJsonDeserializerMembersの設定」も、"The system.web.extensions method didn't do anything, but the appSettings was the magic fix." とのことですので、是非実際に検証してみてください。

    このフォーラムは技術者同士の情報交換の場所ということで、よろしくお願いします。

    2013年8月4日 3:04
  • >ということは、先の質問者さんからのレスにあったことは実際に検証した結果ではなく、質問者さんの頭の中で考えたことな>のですね。

    >であれば、是非、実際に検証した上で回答ください。

    全てではありませんが、maxRequestLengthに関しては想定です。他のレスについては「サーバからのレスポンスに対しては上記のようにコーディングを行えば回避できる」と明記していますし全てのレスを想像で返しているようなご返答は心外です。


    >エラーメッセージの全文もそうですが、その他、特に、実際に stackoverflow に書いてあった workaround では対応できないか、下記レスは間違いないかを検証していただければと思います。

    サーバからのレスポンスに対して回避できるのは間違いないです。workaroundもレスポンスに対しての回避を記述されていますよね?どこにリクエストに対しての回避方法が記述されているのでしょうか?


    >それから、佐祐理さんのレスにあった「aspnet:MaxJsonDeserializerMembersの設定」も、"The system.web.extensions method didn't do anything, but the appSettings was the magic fix." とのことですので、是非実際に検証してみてください。

    実際に検証してみましたが、ダメでした。
    MaxJsonDeserializerMembersの制限(少なく)で出力される例外は下記になります。

    [InvalidOperationException: JavaScriptSerializer によって単一の辞書に逆シリアル化されたアイテム数が既に最大数に達しました。JSON 辞書エントリの最大許容カウントを現在の値 10 から変更するには、"aspnet:MaxJsonDeserializerMembers" 設定を変更します。詳細については、http://go.microsoft.com/fwlink/?LinkId=238386 を参照してください。]
       System.Web.Script.Serialization.JavaScriptObjectDeserializer.ThrowIfMaxJsonDeserializerMembersExceeded(Int32 count) +218
       System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth) +940
       System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) +424
       System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeList(Int32 depth) +354
       System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) +531
       System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth) +954
       System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) +424
       System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer) +108
       System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit) +210
       System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(String input) +86
       System.Web.Mvc.JsonValueProviderFactory.GetDeserializedObject(ControllerContext controllerContext) +297
       System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +123
       System.Web.Mvc.<>c__DisplayClassc.<GetValueProvider>b__7(ValueProviderFactory factory) +59
       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +145
       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +171
       System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +460
       System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
       System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext) +360
       System.Web.Mvc.ControllerBase.get_ValueProvider() +85
       System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +154
       System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +199
       System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) +978
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag) +53
       System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +523
       System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState) +83
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag, Int32 timeout) +97
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) +53
       System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +501
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag, Int32 timeout) +97
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) +53
       System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +417
       System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +49
       System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__2(AsyncCallback asyncCallback, Object asyncState) +127
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag, Int32 timeout) +97
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) +53
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +373
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

    あと、以前より言われておりました実際の例外は下記になります。

    [InvalidOperationException: JSON リクエストが大きすぎるため、逆シリアル化できませんでした。]
       System.Web.Mvc.EntryLimitedDictionary.Add(String key, Object value) +112
       System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) +418
       System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) +204
       System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) +362
       System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) +204
       System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +234
       System.Web.Mvc.<>c__DisplayClassc.<GetValueProvider>b__7(ValueProviderFactory factory) +59
       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +145
       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +171
       System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +460
       System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
       System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext) +360
       System.Web.Mvc.ControllerBase.get_ValueProvider() +85
       System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +154
       System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +199
       System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) +978
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag) +53
       System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +523
       System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState) +83
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag, Int32 timeout) +97
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) +53
       System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +501
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag, Int32 timeout) +97
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) +53
       System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +417
       System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +49
       System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__2(AsyncCallback asyncCallback, Object asyncState) +127
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag, Int32 timeout) +97
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) +53
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +373
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

    また、上記レスでmaxRequestLengthの制限で出力される例外は下記になります。

    [HttpException (0x80004005): 要求の長さの最大値を超えました。]
       System.Web.HttpRequest.GetEntireRawContent() +9664313
       System.Web.HttpRequest.get_InputStream() +41
       System.Web.HttpRequestWrapper.get_InputStream() +9
       System.Web.Mvc.JsonValueProviderFactory.GetDeserializedObject(ControllerContext controllerContext) +177
       System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +123
       System.Web.Mvc.<>c__DisplayClassc.<GetValueProvider>b__7(ValueProviderFactory factory) +59
       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +145
       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +171
       System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +460
       System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
       System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext) +360
       System.Web.Mvc.ControllerBase.get_ValueProvider() +85
       System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +154
       System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +199
       System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) +978
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag) +53
       System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +523
       System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState) +83
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag, Int32 timeout) +97
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) +53
       System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +501
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag, Int32 timeout) +97
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) +53
       System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +417
       System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +49
       System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__2(AsyncCallback asyncCallback, Object asyncState) +127
       System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +161
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +92
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag, Int32 timeout) +97
       System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) +53
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +373
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

    2013年8月5日 1:53
  • ASP.NET MVCはソースコードが公開されています。

    あと、以前より言われておりました実際の例外は下記になります。
    [InvalidOperationException: JSON リクエストが大きすぎるため、逆シリアル化できませんでした。]
       System.Web.Mvc.EntryLimitedDictionary.Add(String key, Object value) +112
       System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backing...

    で問題になっているSystem.Web.Mvc.JsonValueProviderFactoryのコードを見ますと後半のEntryLimitedDictionaryクラス、GetMaximumDepth()メソッド辺りで私の提示したaspnet:MaxJsonDeserializerMembersを参照し、それをもとに制限をかけているように読めますが。

    • 回答としてマーク msddev 2013年8月5日 3:21
    2013年8月5日 2:28
  • >GetMaximumDepth()メソッド辺りで私の提示したaspnet:MaxJsonDeserializerMembersを参照し、それをもとに制限をかけているように読めますが。

    大変申し訳ありません。

    上記の対応で解決できました!

    佐祐理様、SurferOnWww様お手数をおかけしました。感謝いたします。

    私が、上記の対応でできなかったのはリクエストの方ではなくレスポンスのほうでした。

    ただ、レスポンスに於いてはコーディングで回避できるので特に問題としておりませんでしたが

    リクエストと同じ問題かと思っておりました。

    ちなみに、レスポンスで出力される例外は下記になります。

    [InvalidOperationException: JSON JavaScriptSerializer を使用したシリアル化または逆シリアル化中にエラーが発生しました。文字列の長さが maxJsonLength プロパティで設定されている値を超えています。]
       System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, StringBuilder output, SerializationFormat serializationFormat) +137
       System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, SerializationFormat serializationFormat) +83
       System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj) +44
       System.Web.Mvc.JsonResult.ExecuteResult(ControllerContext context) +817
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +39
       System.Web.Mvc.<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17() +74
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +388
       System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +72
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +303
       System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20() +155
       System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +184
       System.Web.Mvc.Async.WrappedAsyncResult`1.End() +136
       System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56
       System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +40
       System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +40
       System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +47
       System.Web.Mvc.Async.WrappedAsyncResult`1.End() +151
       System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
       System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
       System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +44
       System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +47
       System.Web.Mvc.Async.WrappedAsyncResult`1.End() +151
       System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
       System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
       System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +39
       System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +39
       System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +45
       System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +47
       System.Web.Mvc.Async.WrappedAsyncResult`1.End() +151
       System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
       System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
       System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +40
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9628700
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

    2013年8月5日 3:21
  • 一応、JavaScriptSerializerは別の場所でソース公開されています。ただまぁ、ドキュメントにある通りJavaScriptSerializer.MaxJsonLengthプロパティの値を超えるとこの例外が発生します。で、この値がどうなっているかというと、JavaScriptSerializerを呼び出しているSystem.Web.Mvc.JsonResultのコードを見ることになります。

    JavaScriptSerializer()は引数なしのコンストラクタでインスタンス生成されたのち、JsonResult.MaxJsonLengthプロパティの値を設定しています。ですので、SurferOnWwwさんの提示したstackoverflowのこの手順が(ワークアラウンドなどではなく)正しい設定方法ということになるでしょうか。

    • 回答の候補に設定 佐祐理 2013年8月5日 3:54
    2013年8月5日 3:54
  • 佐祐理さん>

    > EntryLimitedDictionaryクラス、GetMaximumDepth()メソッド辺りで私の提示した
    > aspnet:MaxJsonDeserializerMembersを参照し、それをもとに制限をかけているよう
    > に読めますが。

    それはクライアントから Web サーバーに送信できる JSON データの文字数の制限とは関係なくて、佐祐理さんが紹介された ASP.NET appSettings Element のページの説明 "the maximum number of items that can be present in any dictionary deserialized by the JavaScriptSerializer type." のとおり、IDictionary オブジェクトの中のアイテム数のようですね。


    msddev さん>

    > 上記の対応で解決できました!

    aspnet:MaxJsonDeserializerMembers の設定変更で解決できたということであれば、質問者さんのレスにあった、

    > list(オブジェクト)に格納しているデータが大きい(maxJsonLengthのデフォルト値以上)場合にエラーとなります。

    は思い違いで、クライアントから Web サーバーに送信する JSON データの文字数は、JavaScriptSerializer.MaxJsonLength プロパティの設定(MVC の action メソッドの場合)で制限される文字数(デフォルトで 2,097,152 文字)に収まっていたということになります。

    間違いないですか?


    • 編集済み SurferOnWww 2013年8月5日 4:20 一部修正
    2013年8月5日 4:11
  • JavaScriptSerializer()は引数なしのコンストラクタでインスタンス生成されたのち、JsonResult.MaxJsonLengthプロパティの値を設定しています。ですので、SurferOnWwwさんの提示したstackoverflowのこの手順が(ワークアラウンドなどではなく)正しい設定方法ということになるでしょうか。

    レスポンスに対してはstackoverflowのこの手順で良いと思います。(実際にこの手順で回避はできています)

    ただ、コーディングでこのようなことをしなくても全体的(WebConfig等で)にmaxJsonLengthの規定値が設定できないものなのかとは思っています。

    2013年8月5日 4:58
  • aspnet:MaxJsonDeserializerMembers の設定変更で解決できたということであれば、質問者さんのレスにあった、

    > list(オブジェクト)に格納しているデータが大きい(maxJsonLengthのデフォルト値以上)場合にエラーとなります。

    は思い違いで、クライアントから Web サーバーに送信する JSON データの文字数は、JavaScriptSerializer.MaxJsonLength プロパティの設定(MVC の action メソッドの場合)で制限される文字数(デフォルトで 2,097,152 文字)に収まっていたということになります。

    間違いないですか?

    申し訳ありませんが、「maxJsonLengthのデフォルト値以上」というのは思い違いでした。

    サーバへリクエストとレスポンスで同様のエラーメッセージが表示されたためそのように勘違いしてしまいました。

    2013年8月5日 5:05
  • ASP.NET 4, MVC 3 の環境ですが、クライアントから Web サーバーに送信する JSON データの文字数の制限を変更する方法はないか調べてみました。

    MVC の action メソッドの場合、JavaScriptSerializer.MaxJsonLength プロパティのデフォルト値(2,097,152 文字)を超えて、クライアントからサーバーにJSON データを送信すると、以下のエラーとなります。

    ****** エラーメッセージ(ここから)******
    JSON JavaScriptSerializer を使用したシリアル化または逆シリアル化中にエラーが発生しました。文字列の長さが maxJsonLength プロパティで設定されている値を超えています。
    パラメーター名: input
    説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。

    例外の詳細: System.ArgumentException: JSON JavaScriptSerializer を使用したシリアル化または逆シリアル化中にエラーが発生しました。文字列の長さが maxJsonLength プロパティで設定されている値を超えています。
    パラメーター名: input

    ソース エラー:

    現在の Web 要求の実行中にハンドルされていない例外が生成されました。障害の原因および発生場所に関する情報については、下の例外スタック トレースを使って確認できます。 

    スタック トレース:

    [ArgumentException: JSON JavaScriptSerializer を使用したシリアル化または逆シリアル化中にエラーが発生しました。文字列の長さが maxJsonLength プロパティで設定されている値を超えています。
    パラメーター名: input]
       System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit) +593333
       System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(String input) +13
       System.Web.Mvc.JsonValueProviderFactory.GetDeserializedObject(ControllerContext controllerContext) +190
       System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +19
       System.Web.Mvc.<>c__DisplayClassc.<GetValueProvider>b__7(ValueProviderFactory factory) +34
       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151
       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +177
    ・・・以下省略・・・
    ****** エラーメッセージ(ここまで)******

    JavaScriptSerializer.DeserializeObject メソッドを使用している JsonValueProviderFactory クラスの GetDeserializedObject メソッドは以下のように定義されています。

    private static object GetDeserializedObject(ControllerContext controllerContext)
    {
        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
        {
            // not JSON request
            return null;
        }
    
        StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
        string bodyText = reader.ReadToEnd();
        if (String.IsNullOrEmpty(bodyText))
        {
            // no JSON data
            return null;
        }
    
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        object jsonData = serializer.DeserializeObject(bodyText);
        return jsonData;
    }

    ここで使われている JavaScriptSerializer オブジェクトの MaxJsonLength プロパティの設定を変更する手段はなさそうなので、MVC の action メソッドを呼び出している限りは制限を 2,097,152 文字を超えて設定する手段はなさそうです。

    どうしても 2,097,152 文字を超えて設定する必要があれば、action メソッドではなく、web サービス(.asmx)を作ってそのメソッドを呼び出すようにして、web.config の maxJsonLength の設定を変更するぐらいしか思いつきません。

    <追記>

    一部修正しました。 maxRequestLength ⇒ maxJsonLength



    • 回答としてマーク msddev 2013年8月5日 6:36
    • 編集済み SurferOnWww 2013年8月5日 9:24 一部修正
    2013年8月5日 5:41
  • ここで使われている JavaScriptSerializer オブジェクトの MaxJsonLength プロパティの設定を変更する手段はなさそうなので、MVC の action メソッドを呼び出している限りは制限を 2,097,152 文字を超えて設定する手段はなさそうです。

    どうしても 2,097,152 文字を超えて設定する必要があれば、action メソッドではなく、web サービス(.asmx)を作ってそのメソッドを呼び出すようにして、web.config の maxRequestLength の設定を変更するぐらいしか思いつきません。

    ご検証いただきありがとうございます。

    MVCを利用している限りはクライアント→Webサーバ時のmaxRequestLengthは変更できなさそうですね。

    制限値を超える場合は、超えないような造りに変更することを考慮します。

    2013年8月5日 6:36
  • > MVCを利用している限りはクライアント→Webサーバ時のmaxRequestLengthは変更できなさそうですね。

    MVC でも呼び出す相手を Web サービスのメソッドにすることができます。Web サービスのメソッドなら web.config の maxJsonLength の設定は有効に働きますので、2,097,152 文字を超えて設定することは可能です。

    Int32.MaxValue まで可能かは検証してませんけど、2,097,152 文字を超えて設定することは可能であることは検証しました。(ASP.NET 4, MVC 3 ですが)

    こんな感じで web サービス (MaxJsonLengthTest.asmx) を作ってアプリケーションルートに配置すると。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    
    namespace MvcApplication1
    {
        /// <summary>
        /// MaxJsonLengthTest の概要の説明です
        /// </summary>
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        [System.ComponentModel.ToolboxItem(false)]
        [System.Web.Script.Services.ScriptService]
        public class MaxJsonLengthTest : System.Web.Services.WebService
        {
            [WebMethod]
            public string[] TestMethod(string[] data)
            {
                int totalChar = 0;
                foreach (string s in data)
                {
                    totalChar += s.Length + 3;
                }
                totalChar += 10;
                string[] result = { "data.Length is " + data.Length.ToString(), ", totalChar is " + totalChar.ToString() };
                return result;
            }
        }
    }

    ビューからクライアントスクリプト (jQuery 利用)で以下のように呼び出せます。

    var values = '[';
    for (var i = 0; i < 209715; i++) {
        values += '"1234567",';
    }
    values = values.replace(/,$/, "]");
    
    function getResults2() {
        $.ajax({
            type: "POST",
    
            url: "MaxJsonLengthTest.asmx/TestMethod",
    
            data: '{"data":' + values + '}',
    
            contentType: "application/json; charset=utf-8",
    
            dataType: "json",
    
            success: function (response) {
                var msg = response.d;
                $('#output').empty();
                $('#output').append('<p>' + msg[0] + msg[1] + '</p>');
            },
    
            error: function (jqXHR, textStatus, errorThrown) {
                $('#output').text('textStatus: ' + textStatus + ', errorThrown: ' + errorThrown);
            }
        });
    }

    d パラメータの処置に注意してください。上記のコードでは var msg = response.d; の部分です。

    <追記>

    一部修正しました。 maxRequestLength ⇒ maxJsonLength


    • 回答としてマーク msddev 2013年8月5日 7:40
    • 編集済み SurferOnWww 2013年8月5日 9:25 一部修正
    2013年8月5日 7:06
  • > MVCを利用している限りはクライアント→Webサーバ時のmaxRequestLengthは変更できなさそうですね。

    MVC でも呼び出す相手を Web サービスのメソッドにすることができます。Web サービスのメソッドなら web.config の maxRequestLength の設定は有効に働きますので、2,097,152 文字を超えて設定することは可能です。

    Int32.MaxValue まで可能かは検証してませんけど、2,097,152 文字を超えて設定することは可能であることは検証しました。(ASP.NET 4, MVC 3 ですが)

    サンプルありがとうございました。

    確かにJSONを受け付けて、ajaxへの結果を返すようなサービスは必ずしもMVCである必要性はありませんね。

    ご提案いただいた内容も含め、検討したいと思います。

    2013年8月5日 7:39
  • SurferOnWww様

    > MVCを利用している限りはクライアント→Webサーバ時のmaxRequestLengthは変更できなさそうですね。

    話題が、maxRequestLengthが動作しない件についてになっていますが実際はmaxJsonLengthが動作しないでした。

    申し訳ありません。

    2013年8月5日 7:49
  • すみません、自分も間違えてました。

    誤:maxRequestLength
     ↓
    正:maxJsonLength

    2013年8月5日 7:57