ASP.NET MVC を使用してjQueryからJSONを投稿し、この小さなライブラリ関数を使用してJSONを取得します。
_(function($) {
$.postJson = function(url, data) {
return $.ajax({
url: url,
data: JSON.stringify(data),
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8'
});
};
})(jQuery);
_
だから明らかに私はこれを次のように呼びます:
_$('#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 MVC3とASP.NETMVC 4は、送信側をサポートしています(以前は、JSONの送信を処理するためにASP.NET MVCを拡張する必要がありました)が、私が直面している問題は戻ってきました。コントローラーでは、基本的に「成功、他に何も言うことはありません」と言うためにnullを返すことがよくあります。
_[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" });
}
_
私はこのパターンを頻繁に使用しますが、正常に機能します。成功/完了のコールバックが呼び出され、すべてが順調です。しかし最近、ASP.NET MVCとjQueryをアップグレードしたところ、機能しなくなりました。代わりに、return Json(null);
のたびにfailコールバックが呼び出されます。さらに、応答を調べたところ、返されるstatusCodeは実際には200であるため、サーバーに障害は発生していません。jQueryは障害が発生していると言っているだけです。
この問題は、jQuery1.8から1.9へのアップグレードが原因で発生しました。 jQuery 1.7および1.8では、MVCでは次のようになります。
_return Json(null);
_
有効なJSONとして受け入れられ、nullとして解釈されました。技術的には、これはHTTP 200を使用して空白の文字列をクライアントに送り返します。これは、jQuery <1.9の場合は十分です。
しかし、現在(jQuery 1.9.1を使用しています)、空の文字列をJSONとして解析しようとし、jQueryのJSONパーサーは空の文字列に例外をスローし、fail()
で終わるコードチェーンをトリガーします。代わりにコールバック。
回避策は、代わりに、他の情報なしで成功したときにサーバーからこれを返すことです。
_return Json(new{});
_
それはjQueryのJSONパーサーでマスターを通過し、すべてが順調です。これも機能します:
_return Json(true);
_
MVCによるこの動作の下のMusaノートは壊れているようです。これ ASP.NET MVC 3のデフォルトのJSONシリアライザーとしてJSON.NETを使用するに対する個別のスタックオーバーフローの回答-可能ですか? = Json(null)
に対してMVCがnullを返すようにする方法について説明します-基本的に、ASP.NETMVCの組み込みJSONシリアライザーの代わりにJson.NETを使用します。これは私が最終的に使用することになったソリューションです。
ただし、これを修正するには、その回答のわずかに変更されたバージョンを使用する必要があります-コードは以下のとおりです。基本的に、シリアル化に渡す前にnullをチェックするif
ステートメントを含めないでください。そうしないと、同じ苦境に戻ってしまいます。
Json.NETでのISO8601日付のデフォルトの実装は、new Date(...)
で解析しようとすると、 Internet Explorer 9 以下になります。つまり、これらはInternet Explorer9で正常に解析されます。
_var date = new Date('2014-09-18T17:21:57.669');
var date = new Date('2014-09-18T17:21:57.600');
_
しかし、これは例外をスローします:
_var date = new Date('2014-09-18T17:21:57.6');
_
Internet Explorer 9のDate()実装は、正確に3ミリ秒の場所以外には対応できません。これを修正するには、Json.NETの日付形式をオーバーライドして強制する必要があります。以下のコードに含まれています。
_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);
}
}
_
これをBaseControllerに結び付ける方法を示す要点:
https://Gist.github.com/b9chris/6991b341e89bb0a4e6d801d02dfd77