この単純な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として返されます。 Jsonを返すWebサービスを取得するにはどうすればよいですか?
編集:
Fiddler HTTPトレースは次のとおりです。
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>
これを修正しようとして今読んだ記事の数を失いました。手順が不完全であるか、何らかの理由で問題が解決しません。関連性の高いものには次のものがあります(すべて成功なし)。
さらに、他のいくつかの一般的な記事。
最後にそれを理解しました。
アプリのコードは掲載されているとおりです。問題は構成にあります。正しい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に移動されているため、.NET 4以降ではハンドラを登録する必要はありません。何らかの理由で、これは私のために働いていません。しかし、私のアプリのweb.configに登録を追加すると、問題は解決しました。
この問題に関する多くの記事では、_<system.web>
_セクションにハンドラーを追加するように指示しています。これは機能せず、他の問題がすべて発生します。両方のセクションにハンドラーを追加しようとすると、他の移行エラーのセットが生成され、トラブルシューティングが完全に誤った方向に進みました。
それが他の誰かに役立つ場合、私が再び同じ問題を抱えていたら、ここに私がレビューするチェックリストがあります:
type: "POST"
_を指定しましたか?contentType: "application/json; charset=utf-8"
_を指定しましたか?dataType: "json"
_を指定しましたか?[ScriptService]
_属性が含まれていますか?[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
属性が含まれていますか? (私の属性はこの属性がなくても機能しますが、多くの記事で必須であると言われています)<system.webServer><handlers>
_のweb.configファイルにScriptHandlerFactory
を追加しましたか?<system.web><httpHandlers>
_のweb.configファイルからすべてのハンドラーを削除しましたか?これが同じ問題のある人を助けることを願っています。そして、提案のためのポスターに感謝します。
上記のソリューションでは成功しませんでしたが、ここでどのように解決しましたか。
この行をあなたのウェブサービスに入れて、代わりにタイプを返すだけで応答コンテキストに文字列を書く
this.Context.Response.ContentType = "application/json; charset=utf-8";
this.Context.Response.Write(serial.Serialize(city));
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);
}
}
Webサービスから純粋な文字列を返すはるかに簡単な方法があります。 CROW関数と呼びます(覚えやすくします)。
[WebMethod]
public void Test()
{
Context.Response.Output.Write("and that's how it's done");
}
ご覧のとおり、戻り値の型は「void」ですが、CROW関数は必要な値を返します。
文字列を返すメソッドを持つ.asmx Webサービス(.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);
}
});
これがお役に立てば幸いです。呼び出しているメソッドにパラメーターがない場合でも、リクエストで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;
});
私にとっては、この投稿から得たこのコードで動作します:
引用符で囲まれた文字列ではなく、Json.Netを使用して、WCFレストサービス(.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);
}
私はそれが本当に古い質問であることを知っていますが、今日同じ問題に遭遇し、答えを見つけるためにどこでも検索しましたが、結果はありませんでした。長い研究の後、私はこの仕事をする方法を見つけました。リクエストでデータを正しい形式で提供したサービスからJSONを返すには、JSON.stringify()
を使用してリクエストの前にデータを解析し、contentType: "application/json; charset=utf-8"
を忘れないでください。これを使用すると期待される結果が得られます。
上記のすべてのステップ(答えも)を試しましたが、成功しませんでした。システム構成はWindows Server 2012 R2ですIIS 8。
パイプライン=クラシックを管理しているアプリプールを変更しました。