c# - SOAP XML 到 C# 类
问题描述
大家好,我是肥皂新手,我们开始使用一些服务,使用 xml 对我的 asmx 进行后调用。在我的 asmx 文件中的项目中,我需要构建从他们那里收到的模型。所以我有xml:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<Exit xmlns="http://tempuri.org/">
<UserName>daniel@xxx.com</UserName>
<Password>123456</Password>
<parkingLotId>21</parkingLotId>
<gateNumber>EX 41</gateNumber>
<ticketNumber>123123123123123123123</ticketNumber>
<plateNumber>12211221</plateNumber>
<paymentSum>10.0</paymentSum>
<ExitDateTime>2018-12-23T09:56:10</ExitDateTime>
<referenceId>987462187346238746263</referenceId>
</Exit>
</s:Body>
</s:Envelope>
当我将此 xml 粘贴到 Visual Studio Edit -> Special Pase -> Paste XML As Class 中时,它会为我构建具有 xml 属性的模型,例如:
[XmlRoot(ElementName = "Exit", Namespace = "http://tempuri.org/")]
public class Exit
{
[XmlElement(ElementName = "UserName", Namespace = "http://tempuri.org/")]
public string UserName { get; set; }
....
}
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "Exit", Namespace = "http://tempuri.org/")]
public Exit Exit { get; set; }
}
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "s", Namespace = "http://www.w3.org/2000/xmlns/")]
public string S { get; set; }
}
但!每次我用这些数据发出 POST 请求时都会出错:
<?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="en">System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Xml.XmlException: Root element is missing.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Web.Services.Protocols.SoapServerProtocol.SoapEnvelopeReader.Read()
at System.Xml.XmlReader.MoveToContent()
at System.Web.Services.Protocols.SoapServerProtocol.SoapEnvelopeReader.MoveToContent()
at System.Web.Services.Protocols.SoapServerProtocolHelper.GetRequestElement()
at System.Web.Services.Protocols.Soap12ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
--- End of inner exception stack trace ---</soap:Text>
</soap:Reason>
<soap:Detail />
</soap:Fault>
</soap:Body>
</soap:Envelope>
这是我的代码:
[WebMethod]
public string Exit()
{
XmlDocument xmlSoapRequest = new XmlDocument();
using (Stream receiveStream = HttpContext.Current.Request.InputStream)
{
receiveStream.Position = 0;
using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8)) { xmlSoapRequest.Load(readStream); }
}
var password = xmlSoapRequest?.GetElementsByTagName("Password")?.Item(0)?.FirstChild?.Value;
var userName = xmlSoapRequest?.GetElementsByTagName("UserName")?.Item(0)?.FirstChild?.Value;
var parkingLotId = xmlSoapRequest?.GetElementsByTagName("parking_lot_Id")?.Item(0)?.FirstChild?.Value;
var gateNumber = xmlSoapRequest?.GetElementsByTagName("gateNumber")?.Item(0)?.FirstChild?.Value;
var plateNumber = xmlSoapRequest?.GetElementsByTagName("plateNumber")?.Item(0)?.FirstChild?.Value;
var paymentSum = xmlSoapRequest?.GetElementsByTagName("paymentSum")?.Item(0)?.FirstChild?.Value;
var exitDateTime = xmlSoapRequest?.GetElementsByTagName("ExitDateTime")?.Item(0)?.FirstChild?.Value;
var referenceId = xmlSoapRequest?.GetElementsByTagName("referenceId")?.Item(0)?.FirstChild?.Value;
var exitParking = new Exit
{
ExitDateTime = Convert.ToDateTime(exitDateTime),
gateNumber = gateNumber,
parkingLotId = Convert.ToByte(parkingLotId),
Password = Convert.ToUInt32(password),
paymentSum = Convert.ToDecimal(paymentSum),
plateNumber = Convert.ToUInt32(plateNumber),
referenceId = referenceId,
UserName = userName
};
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
var jsonObject = jsonSerializer.Serialize(exitParking);
var content = new StringContent(jsonObject, Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
var result = client.PostAsync("http://merchant-api-eb-parking-prod.eu-west-1.elasticbeanstalk.com/v1/parkings/exit", content).Result;
Context.Response.Output.Write($"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><ExitResponse xmlns=\"http://tempuri.org/\"><ExitResult xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:i=\"http://www.w3.org/2001/XMLSchema\"><a:Status>OK</a:Status></ExitResult></ExitResponse></s:Body></s:Envelope>");
Context.Response.ContentType = "text/xml";
Context.Response.End();
return string.Empty;
}
我可以在请求对象中看到我在 Global.asax 中发布的数据我看到我作为字符串发布的 xml,但是在全局 asax 之后它会引发异常。
我有 Root 属性,但在异常情况下它说:缺少 Root 元素
谢谢你!
解决方案
好的,想通了!错误的原因是:
<Exit xmlns="http:--tempuri-org-">
命名空间(xmlns)必须是我在服务器上的网站 url
http:--mysite-com-
代替
http:--tempuri-org-
推荐阅读
- c# - 如何使用 Xamarin 表单创建功能发现
- c# - 在 Unity 3D 中,是否有理解何时引用变量以及何时将其复制到新变量的一般规则?
- javascript - 在卡片上显示内联元素
- python - >> 气流 DAG 不支持的操作数类型出错:“列表”和“列表”。任务的顺序和并行执行
- makefile - 设置YOLOv4时make不起作用?还有我不确定是否已解决的 cmake 问题
- html - 使用布尔标志Angular 8进行表单验证
- c# - 使用 Linux 系统从 C# Azure 函数运行 PowerShell 脚本/CLI 命令
- java - 在 Postgres 中动态查询 jsonb 列
- python-3.x - 在行为框架(Python)中断言失败时如何继续执行“for”循环?
- html - Div 颜色没有勾勒出所有元素