2015-03-25 5 views
2

Прежде всего, я новый разработчик, поэтому заранее прошу прощения, если я пропущу что-то очевидное.Ошибки при плохом запросе при попытке опубликовать большие данные JSON

Я разрабатываю веб-приложение для работы в автономном режиме с большими объемами данных в IndexedDB. Когда пользователь переходит к webapp, клиент захватывает всю базу данных с сервера и сохраняет ее для использования в indexeddb. Это работает отлично, но когда я пытаюсь использовать метод post для отправки данных (снова несколько записей) обратно в WCF, я получаю метод не разрешен или плохой запрос при попытке отправить параметр тела ajax, и когда я использую uri, он попадает на сервер, но не все данные отправляются. Я думал, что, возможно, недопустимые символы могут быть фактором, поэтому я использовал метод encodeURIComponent в javascript для преобразования недопустимых символов в действительный параметр uri. Я также попытался сжать данные с помощью javacript-сжатия api под названием LZString. Я пробовал использовать XMLHttpRequest (чего я не совсем понимаю). Этот webapp должен работать в автономном режиме, поэтому я не могу выполнить вызов сервера, кроме как для первоначального получения данных при первом открытии клиента и для синхронизации данных с сервером, поэтому я должен отправлять большие объемы данных за раз.

Я также использую обертку IndexedDB под названием Dexie.js.

Образцы моего кода ниже. Некоторый код прокомментирован, но остается показать, что я пробовал.

Это то, что я есть на сервере ..

[OperationContract] 
    [WebInvoke(Method = "POST", 
     RequestFormat = WebMessageFormat.Json, 
     ResponseFormat = WebMessageFormat.Json, 
     UriTemplate = "REST_SendCompletedServiceOrders", 
     BodyStyle = WebMessageBodyStyle.Wrapped)] 
    [FaultContract(typeof (Exception))] 
    bool REST_SendCompletedServiceOrders(string compressedWebData); 

Это событие щелчка на клиенте используется для синхронизации назад ..

$('#syncCompletedData').on('click', function() { 

    db.ServiceOrder 

     .toArray(function(so) { 
      var completedServiceOrders = []; 
      for (var i = 0; i < so.length; i++) { 
       if (so[i].IsCompleted) { 
        completedServiceOrders.push(so[i]); 
       }; 
      } 
      var customerId = sessionStorage.getItem("customerId"); 
      var companyId = sessionStorage.getItem("companyId"); 
      var computerId = sessionStorage.getItem("computerId"); 
      var webData = JSON.stringify({ webCustomerId: customerId, webCompanyId: companyId, webComputerId: computerId, webServiceOrder: completedServiceOrders }); 
      alert(webData); 

      alert("before compression is " + webData.length); 

      var URIEncodedWebData = encodeURIComponent(webData); 
      var JSONWebData = JSON.stringify(URIEncodedWebData); 

     var compressedWebData = LZString.compressToUTF16(JSONWebData); 

      alert("after compression is " + compressedWebData.length); 
      debugger; 

      try { 
       $.ajax({ 
        type: "POST", 
        url: "MFSRemoteDataService/REST_SendCompletedServiceOrders", 
        contentType: "application/json; charset=utf-8", 
        dataType: "json", 
        data: { compressedWebData: compressedWebData }, 
        success: function(data) { alert(JSON.stringify(data)); }, 
        failure: function(errMsg) { 
         alert(errMsg); 
        } 
       }); 
      } catch (e) { 
       alert(e); 
      } 

     }); 
}); 

До длины данных сжатия составляет 7707. После сжатия данных длина составляет 1831.

ance для любой помощи, обратной связи, критики и т. д.

+1

Как вы думаете, вы пытались увеличить свойство MaxJSONLength в web.config вашего WCF? –

+0

Да, я пробовал это

+1

