Ajax処理の「無効なJSONプリミティブ」


101

jQueryからのajax呼び出しでエラーが発生します。

ここに私のjQuery関数があります:

function DeleteItem(RecordId, UId, XmlName, ItemType, UserProfileId) {
    var obj = {
        RecordId: RecordId,
        UserId: UId,
        UserProfileId: UserProfileId,
        ItemType: ItemType,
        FileName: XmlName
    };
    var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);

    $.ajax({
        type: "POST",
        url: "EditUserProfile.aspx/DeleteRecord",
        data: json,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        async: true,
        cache: false,
        success: function(msg) {
            if (msg.d != null) {
                RefreshData(ItemType, msg.d);
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert("error occured during deleting");
        }
    });
}

そしてこれは私のWebMethodです:

[WebMethod]
public static string DeleteRecord(Int64 RecordId, Int64 UserId, Int64 UserProfileId, string ItemType, string FileName) {
    try {
        string FilePath = HttpContext.Current.Server.MapPath(FileName);

        XDocument xmldoc = XDocument.Load(FilePath);
        XElement Xelm = xmldoc.Element("UserProfile");
        XElement parentElement = Xelm.XPathSelectElement(ItemType + "/Fields");

        (from BO in parentElement.Descendants("Record")
         where BO.Element("Id").Attribute("value").Value == RecordId.ToString()
         select BO).Remove();
        XDocument xdoc = XDocument.Parse(Xelm.ToString(), LoadOptions.PreserveWhitespace);
        xdoc.Save(FilePath);

        UserInfoHandler obj = new UserInfoHandler();
        return obj.GetHTML(UserId, UserProfileId, FileName, ItemType, RecordId, Xelm).ToString();
    } catch (Exception ex) {
        HandleException.LogError(ex, "EditUserProfile.aspx", "DeleteRecord");
    }
    return "success";
}

誰かが私のコードのどこが悪いのか教えてくれますか?

このエラーが発生しています:

{
    "Message":"Invalid JSON primitive: RecordId.",
    "StackTrace":"
       at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()
       at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
       at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)
       at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)
       at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)
       at System.Web.Script.Services.RestHandler.GetRawParamsFromPostRequest(HttpContext context, JavaScriptSerializer serializer)
       at System.Web.Script.Services.RestHandler.GetRawParams(WebServiceMethodData methodData, HttpContext context)
       at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)",
    "ExceptionType":"System.ArgumentException"
}

わからないのは。JavaScriptはAddAlbumToMyProfileに関するもので、WebMethodはDeleteRecordと呼ばれます。正しいコードを表示してよろしいですか?
ジッタ

(firebugまたはwhatnotを使用して)POSTがどのように見えるかをキャプチャして質問に追加することもできますか?送信する前にデータをエンコードする方法であるかどうかはわかりませんが、this(json.org/json2.js)を使用してシリアル化することもできます。
R0MANARMY

回答:


135

変数jsonが後に何を含むかを推測するだけです

var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);?

それがそのような有効なjsonオブジェクトである場合{'foo':'foovalue', 'bar':'barvalue'}、jQueryはそれをjsonデータとして送信せず、代わりにそれをシリアル化しfoor=foovalue&bar=barvalueてエラーを得るかもしれません"Invalid JSON primitive: foo"

代わりにデータを文字列として設定してみてください

$.ajax({
    ...
    data: "{'foo':'foovalue', 'bar':'barvalue'}", //note the additional quotation marks
    ...
})

この方法では、jQueryはデータをそのままにして、文字列をそのままサーバーに送信し、ASP.NETがjsonサーバー側を解析できるようにする必要があります。


5
明確化に感謝し、もう1つのコメントを追加します。JSON.stringify({foo: 'foovalue'、bar: 'barvalue'})のようにいつでも行うことができます
Elaine

