51

この単純なWebサービスがJSONをクライアントに返すことを拒否するのはなぜですか?

これが私のクライアントコードです:

        var params = { };
        $.ajax({
            url: "/Services/SessionServices.asmx/HelloWorld",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            timeout: 10000,
            data: JSON.stringify(params),
            success: function (response) {
                console.log(response);
            }
        });

そしてサービス:

namespace myproject.frontend.Services
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [ScriptService]
    public class SessionServices : System.Web.Services.WebService
    {
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
}

web.config:

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
</configuration>

そして応答:

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>

私が何をしても、応答は常にXMLとして返されます。WebサービスでJsonを返すにはどうすればよいですか?

編集:

FiddlerHTTPトレースは次のとおりです。

REQUEST
-------
POST http://myproject.local/Services/SessionServices.asmx/HelloWorld HTTP/1.1
Host: myproject.local
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://myproject.local/Pages/Test.aspx
Content-Length: 2
Cookie: ASP.NET_SessionId=5tvpx1ph1uiie2o1c5wzx0bz
Pragma: no-cache
Cache-Control: no-cache

{}

RESPONSE
-------
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 19 Jun 2012 16:33:40 GMT
Content-Length: 96

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>

これを修正しようとして今読んだ記事の数を失ってしまいました。手順が不完全であるか、何らかの理由で問題が解決しないかのいずれかです。より関連性の高いもののいくつかは次のとおりです(すべて成功しませんでした):

さらに、他のいくつかの一般的な記事。

4

10 に答える 10

48

ついにそれを理解した。

アプリコードは投稿されたとおりに正しいです。問題は構成にあります。正しいweb.configは次のとおりです。

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.webServer>
        <handlers>
            <add name="ScriptHandlerFactory"
                 verb="*" path="*.asmx"
                 type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                 resourceType="Unspecified" />
        </handlers>
    </system.webServer>
</configuration>

ドキュメントによると、ハンドラーはmachine.configに移動されているため、.NET4以降ではハンドラーの登録は不要です。どういうわけか、これは私にとってはうまくいきません。しかし、私のアプリのweb.configに登録を追加すると、問題は解決しました。

この問題に関する多くの記事は、ハンドラーを<system.web>セクションに追加するように指示しています。これは機能せず、他の多くの問題を引き起こします。両方のセクションにハンドラーを追加しようとしましたが、これにより、トラブルシューティングを完全に誤った方向に向けた他の一連の移行エラーが生成されます。

それが他の誰かを助ける場合に備えて、私が同じ問題を再び抱えていた場合、これが私がレビューするチェックリストです:

  1. type: "POST"ajaxリクエストで指定しましたか?
  2. contentType: "application/json; charset=utf-8"ajaxリクエストで指定しましたか?
  3. dataType: "json"ajaxリクエストで指定しましたか?
  4. .asmx Webサービスに[ScriptService]属性が含まれていますか?
  5. Webメソッドに[ScriptMethod(ResponseFormat = ResponseFormat.Json)] 属性が含まれていますか?(私のコードはこの属性がなくても機能しますが、多くの記事で必須と言われています)
  6. ScriptHandlerFactoryのweb.configファイルにを追加しました<system.webServer><handlers>か?
  7. のweb.configファイルからすべてのハンドラーを削除しました<system.web><httpHandlers>か?

これが同じ問題を抱えている人に役立つことを願っています。そして提案のためのポスターに感謝します。

于 2012-06-20T13:18:17.433 に答える
31

上記の解決策では成功しませんでした。ここで私はそれをどのように解決しましたか。

この行をWebサービスに入れて、タイプを返すのではなく、応答コンテキストで文字列を記述します

this.Context.Response.ContentType = "application/json; charset=utf-8";
this.Context.Response.Write(serial.Serialize(city));
于 2012-07-17T17:16:43.340 に答える
13

Framework 3.5を使い続けたい場合は、次のようにコードを変更する必要があります。

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
[ScriptService]
public class WebService : System.Web.Services.WebService
{
    public WebService()
    {
    }

    [WebMethod]
    public void HelloWorld() // It's IMP to keep return type void.
    {
        string strResult = "Hello World";
        object objResultD = new { d = strResult }; // To make result similarly like ASP.Net Web Service in JSON form. You can skip if it's not needed in this form.

        System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
        string strResponse = ser.Serialize(objResultD);

        string strCallback = Context.Request.QueryString["callback"]; // Get callback method name. e.g. jQuery17019982320107502116_1378635607531
        strResponse = strCallback + "(" + strResponse + ")"; // e.g. jQuery17019982320107502116_1378635607531(....)

        Context.Response.Clear();
        Context.Response.ContentType = "application/json";
        Context.Response.AddHeader("content-length", strResponse.Length.ToString());
        Context.Response.Flush();

        Context.Response.Write(strResponse);
    }
}
于 2013-09-08T13:46:05.957 に答える
7

