ASMX WebService无法处理JSON POST请求,寻求解决方法
ASMX WebService无法接收JSON格式POST请求,返回SOAP错误
问题背景
在Visual Studio 2022中创建基于.NET Framework的ASP.NET Web Application(ASMX WebService),使用C# HttpClient发送JSON格式POST请求时,收到“服务器无法处理请求”的SOAP错误,但发送到JSONPlaceholder免费测试API时可正常运行。
错误响应信息
Hello, World! Send msg: Hello_World. ===== {"Transmission":"Hello_World"} ===== Response: <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><soap:Code><soap:Value>soap:Receiver</soap:Value></soap:Code><soap:Reason><soap:Text xml:lang="es">System.Web.Services.Protocols.SoapException: El servidor no puede procesar la solicitud. ---> System.Xml.XmlException: Los datos del nivel de raíz no son válidos. línea 1, posición 1. en System.Xml.XmlTextReaderImpl.Throw(Exception e) en System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace() en System.Xml.XmlTextReaderImpl.ParseDocumentContent() en System.Web.Services.Protocols.SoapServerProtocol.SoapEnvelopeReader.Read() en System.Xml.XmlReader.MoveToContent() en System.Web.Services.Protocols.SoapServerProtocolHelper.GetRequestElement() en System.Web.Services.Protocols.Soap12ServerProtocolHelper.RouteRequest() en System.Web.Services.Protocols.SoapServerProtocol.Initialize() en System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) --- Fin del seguimiento de la pila de la excepción interna ---</soap:Text></soap:Reason><soap:Detail /></soap:Fault></soap:Body></soap:Envelope>
客户端代码
private static async Task Main(string[] args) { Console.WriteLine("Hello, World!"); try { /* * Check web service created locally. * string wsUrl = "https://localhost:44373/SoapDemo.asmx"; * string wsUrl = "https://jsonplaceholder.typicode.com/posts"; */ string wsUrl = "https://localhost:44373/SoapDemo.asmx"; // Send a small string. string msg = "Hello_World"; Console.WriteLine("Send msg:\n{0}.", msg); // Create connection to Web Service. var client = new HttpClient(); // Prepare the data to send to WS. Post postMsg = new Post(); postMsg.Transmission = msg; var data = JsonSerializer.Serialize<Post>(postMsg); // Finally send the msg to the WebService. Console.WriteLine("=====\n" + data + "\n====="); HttpContent content = new StringContent(data, System.Text.Encoding.UTF8, "application/json"); // Recive a response from the Web Service server. var httpResponse = await client.PostAsync(wsUrl, content); // if (httpResponse.IsSuccessStatusCode) { var result = await httpResponse.Content.ReadAsStringAsync(); Console.WriteLine("Response:\n{0}", result); // var postResult = JsonSerializer.Deserialize<Post>(result); // Console.WriteLine("Response:\n{0}", postResult); // } } catch (Exception ex) { Console.WriteLine("Transmission error:\n{0}", ex.ToString()); } }
WebService端ASMX函数代码
[WebMethod] // [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public bool Transmission() { ABCObject ObjectName = null; string contentType = HttpContext.Current.Request.ContentType; if (false == contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase)) { return false; } using (System.IO.Stream stream = HttpContext.Current.Request.InputStream) using (System.IO.StreamReader reader = new System.IO.StreamReader(stream)) { stream.Seek(0, System.IO.SeekOrigin.Begin); string bodyText = reader.ReadToEnd(); bodyText = bodyText == "" ? "{}" : bodyText; var json = Newtonsoft.Json.Linq.JObject.Parse(bodyText); ObjectName = Newtonsoft.Json.JsonConvert.DeserializeObject<ABCObject>(json.ToString()); } return true; }
解决方案
1. 启用ASMX的JSON请求支持
ASMX默认仅处理SOAP请求,必须给WebMethod添加[ScriptMethod]特性,明确指定请求和响应格式为JSON:
[WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json, RequestFormat = RequestFormat.Json)] public bool Transmission(ABCObject requestData) { // 直接使用自动反序列化后的参数,无需手动读取请求流 if (requestData == null || string.IsNullOrEmpty(requestData.Transmission)) { return false; } // 此处添加业务处理逻辑 return true; }
2. 修正客户端请求地址
JSON请求必须指向ASMX的具体方法,地址应为https://localhost:44373/SoapDemo.asmx/Transmission,而非根地址SoapDemo.asmx。
3. 确保数据模型结构一致
客户端的Post类与服务端的ABCObject类字段需完全匹配,示例:
// 客户端模型 public class Post { public string Transmission { get; set; } } // 服务端模型 public class ABCObject { public string Transmission { get; set; } }
4. 验证Web.config配置
确保配置了ScriptHandler以处理JSON请求:
<system.web> <httpHandlers> <add verb="*" path="*.asmx" type="System.Web.Script.Services.ScriptHandlerFactory" validate="false"/> </httpHandlers> </system.web>
同时确认compilation节点的targetFramework与项目使用的.NET Framework版本一致。
5. 简化客户端请求代码
可使用JsonContent简化JSON内容创建(需引用System.Net.Http.Json NuGet包):
var postMsg = new Post { Transmission = msg }; var content = JsonContent.Create(postMsg); var httpResponse = await client.PostAsync("https://localhost:44373/SoapDemo.asmx/Transmission", content);
内容的提问来源于stack exchange,提问作者F A Fernández
相关产品推荐
相关产品推荐

