#c# #.net #xml #wcf #faultexception
#c# #.net #xml #wcf #исключение faultexception
Вопрос:
У меня есть xml-файл следующего формата:
<?xml version="1.0" encoding="utf-16"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:Receiver</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">Cannot create order</soap:Text>
</soap:Reason>
<soap:Detail>
<ComplianceViolationInfos xmlns="http://aaim.sungard.com/order/service/v1_0" xmlns:ns10="http://aaim.sungard.com/issuer/schema/v2011_06_01" xmlns:ns2="http://aaim.sungard.com/datatypes/schema/v2011_06_01" xmlns:ns3="http://aaim.sungard.com/order/schema/v2011_06_01" xmlns:ns4="http://aaim.sungard.com/fxorder/schema/v2011_06_01" xmlns:ns5="http://aaim.sungard.com/portfolio/schema/v2011_06_01" xmlns:ns6="http://aaim.sungard.com/transaction/schema/v2011_06_01" xmlns:ns7="http://aaim.sungard.com/compliance/schema/v2011_06_01" xmlns:ns8="http://aaim.sungard.com/user/schema/v2011_06_01" xmlns:ns9="http://aaim.sungard.com/instrument/schema/v2011_06_01">
<ns7:violationInfo>
<ns7:RuleType>REQ_OVERRIDE</ns7:RuleType>
<ns7:RuleName> Name </ns7:RuleName>
<ns7:Diagnostic> data </ns7:Diagnostic>
</ns7:violationInfo>
<ns7:violationInfo>
<ns7:RuleType> rule </ns7:RuleType>
<ns7:RuleName> data </ns7:RuleName>
<ns7:Diagnostic>1. data </ns7:Diagnostic>
</ns7:violationInfo>
<ns7:violationInfo>
<ns7:RuleType>WARNING</ns7:RuleType>
<ns7:RuleName> name </ns7:RuleName>
<ns7:Diagnostic> data </ns7:Diagnostic>
</ns7:violationInfo>
</ComplianceViolationInfos>
</soap:Detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
В случае ошибки я хочу получить доступ ко всем данным, которые находятся между флагом details, обработать их дальше и позже вернуть пользователю. Я работаю над приложением .NET Core, поэтому я не могу использовать SoapExceptions.
Для достижения этого у меня есть try-catch-blog в моем коде, который улавливает Faultexception:
try
{
//..//
}
catch (FaultException e)
{
MessageFault messagefault = e.CreateMessageFault();
var xmlElement = messagefault.GetReaderAtDetailContents();
string test = xmlElement.ReadContentAsString();
throw e;
}
Приведенный выше код не возвращает данные между подробными флагами. Я также уже пробовал:
string xmlElement = messagefault.GetDetail<XmlElement>().Value
Это вернуло пустую строку.
Я думаю, причина в ошибке в моем wcf этого сервиса, которую я не могу понять. Классы для сериализации:
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "1.0.0.1")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://aaim.sungard.com/compliance/schema/v2011_06_01")]
public partial class ComplianceViolationInfo
{
private ViolationInfo[] ViolationInfoField;
[System.Xml.Serialization.XmlArrayAttribute(Order = 0)]
[System.Xml.Serialization.XmlArrayItemAttribute("violationInfo", IsNullable = false)]
public ViolationInfo[] ViolationInfo
{
get
{
return this.ViolationInfoField;
}
set
{
this.ViolationInfoField = value;
}
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "1.0.0.1")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://aaim.sungard.com/compliance/schema/v2011_06_01")]
public partial class ViolationInfo
{
private string ruleTypeField;
private string ruleNameField;
private string diagnosticField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 0)]
public string RuleType
{
get
{
return this.ruleTypeField;
}
set
{
this.ruleTypeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 1)]
public string RuleName
{
get
{
return this.ruleNameField;
}
set
{
this.ruleNameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 2)]
public string Diagnostic
{
get
{
return this.diagnosticField;
}
set
{
this.diagnosticField = value;
}
}
}
Это называется так:
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
[System.ServiceModel.FaultContractAttribute(typeof(OrderService.ComplianceViolationInfo), Action="", Name="ComplianceViolationInfos", Namespace="http://aaim.sungard.com/order/service/v1_0")]
[System.ServiceModel.FaultContractAttribute(typeof(OrderService.FaultInfo), Action = "", Name = "FaultInfo", Namespace = "http://aaim.sungard.com/order/service/v1_0")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
System.Threading.Tasks.Task<OrderService.CreateOrderResponse1> CreateOrderAsync(OrderService.CreateOrderRequest request);
Комментарии:
1. Если вы получаете ответ, чем вы должны проверить статус 200 OK. Если вы не получаете 200 OK, вам нужно записать ответ об ошибке. Смотрите : docs.microsoft.com/en-us/dotnet/api /…
2. Соединение в порядке, это soapfault в данном случае происходит, когда пользователь делает неправильный заказ, я хочу показать ошибки, которые он допустил в своем заказе, показанные в деталях xml-файла.
3. Если соединение было плохим, вы не получили бы никакого ответа. Вы получаете статус 200 OK или что-то еще? Контроллер может исключать более одного типа ответа. для каждого типа ответа вам нужен свой набор классов сериализации c #, чтобы получить подробные данные.
4. Я получаю статус 200 OK, а затем получаю XML-файл вышеуказанной формы из интерфейса.
5. Ваш контроллер должен обрабатывать более одного типа ответа (маршрута). Смотрите : docs.microsoft.com/en-us/aspnet/core/web-api /…