jsonの解析エラー シンタックスエラー unexpected end of input

次のようなコードが表示されました。

function pushJsonData(productName) {
    $.ajax({
        url: "/knockout/SaveProduct",
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: " { \"Name\" : \"AA\" } ",
        async: false,
        success: function () {
            loadJsonData();   
        },
        error: function (jqXHR, textStatus, errorThrown) {
          alert(textStatus + " in pushJsonData: " + errorThrown + " " + jqXHR);
        }
    });
}

データの値をハードコードしていることに注意してください。データは問題なくデータベースに入ります。しかし、"parsing error syntax error unexpected end of input"というエラーがずっと出ています。私のデータは正しいJSON構文であることは確認しています。ChromeインスペクタのNetworkで確認したところ、saveProductリクエストではデータが正しく表示されていました。

{ "Name": "AA" }

このPOSTリクエストにはレスポンスがありませんでした。そのため、どこでパースエラーが発生しているのかがわかりません。FireFoxのブラウザを使ってみましたが、同じことが起こりました。

何が問題なのか、どなたか教えてください。

ありがとうございます。

P.S. コントローラのコードは以下の通りです。

namespace MvcApplJSON.Controllers
{
    public class KnockoutController : Controller
    {
        //
        // GET: /Knockout/

        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public JsonResult GetProductList()
        {
            var model = new List<Product>();
            try
            {
                using (var db = new KOEntities())
                {
                    var product = from p in db.Products orderby p.Name select p;
                    model = product.ToList();
                }
            }
            catch (Exception ex)
            { throw ex; }
            return Json(model, JsonRequestBehavior.AllowGet);
        }
        [HttpPost]
        public void SaveProduct (Product product)
        {
            using (var db = new KOEntities())
            {
                db.Products.Add(new Product { Name = product.Name, DateCreated = DateTime.Now });
                db.SaveChanges();
            }
        }
    }
}
ソリューション

何が問題なのか、はっきりとは言えません。文字化けかもしれませんし、最初と最後に空けたスペースかもしれませんし、わかりません。

いずれにしても、あなたのようにJSONを文字列としてハードコードするべきではありません。JSONデータをサーバーに送信する適切な方法は、JSONシリアライザーを使用することです。

data: JSON.stringify({ name : "AA" }),

サーバ側では、この入力を受け取るための適切なビューモデルがあることを確認してください。

public class UserViewModel
{
    public string Name { get; set; }
}

と対応するアクションがあることを確認します。

[HttpPost]
public ActionResult SaveProduct(UserViewModel model)
{
    ...
}

ここで、もう一つあります。あなたはdataType: 'json'を指定しています。これは、サーバーがJSONの結果を返すことを期待しているということです。コントローラのアクションは、JSONを返さなければなりません。コントローラアクションがビューを返す場合、これが取得しているエラーの説明になります。これは、jQueryがサーバーからのレスポンスを解析しようとしたときに発生します。

[HttpPost]
public ActionResult SaveProduct(UserViewModel model)
{
    ...
    return Json(new { Foo = "bar" });
}

とはいえ、ほとんどの場合、ASP.NET MVCのコントローラアクションにAJAXリクエストを行う際に、dataTypeプロパティを設定する必要はありません。その理由は、特定のActionResultViewResultJsonResultなど)を返すと、フレームワークが自動的に正しいContent-TypeレスポンスHTTPヘッダーを設定するからです。 jQueryは、このヘッダーを使用してレスポンスを解析し、すでに解析されたサクセスコールバックのパラメーターとして供給します。

ここでの問題は、サーバーが有効なJSONを返さなかったことが原因ではないかと思います。ViewResultやPartialViewResultが返されたか、コントローラのアクションで壊れたJSONを手動で作成しようとしたかのどちらかだと思います(もちろん、JsonResultを代わりに使うべきではありません)。

もうひとつ、気になったことがあります。

async: false,

この属性をfalseに設定することは避けてください。この属性を false に設定すると、リクエストの実行中にクライアントのブラウザをフリーズさせることになります。この場合、通常のリクエストを行うことができます。もしAJAXを使いたいのであれば、非同期イベントやコールバックの観点から考え始めましょう。

解説 (10)

ノードの http リクエストを使い、data イベントをリッスンしていました。 このイベントは、データを一時的にバッファに入れるだけなので、完全なJSONは得られません。 修正するには、各 data イベントを変数に追加しなければなりません。誰かの役に立つかもしれません(http://nodejs.org/api/http.html)。

解説 (0)

私の場合は、名前と値のペアに一重引用符が使われていることが原因でした...。 data: "{'Name':'AA'}"

名前と値のペアを二重引用符で囲むように変更したら、問題なく動作しました... data: '{"Name":"AA"}' あるいは、次のようになります... data: "{\"Name\":\"AA\"}"

解説 (1)