web-dev-qa-db-ja.com

httpget webmethod(c#)へのJQueryajax呼び出しが機能しない

コードビハインドでajaxをwebmethodに取得しようとしています。問題は、jQuery onfailメソッドからエラー「parserror」が発生し続けることです。

GETをPOSTに変更すると、すべて正常に機能します。以下のコードを参照してください。

Ajax Call

<script type="text/javascript">
        var id = "li1234";

        function AjaxGet() {
            $.ajax({
                type: "GET",
                url: "webmethods.aspx/AjaxGet",
                data: "{ 'id' : '" + id + "'}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                async: false,
                success: function(msg) {
                    alert("success");

                },
                error: function(msg, text) {
                    alert(text);
                }
            });
        }

    </script>

コードビハインド

[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod(UseHttpGet = true,
    ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)] 
public static string AjaxGet(string id)
{
    return id;
}

Web.config

        <webServices>
            <protocols>
                <add name="HttpGet"/>
            </protocols>
        </webServices>

使用されているURL

......../webmethods.aspx/AjaxGet?{%20%27id%27%20:%20%27li1234%27}

応答の一部として、ページwebmethodsのhtmlを返します。

どんな助けでも大歓迎です。

13
Tim Jarvis

何よりもまず、あなたは最も簡単な方法ではないことを選択します。 ScriptMethodsは、jQueryではなくASP.NETScriptManagerと一緒に使用するのが簡単です。現在使用しようとしているASMXWebサービスではなく、JSON対応のWCF HTTPサービス(RESTfullサービスとしてより適切)を使用することをお勧めします。それでも、クライアント側でMicrosoftテクノロジを使用しなくても、コードを機能させることができます。

まず、サーバー側を確認します。

  1. Webmethods.aspxの名前をwebmethods.asmxに変更します。
  2. Inside of \を配置し、asmx拡張機能のhttpHandlers(ScriptHandlerFactory)も構成に存在することを確認します。

    <configuration>
      <!-- ... -->
      <system.web>
        <webServices>
          <protocols>
            <add name="HttpGet"/>
          </protocols>
        </webServices>
        <httpHandlers>
          <!-- ... -->
          <add verb="*" path="*.asmx"
               type="System.Web.Script.Services.ScriptHandlerFactory"
               validate="false"/>
        </httpHandlers></system.web></configuration>
    
  3. System.Web.Services.WebServiceから継承されたクラスに[ScriptService]属性(フルネームが必要な場合は[System.Web.Script.Services.ScriptService])が設定されていることを確認します。

これで、サービスをテストできます。次のようなWebブラウザのURLを開きます http://localhost/webmethods.asmx/AjaxGet?id = li1234 次のようなものを受け取った場合
<?xml version="1.0" encoding="utf-8" ?>
<string xmlns="http://tempuri.org/">li1234</string>

あなたはあなたのサービス部分がうまく働くことを確信することができます。

備考:「ResponseFormat = System.Web.Script.Services.ResponseFormat.Json」属性に依存して、「Content-Type: application/json;」リクエストに設定されていません。

次に、クライアントコードを修正します。私が次のコードに置いたコメントがすべてを説明することを願っています。

もう1つの小さな発言。コードの最後の部分では、もう1つの「複雑な」Webメソッドを呼び出します。

[WebMethod]
[ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public OutputData AjaxGetMore (InputData input) {
    return new OutputData () {
        id = input.id,
        message = "it's work!",
        myInt = input.myInt+1
    };
}

どこ

public class OutputData {
    public string id { get; set; }
    public string message { get; set; }
    public int myInt { get; set; }
}
public class InputData {
    public string id { get; set; }
    public int myInt { get; set; }
}

現在、JSONプラグインを使用するJavaScriptコードのみが使用されています。これは、誰かが好む場合は、Crockfordのjson2.jsに置き換えることができます。

var id = "li1234";
// version 1 - works
var idAsJson = '"' + id + '"';  // string serializes in JSON format
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGet?id=" + idAsJson,
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        alert(msg.d);   // var msg = {d: "li1234"} 
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});

// version 2 with respect of JSON plugin
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGet?id=" + $.toJSON(id),
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        alert(msg.d);   // var msg = {d: "li1234"} 
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});
// version 3 where jQuery will construct URL for us
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGet",
    data: {id: $.toJSON(id)},
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        alert(msg.d);   // var msg = {d: "li1234"} 
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});
// version 4. We set "Content-Type: application/json" about our data, but we use no 
//            not 'dataType: "json"' parameter. Then we have "Accept: */*" in the request
//            instead of "Accept: application/json, text/javascript, */*" before.
//            Everithing work OK like before.
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGet",
    data: {id: $.toJSON(id)},
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        alert(msg.d);   // var msg = {d: "li1234"} 
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});
// version 5. If we don't place "Content-Type: application/json" in our reqest we
//            receive back XML (!!!) response with "HTTP/1.1 200 OK" header and 
//            "Content-Type: text/xml; charset=utf-8" which will be placed.
//            How one can read in
// http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx),
//             ASP.NET AJAX will not make JSON serialized of response data for
//             security reasons.
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGet",
    data: {id: $.toJSON(id)},
    dataType: "json",
    //contentType: "application/json; charset=utf-8",
    success: function(msg) {
        alert(msg.d);   // var msg = {d: "li1234"} 
    },
    error: function (res, status, ex) {
        // the code here will be works because of error in parsing server response
        if (res.status !== 200) {   // if not OK
            // we receive exception in the next line, be
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        } else {
            alert("status=" + status + "\nex=" + ex + "\nres.status=" + res.status + "\nres.statusText=" + res.statusText +
                    "\nres.responseText=" + res.responseText);
        }
    }
});
// version 6. Send more komplex data to/from the service
var myData = { id: "li1234", myInt: 100}
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGetMore",
    data: {input:$.toJSON(myData)},
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        // var msg = {__type: "Testportal.OutputData", id: "li1234", message: "it's work!", myInt:101}
        alert("message=" + msg.d.message + ", id=" + msg.d.id + ", myInt=" + msg.d.myInt); 
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});
23
Oleg

私は答えを探してここに来ました...他の人のために、ここに答えがあります。

セキュリティ上の理由から、ASP.Net AJAXページメソッドはPOSTリクエストのみをサポートします。

https://stackoverflow.com/a/2397521 から)

5
user3927354
//...
data: { "id" : id },
//...

データはオブジェクトであり、オブジェクトのように見える文字列ではありません。

文字列を使用する場合は、次のように正しくフォーマットされたURLクエリ文字列である必要があります。

//...
data: "id=" + encodeURIComponent(id) + "&otherstuff=" + encodeURIComponent(data),
//...
2
Tomalak

http://www.json.org/js.html JSON.stringifyをチェックアウトすることもできます。ここでは、パラメーターとしてjsonオブジェクトを受け入れ、文字列を返します。

1
Milo Cabs

VBを使用している場合は、次のようにメソッドを装飾します。

<WebMethod()>
<ScriptMethod(UseHttpGet:= True, ResponseFormat:= ResponseFormat.Json)>
0
CBarr