jQuery .ajax发布失败,带有大型JSON对象

时间:2011-10-28 15:50:01

标签: jquery ajax json post

我将JSON数据发布到ASP.NET MVC2服务器。我发布了大型JSON字符串(其中包含一个base64编码的文件流,从本地文件系统读取)。 jQuery ajax调用工作正常,文件大小约为2.5Mb。一旦超过这个大小,ajax调用就会失败(永远不会到达控制器)。我无法准确地检测出错误是什么 - 它似乎没有填充错误变量。

ajax调用如下:

$.ajax({
            type: "POST",
            dataType: 'json',
            timeout: 10000,
            url: "/Molecule/SaveMolecule",
            data: { jsonpost: postdata, moleculetype: _moleculeType, moleculefilestream: _moleculefilestream, changedproducts: stringifiedChangedProducts }, // NOTE the moleculeType being added here
            success: function (data) {
                if (data.rc == "success") {
                    $.log('ServerSuccess:' + data.message);

                    molecule_updateLocalInstance();

                    _bMoleculeIsDirty = false;
                    if (bReturnToMoleculeList != null && bReturnToMoleculeList == true) {
                        navigator_Go('/Molecule/Index/' + _moleculeType);
                    }
                    else {
                        _saveMoleculeButtonFader = setTimeout(function () {

                            $('#profilesave-container').delay(500).html('<img src="/content/images/tick.png" width="32px" height="32px" /><label>' + _moleculeSingularTerm + ' was saved</label>').fadeIn(500);

                            _saveMoleculeButtonFader = setTimeout(function () { $('#profilesave-container').fadeOut(1000); }, 2000);

                        }, 500);
                    }

                } else {
                    $.log('ServerUnhappy:' + data.message);
                    RemoveMoleculeExitDialog();
                }
            }
            , error: function (jqXHR, textStatus, errorThrown) {
                alert('Save failed, check console for error message:' +textStatus+' '+ errorThrown);
                MarkMoleculeAsDirty();
                $.log('Molecule Save Error:' + helper_objectToString(textStatus+' '+errorThrown));
            }
        });

其中_moleculefilestream是大型base64编码流。

我的web.config包含以下内容:

<system.web.extensions>
    <scripting>
      <webServices>
        <jsonSerialization maxJsonLength="50000000">
        </jsonSerialization>
      </webServices>
    </scripting>
  </system.web.extensions>

有人有什么好主意吗?

3 个答案:

答案 0 :(得分:1)

尝试设置httpRuntime的maxRequestLength属性。

http://msdn.microsoft.com/en-us/library/e1f13641.aspx

您可以通过位置标记将其设置为您需要的控制器/操作。

答案 1 :(得分:1)

您是否尝试过调整超时?对于2.5Mb而言,10秒可能就够了,但不能更多。

答案 2 :(得分:1)

<强>更新

必须将<{1}}元素添加到 web.config 文件的spnet:MaxJsonDeserializerMembers部分,设置为 2147483647 ,这是等效的<appSettings>数据类型的最大值。

Int32

在官方documentation的此页面中,您将能够找到有关这些元素的所有信息及其用途。

注意:在官方文档的部分中,建议不要调整到最大值,因为它代表了安全风险。理想情况下,您应该检查要反序列化的项目数,并尝试根据您使用的最大json大小进行估算。

@Flxtr的原帖:Here

<强> OLD

如果您要上传文件,为什么不尝试使用FormData

例如:

<configuration>
  <appSettings>
    <add key="aspnet:MaxJsonDeserializerMembers" value="2147483647" />
  </appSettings>
</configuration>

然后,在服务器端,更改Web配置中的请求长度:

function getDataForm() {

    var data = new FormData();

    var files = fileUploader.get(0).files;
    if (files.length > 0) {
        data.append("File", files[0]);
    }
    data.append("ImagePath", "");

    data.append("Id", ImageId);
    data.append("Name", txtName.val().trim());
    data.append("Description", txtDescription.val().trim());

    return data;
}

function save(data) {
    $.ajax({
        type: "POST",
        url: "/Files/SaveImage",
        contentType: false,
        processData: false,
        data: data,
        success: function (response) {

            if (response.success) {
                $.showMessage(messages.NAME, messages.SUCCESS, "success");
                closeForm();
                Files.ImageList.gridImages.ajax.reload();
            }
            else {
                $.showMessage(messages.NAME, response.message, "error");
            };

            btnSave.button('reset');
        },
        error: function (request, status, exception) {
            $.showMessage(messages.NAME, exception, "error");
            btnSave.button('reset');
        }
    });
};

例如:

<httpRuntime targetFramework="4.6.1" maxRequestLength="65536"/>

另外,在ajax请求中将参数<system.web> <compilation debug="true" targetFramework="4.6.1" /> <httpRuntime targetFramework="4.6.1" maxRequestLength="65536"/> <customErrors mode="RemoteOnly"> <error statusCode="401" redirect="/Error/401" /> ... <error statusCode="411" redirect="/Error/411" /> </customErrors> </system.web> 更改为processData

false

这些只是建议。对我来说唯一真正有用的是序列化列表并在服务器上反序列化。

例如,在客户端:

$.ajax({
    url: "/Security/SavePermissions",
    type: "POST",
    processData: false,
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify(pStrPermissions),
    success: function (response) {
        if (response.success) {
            panel.showAlert("Permisos", "Se han actualizado correctamente los permisos.", "success");
            resetForm();
        }
        else {
            $.showMessage("Permisos", response.message, "error");
        };
    },
    error: function (request, status, exception) {
        $.showMessage("Permisos", exception, "error");
    }
});

在服务器端:

function savePermissions(pLstObjPermissions) {
    $.ajax({
        url: "/Security/SavePermissions",
        type: "POST",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify({ pStrPermissions: JSON.stringify(pLstObjPermissions)}) ,
        success: function (response) {
            if (response.success) {
                panel.showAlert("Permisos", "Se han actualizado correctamente los permisos.", "success");
                resetForm();
            }
            else {
                $.showMessage("Permisos", response.message, "error");
            };
        },
        error: function (request, status, exception) {
            $.showMessage("Permisos", exception, "error");
        }
    });
};

我知道这不是最好的方法,但它会有效,直到有更好的方式出现。

如果您有更好的方法来解决此问题,请分享。