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"
}
変数json
には何が含まれているのでしょうか
var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);?
{'foo':'foovalue', 'bar':'barvalue'}
のような有効なjsonオブジェクトの場合、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サーバー側を解析できるようにします。
を使用して
data : JSON.stringify(obj)
上記の状況ではうまくいくと思います。
注:すべてのブラウザがそのJSONオブジェクト(IE7-)をサポートしていないjson2.jsライブラリを追加する必要があります json.jsとjson2.jsの違い
ジッターで述べたように、$.ajax
関数は、data
パラメーターとして使用されるオブジェクト/配列をURLエンコード形式にシリアル化します。奇妙なことに、dataType
パラメーターはサーバーからの応答にのみ適用され、リクエスト内のデータには適用されません。
同じ問題に遭遇した後、 jquery-json plugin をダウンロードして使用し、リクエストデータをScriptServiceに正しくエンコードしました。次に、$.toJSON
関数を使用して、サーバーに送信する目的の引数をエンコードしました。
$.ajax({
type: "POST",
url: "EditUserProfile.aspx/DeleteRecord",
data: $.toJSON(obj),
contentType: "application/json; charset=utf-8",
dataType: "json"
....
});
それはこのように働いています
data: JSON.stringify({'id':x}),
Jquery Ajaxは、デフォルトで次のようなクエリ文字列パラメーター形式でデータを送信します。
RecordId=456&UserId=123
processData
オプションがfalseに設定されていない限り、その場合はオブジェクトとしてサーバーに送信されます。
contentType
オプションは、フォーマットクライアントがデータを送信したサーバー用です。
dataType
オプションは、サーバーから返されるデータクライアントの種類を通知するサーバー用です。
サーバーがJSONではなくクエリ文字列パラメーターとして解析するように、contentTypeを指定しないでください。
または
ContentTypeを 'application/json;として使用します。 charset = utf-8 'とJSON.stringify(object)を使用して、サーバーがJSONを文字列から逆シリアル化できるようにします。
@jitterは彼の推測に正しかったと思いますが、彼の解決策はうまくいきませんでした。
動作したのは次のとおりです。
$.ajax({
...
data: "{ intFoo: " + intFoo + " }",
...
});
試したことはありませんが、parametterが文字列の場合、次のようになります。
$.ajax({
...
data: "{ intFoo: " + intFoo + ", strBar: '" + strBar + "' }",
...
});
私は同じ問題に直面していましたが、良い解決策は次のとおりです:
これを試して...
$.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");
}
});
ここで、文字列型パラメーターについては、文字列値としてそれを示すために(\ ')エスケープシーケンス文字を使用していることに注意してください。
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"
}
サーバーで、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;
}