2011-10-28 47 views
5

Tôi đang đăng dữ liệu JSON lên máy chủ ASP.NET MVC2. Tôi đăng các chuỗi JSON lớn (kết hợp với luồng tệp được mã hóa base64, đọc từ hệ thống tệp cục bộ). Cuộc gọi jQuery ajax hoạt động tốt với kích thước tệp khoảng 2.5Mb. Khi đã ở trên kích thước này, cuộc gọi ajax sẽ không thành công (không bao giờ đến bộ điều khiển). Tôi không thể phát hiện chính xác lỗi là gì - nó dường như không cư trú trong các biến lỗi.Bài đăng jQuery .ajax không thành công với đối tượng JSON lớn

Cuộc gọi ajax là như sau:

$.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)); 
      } 
     }); 

nơi _moleculefilestream là dòng base64 mã hóa lớn.

web.config của tôi bao gồm những điều sau đây:

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

Bất cứ ai có bất kỳ ý tưởng sáng?

Trả lời

1

Bạn đã thử điều chỉnh thời gian chờ chưa? 10 giây có thể đủ cho 2.5Mb nhưng không đủ.

+0

Cảm ơn mẹo Erick - Tôi đang thử nghiệm tại địa phương, vì vậy 10s là rất nhiều cho các tập tin lớn, nhưng tôi mất điểm của bạn cho môi trường sống và sẽ tăng thời gian chờ cho phù hợp. – Journeyman

1

CẬP NHẬT

Các yếu tố spnet:MaxJsonDeserializerMembers phải được thêm vào phần <appSettings> của file web.config của bạn, thiết lập để đó là tương đương với giá trị lớn nhất của một loại Int32 dữ liệu.

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

Trong trang chính thức documentation, bạn sẽ có thể tìm thấy tất cả thông tin về các yếu tố cũng như việc sử dụng chúng.

Lưu ý: Trong phần tài liệu chính thức, không nên điều chỉnh giá trị lớn nhất vì nó thể hiện rủi ro bảo mật. Lý tưởng nhất, bạn nên kiểm tra số lượng các mục bạn muốn deserialize và cố gắng để ước tính dựa trên kích thước json tối đa bạn đang sử dụng.

bài

gốc bởi @Flxtr: Here

OLD

Nếu bạn muốn tải lên một file, tại sao không thử sử dụng FormData

Ví dụ:

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'); 
     } 
    }); 
}; 

Sau đó, , ở phía máy chủ, thay đổi độ dài yêu cầu trong cấu hình web:

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

Ví dụ:

<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> 

Ngoài ra, thay đổi thông số processData-false trong yêu cầu ajax:

$.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"); 
    } 
}); 

Đây chỉ là gợi ý. Điều duy nhất thực sự làm việc cho tôi là sắp xếp lại danh sách và deserialize nó trên máy chủ.

Ví dụ, trên các mặt hàng:

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"); 
     } 
    }); 
}; 

Về phía server:

public ActionResult SavePermissions(string pStrPermissions) 
{ 
    var lLstObjResult = new Dictionary<string, object>(); 

    try 
    { 
     SecurityFactory.GetPermissionService().UpdateList(JsonConvert.DeserializeObject<IList<Permission>>(pStrPemissions)); 
     lLstObjResult.Add(MESSAGE, "Registro guardado exitosamente"); 
     lLstObjResult.Add(SUCCESS, true); 
    } 
    catch (Exception e) 
    { 
     lLstObjResult.Add(MESSAGE, e.Message); 
     lLstObjResult.Add(SUCCESS, false); 
    } 

    return Json(lLstObjResult, JsonRequestBehavior.AllowGet); 
} 

Tôi biết rằng đây không phải là cách tốt nhất, nhưng nó hoạt động cho đến khi một cái gì đó tốt hơn đến cùng.

Nếu bạn có cách nào tốt hơn để giải quyết vấn đề này, hãy chia sẻ nó.

Các vấn đề liên quan