Проблема в том, что вы не отправляете данные, а сколько WCF может принимать. см. [Похожие] (http://stackoverflow.com/questions/884235/wcf-how-to-increase-message-size-quota) – juanvan

ответ

0

Я понял свою проблему. Я пытался передать строку методу контракта, и я продолжал получать ошибки с ошибками. Вместо этого я завернул строку Json и отправил ее объекту вместо строки, созданной на сервере.

Я завернул JSON и послал его в теле запроса Аякса ..

var rawWebData = { 
      WebCustomerID: customerId, 
      WebCompanyID: companyId, 
      WebComputerID: computerId, 
      WebServiceOrders: completedServiceOrders 
     }; 
     var rawData = { webData: rawWebData }; 
     var webData = JSON.stringify(rawData); 
      try { 
       $.ajax({ 
        type: "POST", 
        url: "MFSRemoteDataService/REST_SendCompletedServiceOrders", 
        contentType: "application/json; charset=utf-8", 
        dataType: "json", 
        traditional: true, 
        data: webData, 
        success: function (data) { 
         alert(JSON.stringify(data)); 
        }, 
        failure: function (errMsg) { 
         alert(errMsg); 
        } 
       }); 
      } catch (e) { 
       alert(e); 
      } 

     }); 

Затем я создал класс для сбора данных ...

[DataContract] 
public class WebServiceOrder 
{ 
    [DataMember] 
    public Int32 WebCustomerID { get; set; } 

    [DataMember] 
    public Int32 WebCompanyID { get; set; } 

    [DataMember] 
    public Int32 WebComputerID { get; set; } 

    [DataMember] 
    public virtual List<ServiceOrder> WebServiceOrders { get; set; } 

} 

Затем я изменил метод контракта, чтобы принять объект, который я создал вместо строки. WCF десериализовал строку JSON.

 [OperationContract] 
    [WebInvoke(Method = "POST", 
     RequestFormat = WebMessageFormat.Json, 
     ResponseFormat = WebMessageFormat.Json, 
     UriTemplate = "REST_SendCompletedServiceOrders", 
     BodyStyle = WebMessageBodyStyle.WrappedRequest)] 
    [FaultContract(typeof (Exception))] 
    bool REST_SendCompletedServiceOrders(WebServiceOrder webData); 
2

В показанном фрагменте вы составляете данные ajax для использования в get, что обычно означает, что вы готовите uri. Тем не менее, поскольку он оба использует post и ajax, информация будет отправлена ​​в орган после запроса и, как таковая, не должна быть закодирована.

Кодировка раздувается строгим json. Вы можете остановиться в webdata и опубликовать это отдельно, удалите параметр dataType в параметрах ajax, переключитесь на использование traditional:true в параметрах ajax и все должно правильно привязать модель.

Трудно сказать, что ваш сервер вид сбоку модель выглядит, но если принимающий параметр называется compressedWebData (имена должны быть точным, то же самое происходит со структурой), то это вероятно, будет работать, как это

//code as shown in OP 
//replace var webData = with the following 
var compressedWebData = { webCustomerId: customerId, webCompanyId: companyId, webComputerId: computerId, webServiceOrder: completedServiceOrders }; 

try { 
    $.ajax({ 
     type: "POST", 
     url: "MFSRemoteDataService/REST_SendCompletedServiceOrders", 
     contentType: "application/json", 
     data: JSON.stringify(compressedWebData), 
     traditional:true, 
     success: function(data) { alert(JSON.stringify(data)); }, 
     failure: function(errMsg) { 
      alert(errMsg); 
     } 
    }); 
} catch (e) { 
    alert(e); 
} 
+0

Спасибо за ваш ответ. Первоначально я пытался использовать параметр body, но на сервере ничего не происходило (без точек останова), и я возвращал 400 ошибок. Поскольку я добирался до сервера с параметрами uri, я думал, что это был маршрут, поэтому я использовал кодировщик uri, потому что данные, которые я отправлял, усекались на сервере. Мне нужно выяснить, почему я получаю ошибку 400, потому что мне действительно нужно отправить данные через тело. –

+0

@JasonClark - Если вы установили точку останова на одном из ваших фильтров, попадает ли он в запрос ajax? –

+0

@JasonClark - Есть ли недопустимые символы в вашем завершенномServiceOrders? Можете ли вы опубликовать своего рода политую версию json? –

Смежные вопросы