パーティーに10年遅れましたが、それでも関連があります。それは有効なJSONではありません。JSONの文字列(プロパティ名を含む)は二重引用符を使用する必要があるため、でなければなりません{"foo": "foovalue", "bar": "barvalue"}。単一引用符を使用すると、構文エラーになります。
Mike 'Pomax' Kamermans

108

使用する

data : JSON.stringify(obj)

上記の状況で私は信じていたでしょう。

注:json2.jsライブラリーを追加する必要があります。すべてのブラウザーがそのJSONオブジェクトをサポートしていない(IE7-) json.jsとjson2.jsの違い


3
ありがとう!単純なJSクラスを使用する場合、これは機能します。私は変更data: { JSON.stringify(obj) }data: JSON.stringify(obj)(シリアル化するために私のjavascript / JSONクラスはスタイルのあるvar myObj = { title: "x", subclass = someVar, ... }
LKO

1
これは、JSONを実際に送信する必要がある場合のソリューションです(asp.net Webサービスで使用する場合があります)。他の場合では、単にを削除しcontentTypeて、jQueryにフォームエンコードされたデータを渡させる方が簡単な場合があります。
GSerg 2017年

19

ジッタで指摘されているように、この$.ajax関数は、dataパラメーターとして使用されるオブジェクト/配列をURLエンコード形式にシリアル化します。奇妙なことに、dataTypeパラメーターはサーバーからの応答にのみ適用され、要求内のデータには適用されません。

同じ問題が発生した後、jquery-jsonプラグインをダウンロードして使用し、リクエストデータをScriptServiceに正しくエンコードしました。次に、$.toJSON関数を使用して、サーバーに送信する必要な引数をエンコードします。

$.ajax({
    type: "POST",
    url: "EditUserProfile.aspx/DeleteRecord",
    data: $.toJSON(obj),
    contentType: "application/json; charset=utf-8",
    dataType: "json"
    ....
});

2
dataパラメータが呼び出しによって無視されることを指摘してくれてありがとう。
ノエルアブラハム

3
これは機能しますが、データエンコードに関するポイントのおかげで、JavaScriptクラスがスタイルである場合は、機能するように変更さdata: { JSON.stringify(obj) }data: JSON.stringify(obj)ましたvar myObj = { title: "x", subclass = someVar, ... }
lko

19

それはこのようなものを働いています

data: JSON.stringify({'id':x}),

3
この回答は、おそらくコードの説明を提供しなかったために、低品質のレビューキューで判明しました。このコードが質問に回答する場合は、回答にコードを説明するテキストを追加することを検討してください。このようにして、あなたはより多くの賛成票を獲得し、質問者が何か新しいことを学ぶのを助ける可能性がはるかに高くなります。
lmo 2016

複雑なオブジェクトの配列と整数の2つのパラメーターを渡します。データ:{items:JSON.stringify(myarray)、myId:value}。
A.Dara

回答を投稿していただきありがとうございます。これは私のために働いた。
ZMAX

13

Jquery Ajaxはデフォルトで次のようなクエリ文字列パラメーター形式でデータを送信します。

RecordId=456&UserId=123

processDataオプションがfalseに設定されていない限り、オブジェクトとしてサーバーに送信されます。

  • contentType オプションは、クライアントがデータを送信したサーバーの形式です。

  • dataType オプションはサーバー用で、サーバーから返されるデータクライアントのタイプを通知します。

サーバーがそれらをjsonではなくクエリ文字列パラメーターとして解析するようにcontentTypeを指定しないでください。

または

contentTypeを 'application / json;として使用します。charset = utf-8 'とJSON.stringify(object)を使用して、サーバーが文字列からjsonをデシリアライズできるようにします。


5

彼の推測では@jitterは正しかったと思いますが、彼の解決策は私にはうまくいきませんでした。

これが機能したことです:

$.ajax({
    ...
    data: "{ intFoo: " + intFoo + " }",
    ...
});

私は試していませんが、parametterが文字列の場合、次のようになるはずです。

$.ajax({
    ...
    data: "{ intFoo: " + intFoo + ", strBar: '" + strBar + "' }",
    ...
});

9
JSONオブジェクトを作成するためにそのようなコード(文字列連結)を記述する必要があった場合、(比喩的に言えば)自分を殺してしまいます。より良い方法が必要です。
PandaWood 2013

3

私は同じ問題に直面していました、私が良い解決策を持っているのは以下の通りです:

これを試して...

$.ajax({
    type: "POST",
    url: "EditUserProfile.aspx/DeleteRecord",
    data: '{RecordId: ' + RecordId + ', UserId: ' + UId + ', UserProfileId:' + UserProfileId + ', ItemType: \'' + ItemType + '\', FileName: '\' + XmlName + '\'}',
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    async: true,
    cache: false,
    success: function(msg) {
        if (msg.d != null) {
            RefreshData(ItemType, msg.d);
        }
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert("error occured during deleting");
    }
});

文字列型のパラメーターについては、文字列値としてそれを示すために(\ ')エスケープシーケンス文字を使用したことに注意してください。


データ: "{Notes:\" "+ $( '#txtNotes')。val()+" \ "}
bestinamir

1

JSONを手動でフォーマットする場合は、jsonlint.comに非常に便利なバリデーターがあります。

一重引用符の代わりに二重引用符を使用します。

無効:

{
    'project': 'a2ab6ef4-1a8c-40cd-b561-2112b6baffd6',
    'franchise': '110bcca5-cc74-416a-9e2a-f90a8c5f63a0'
}

有効:

{
    "project": "a2ab6ef4-1a8c-40cd-b561-2112b6baffd6",
    "franchise": "18e899f6-dd71-41b7-8c45-5dc0919679ef"
}

0

サーバーで、jsonをカスタムオブジェクトにシリアル化/非シリアル化するには:

public static string Serialize<T>(T obj)
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    MemoryStream ms = new MemoryStream();
    serializer.WriteObject(ms, obj);
    string retVal = Encoding.UTF8.GetString(ms.ToArray());
    return retVal;
}

