2013-04-11 21 views
14

używam ASP.NET MVC odpowiedzieć JSON z jQuery, JSON i trochę do tyłu, przy użyciu tej funkcji trochę Biblioteka:jQuery po JSON nie po powrocie zerowy z ASP.NET MVC

(function($) { 
    $.postJson = function(url, data) { 
     return $.ajax({ 
      url: url, 

      data: JSON.stringify(data), 
      type: 'POST', 
      dataType: 'json', 
      contentType: 'application/json; charset=utf-8' 
     }); 
    }; 
})(jQuery); 

Tak oczywiście to zadzwonię jak:

$('#button').click(function() { 
    $.postJson('/controller/action', { Prop1: 'hi', Prop2: 'bye' }) 
    .done(function(r) { alert('It worked.'); }) 
    .fail(function(x) { alert('Fail! ' + x.status); }); 
}); 

ASP.NET MVC 3 i ASP.NET MVC 4 wsparcie przedstawić stronę rzeczy (przed, że potrzebne do rozszerzenia ASP.NET MVC do obsługi składania JSON), ale problem biegnę do jest po powrocie. Na kontrolerze często zwróci null w zasadzie powiedzieć „Sukces, nic innego do powiedzenia,” jak:

[HttpPost] 
public JsonResult DoSomething(string Prop1, string Prop2) 
{ 
    if (doSomething(Prop1, Prop2) 
     return Json(null); // Success 

    return Json(new { Message = "It didn't work for the following reasons" }); 
} 

Używam tego wzoru często i to działa dobrze - mój sukces/zrobić zwrotna jest wywoływana i wszystko jest dobrze. Ale ostatnio uaktualniłem ASP.NET MVC i jQuery, i to przestało działać - zamiast tego moje niepowodzenie wywołania zwrotnego jest wywoływane za każdym razem, gdy I return Json(null);. Ponadto sprawdziłem odpowiedź, a zwracany kod statusu jest w rzeczywistości 200, więc serwer nie zawodzi - jQuery tylko to mówi.

+1

BTW globalny '$ (document) .ajaxError ...' 'exception.message' przedstawia" ** Nieoczekiwany koniec wejścia ** "gdy zwróci się' Json (null) '(żeby o tym wspomnieć, nie pomogło mi znaleźć przyczyny problemu). – Slauma

Odpowiedz

35

Problem został spowodowany przez uaktualnienie z jQuery 1.8 do 1.9. W jQuery 1.7 i 1.8 to w MVC:

return Json(null); 

został przyjęty jako poprawny JSON i interpretowany jako zerowy. Technicznie, to wysyła pusty ciąg z powrotem do klienta z HTTP 200, i to jest wystarczająco dobre dla jQuery < 1.9.

Ale teraz (używamy jQuery 1.9.1), próbuje sparsować pusty ciąg jako JSON, parser JSQL jQuery rzuca wyjątek na pusty ciąg, a to wyzwala łańcuch kodu, który kończy się wywoływaniem zwrotnym fail() .

Rozwiązaniem jest zamiast przekazać te z serwera na sukces bez INNE INFORMACJE:

return Json(new{}); 

który przechodzi wykrzesać z jQuery parsera JSON jest i wszystko jest dobrze. Działa to również:

return Json(true); 


Aktualizacja

Musa zauważa poniżej to zachowanie przez MVC wydaje złamany. Ten separate Stack Overflow answer to Using JSON.NET as the default JSON serializer in ASP.NET MVC 3 - is it possible? opisuje, jak zmusić MVC do zwrócenia wartości null dla Json(null) - w zasadzie użyć Json.NET zamiast wbudowanego serializatora JSON programu ASP.NET MVC. To jest rozwiązanie, które ostatecznie wykorzystałem.

Musisz użyć nieco zmodyfikowanej wersji tej odpowiedzi, aby to naprawić - kod jest poniżej. Zasadniczo, nie dołączaj oświadczenia if sprawdzającego wartość zerową przed przejściem do serializacji lub wracasz do tej samej sytuacji.


Aktualizacja 2

Domyślna implementacja ISO 8601 Daty w Json.NET łamie Internet Explorer 9 i poniżej, kiedy próbuje zanalizować go z new Date(...).Innymi słowy, te analizować porządku w Internecie   Explorer   9:

var date = new Date('2014-09-18T17:21:57.669'); 
var date = new Date('2014-09-18T17:21:57.600'); 

Ale to zgłasza wyjątek:

var date = new Date('2014-09-18T17:21:57.6'); 

Internet   Explorer   9 data() realizacja nie może poradzić sobie z niczego, ale dokładnie trzy milisekundy. Aby to naprawić, musisz zastąpić format daty Json.NET, aby go wymusić. Zawarty w kodzie poniżej.

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

     var response = context.HttpContext.Response; 

     response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType : "application/json"; 

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

     var settings = new JsonSerializerSettings 
     { 
      Converters = new[] {new IsoDateTimeConverter 
      { 
       DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffK" 
      }} 
     }; 
     var jsonSerializer = JsonSerializer.Create(settings); 

     jsonSerializer.Serialize(response.Output, Data); 
    } 
} 

GIST, który pokazuje, jak powiązać to do BaseController:

https://gist.github.com/b9chris/6991b341e89bb0a4e6d801d02dfd7730

+0

'return Json (null);' zwracanie pustego łańcucha brzmi zepsute, powinno zwrócić 'null' – Musa

+0

@Musa Prawdopodobnie, chociaż w tym momencie może to być również zmiana łamania - poszedłem kopać i wygląda na to, że zwrócił puste ciąg znaków dla wartości null od pierwszych dni MVC. Zgadzam się, że może to być czystsze rozwiązanie tego problemu. Ta odpowiedź obejmuje to, mimo że przykładowy kod sprawdza wartość pustą i zwraca pusty ciąg znaków, zanim Json.Net może uzyskać do niego dostęp - usuń te 2 linie, a otrzymasz zerową wartość zwracaną. http://stackoverflow.com/a/7150912/176877 –

Powiązane problemy