我的開發環境和Project架構都很簡單 :
- VWD 2010
- ASP.NET 4.0
- jQuery 1.4.4
- JSON.NET
- ASP.NET內建的Dev Server
- CodePlex上的CassiniDev
System.InvalidOperationException: Request format is unrecognized for URL unexpectedly ending in '/getRecords'.來看看Code部份:
System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response)
System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context, String verb, String url, String filePath)
System.Web.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
function getRecords(RecordID) { $.ajax({ type: "POST", url: "WebService/ClientCallBack.asmx/getRecords", data: "{ 'RecordID': '" + RecordID + "' }", contentType: "application/json; charset=utf-8", dataType: "json", success: function (msg) { var json = JSON.parse(msg.d); $.each(json, function (idx, item) { alert(json[idx].Title); //Do Something Else }); }, error: function (err) { alert("error : " + err.responseText); } }); }
using Newtonsoft.Json; [WebMethod] public string getRecords(int RecordID) { List<DataContractClass.Records> jsonlist = new List<DataContractClass.Records>(); DataContractClass.Records r = null; using (ReferralDBEntities de = new ReferralDBEntities()) { int id = 0; var records = from pack in de.ReferralPackages where pack.RecordID == RecordID orderby pack.CreatedDate descending select pack, item; foreach (var rec in records) { r = new DataContractClass.PatientRecords(); r.PackageID = rec.pack.PackageID; r.Title = rec.pack.Title; //and more... jsonlist.Add(r); } } return JsonConvert.SerializeObject(jsonlist); }
由於那個WebService是用EF4加JSON.NET回傳Json String,所以我在Browser直接打上<http://www.mydomain.com/WebService/ClientCallBack.asmx>試試,但竟沒有問題,再看看jQuery部份,兩者實在沒有微調空間,
jQuery最重要的兩行我都有了。
contentType: "application/json; charset=utf-8", dataType: "json",
試了很多方法都不行,最後唯有Google再Google,找到這篇文章。
問題大概是會出現在當IIS7的Application Pool設定Managed pipeline mode成<Integrated>才發生。
而解決方法是在web.config的system.web段中插入下面的設定就搞定。
<system.web> <webServices> <protocols> <add name="HttpGet" /> <add name="HttpPost" /> </protocols> </webServices> </system.web>
但事情還未解決...之後又出現新的錯誤:
System.InvalidOperationException: Request format is invalid: application/json; charset=utf-8.
at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
而解決方法則在這裡找到。
在web.config加入
<system.webServer> <handlers> <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </handlers> </system.webServer>
就大功告成。
第一個問題成因在KB article中有解說。
<By default, in .NET Framework 1.1, HTTP GET and HTTP POST are both disabled. This is for security reasons.>
雖然文中說是.NET 1.1問題,但解決方法卻是一模一樣。
而第二個問題就是,其實在IIS7的Manager上的Handler Mappings部份已經可以見到有ScriptHandlerFactory,
但就是沒有preCondition="integratedMode"一項,所以相信為什麼在Managed pipeline mode=<Classic>沒有問題,但轉成<integrated>就會產生錯誤。
[...] 呼叫的程式碼裡看來看去找了好久,結果發現是 web.config 造成的, 總算在這一篇(IIS7導致WebService無效?)找到我的問題,才想到我忘了在 web.config 中加入相對應的 httpModules 及 [...]
回覆刪除