public static T Deserialize<T>(string json)
{
    T obj = Activator.CreateInstance<T>();
    MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    obj = (T)serializer.ReadObject(ms);
    ms.Close();
    return obj;
}

0

同じ問題がありました。ポップアップウィンドウを閉じて、親ページを「保存」と呼んでいました。ClientIDMode="Static"同じコントロールIDで親ページとポップアップページの両方で使用していることがわかりました。ClientIDMode="Static"いずれかのページから削除すると、問題が解決しました。


0

ここでdataTpeは「json」なので、APIを呼び出すとき、data / reqParamは文字列の形式である必要があります。好きなだけ多くのオブジェクトを指定できますが、最後に$ .ajaxのデータ内でオブジェクトを文字列化します。

             let person= {  name: 'john',
                age: 22
            };

           var personStr = JSON.stringify(person); 

            $.ajax({
                url: "@Url.Action("METHOD", "CONTROLLER")",
                type: "POST",
                data: JSON.stringify( { param1: personStr } ),
                contentType: "application/json;charset=utf-8",
                dataType: "json",
        success: function (response) {

            console.log("Success");

        },
        error: function (error) {
            console.log("error found",error);
        }
    });

または、

       $.ajax({
                url: "@Url.Action("METHOD", "CONTROLLER")",
                type: "POST",
                data: personStr,
                contentType: "application/json;charset=utf-8",
                dataType: "json",
        success: function (response) {

            console.log("Success");

        },
        error: function (error) {
            console.log("error found",error);
        }
    });

-2

これらの答えは、無効なパラメーターと欠落しているパラメーターの間を行き来するだけでした。

これは私にとってはうまくいきました、文字列変数を引用符で囲むだけです...

data: { RecordId: RecordId,
            UserId: UId,
            UserProfileId: UserProfileId,
            ItemType: '"' +  ItemType + '"',
            FileName: '"' +  XmlName + '"'
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.