Webサービスから純粋な文字列を返す簡単な方法があります。私はそれをCROW関数と呼んでいます(覚えやすくします)。

  [WebMethod]
  public void Test()
    {
        Context.Response.Output.Write("and that's how it's done");    
    }

ご覧のとおり、戻り値のタイプは「void」ですが、CROW関数は必要な値を返します。

于 2015-04-24T12:06:26.377 に答える
1

文字列を返すメソッドを持つ.asmxWebサービス(.NET 4.0)があります。文字列は、多くの例に見られるように、シリアル化されたリストです。これにより、XMLでラップされていないjsonが返されます。web.configに変更を加えたり、サードパーティのDLLを作成したりする必要はありません。

var tmsd = new List<TmsData>();
foreach (DataRow dr in dt.Rows)
{

m_firstname = dr["FirstName"].ToString();
m_lastname = dr["LastName"].ToString();

tmsd.Add(new TmsData() { FirstName = m_firstname, LastName = m_lastname} );

}

var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string m_json = serializer.Serialize(tmsd);

return m_json;

サービスを使用するクライアント部分は次のようになります。

   $.ajax({
       type: 'POST',
       contentType: "application/json; charset=utf-8",
       dataType: 'json',
       url: 'http://localhost:54253/TmsWebService.asmx/GetTombstoneDataJson',
       data: "{'ObjectNumber':'105.1996'}",
       success: function (data) {
           alert(data.d);
       },
       error: function (a) {
           alert(a.responseText);
       }
   });
于 2013-05-08T09:13:39.223 に答える
1

これがお役に立てば幸いです。呼び出しているメソッドにパラメーターがない場合でも、リクエストでJSONオブジェクトを送信する必要があるようです。

var params = {};
return $http({
        method: 'POST',
        async: false,
        url: 'service.asmx/ParameterlessMethod',
        data: JSON.stringify(params),
        contentType: 'application/json; charset=utf-8',
        dataType: 'json'

    }).then(function (response) {
        var robj = JSON.parse(response.data.d);
        return robj;
    });
于 2017-09-29T09:52:34.590 に答える
0

私にとっては、この投稿から取得したこのコードで動作します:

Json.Netを使用して、引用符で囲まれた文字列なしで、WCF Restサービス(.NET 4)からjsonを返すにはどうすればよいですか?

[WebInvoke(UriTemplate = "HelloWorld", Method = "GET"), OperationContract]
public Message HelloWorld()
{
    string jsonResponse = //Get JSON string here
    return WebOperationContext.Current.CreateTextResponse(jsonResponse, "application/json; charset=utf-8", Encoding.UTF8);
}
于 2012-06-18T18:01:55.787 に答える
0

上記のすべての手順(答えも含む)を試しましたが、成功しませんでした。システム構成はWindows Server 2012 R2、IIS8です。次の手順で問題が解決しました。

パイプライン=クラシックを管理しているアプリプールを変更しました。

于 2014-04-09T14:39:11.167 に答える
0

私はそれが本当に古い質問であることを知っています、しかし私は今日同じ問題に遭遇しました、そして私は答えを見つけるために至る所で探していました、しかし結果はありませんでした。長い研究の結果、私はこの仕事をする方法を見つけました。リクエストでデータを正しい形式で提供しているサービスからJSONを返すには、リクエストの前にデータを解析するために使用します。これを使用すると、期待どおりの結果が得られることをJSON.stringify()忘れないでください。contentType: "application/json; charset=utf-8"

于 2017-03-23T10:47:31.613 に答える
-1
response = await client.GetAsync(RequestUrl, HttpCompletionOption.ResponseContentRead);
if (response.IsSuccessStatusCode)
{
    _data = await response.Content.ReadAsStringAsync();
    try
    {
        XmlDocument _doc = new XmlDocument();
        _doc.LoadXml(_data);
        return Request.CreateResponse(HttpStatusCode.OK, JObject.Parse(_doc.InnerText));
    }
    catch (Exception jex)
    {
        return Request.CreateResponse(HttpStatusCode.BadRequest, jex.Message);
    }
}
else
    return Task.FromResult<HttpResponseMessage>(Request.CreateResponse(HttpStatusCode.NotFound)).Result;
于 2015-05-17T10:17:45.953 に答える