Мне нужно вызвать сервис мыла из основного приложения C # .net и получить результаты в классе, который я могу использовать для выполнения некоторой логики. Я сделал запрос мыла, и удаленный вызов работает нормально, но теперь я должен десериализовать ответ мыла xml в класс. Вот пример ответа:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://some_domain/soap/ApplicationServices">
<SOAP-ENV:Body>
<ns1:preparelabelsResponse xmlns:ns1="http://some_domain/soap/ApplicationServices">
<return xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="tns:PrepareReturn[1]">
<item xsi:type="tns:PrepareReturn">
<clientref xsi:type="xsd:string">2015/0418/001</clientref>
<pclid xsi:type="xsd:string"></pclid>
<error xsi:type="xsd:string">Invalid timestamp 20191018105727</error>
</item>
</return>
</ns1:preparelabelsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Поскольку я использую Visual Studio 2017, я попытался добавить подключенную службу в свое приложение .netcore с помощью поставщика ссылок на веб-службы WCF, а затем вызвать метод. Вызов не удался с сообщением: неправильный формат XML, который, вероятно, был сгенерирован сервером. Выполнение тех же шагов в приложении .NET Framework работало нормально, и я получил правильный ответ. Так что я подозреваю, что в провайдере .netcore wcf что-то не так. Мой второй подход состоял в том, чтобы создать запрос мыла вручную, а затем проанализировать ответ мыла. Для построения запроса у меня есть элегантное решение, а для анализа ответа - нет. Я пытался использовать классы, сгенерированные поставщиком wcf, но десериализация xml не работала. Затем я попытался изменить атрибуты, чтобы сделать это правильно, но не помогло. Ниже я добавил эти классы:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "1.0.0.1")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="preparelabelsResponse", WrapperNamespace="encoded", IsWrapped=true)]
public partial class preparelabelsResponse
{
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="", Order=0)]
public PrepareReturn[] @return;
public preparelabelsResponse()
{
}
public preparelabelsResponse(PrepareReturn[] @return)
{
this.@return = @return;
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "1.0.0.1")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.SoapTypeAttribute(Namespace="http://some_domain/soap/ApplicationServices")]
public partial class PrepareReturn
{
private string clientrefField;
private string pclidField;
private string errorField;
/// <remarks/>
public string clientref
{
get
{
return this.clientrefField;
}
set
{
this.clientrefField = value;
}
}
/// <remarks/>
public string pclid
{
get
{
return this.pclidField;
}
set
{
this.pclidField = value;
}
}
/// <remarks/>
public string error
{
get
{
return this.errorField;
}
set
{
this.errorField = value;
}
}
}
И десериализацию XML:
var soapResponse = XDocument.Load(sr);
XNamespace myns = "http://some_domain/soap/ApplicationServices";
var xml = soapResponse.Descendants(myns + "preparelabelsResponse").FirstOrDefault().ToString();
var result = Deserialize<preparelabelsResponse>(xml);
...
public static T Deserialize<T>(string xmlStr)
{
var serializer = new XmlSerializer(typeof(T));
T result;
using (TextReader reader = new StringReader(xmlStr))
{
result = (T)serializer.Deserialize(reader);
}
return result;
}
Итак, что я мог сделать, это убрать XML из всех пространств имен и атрибутов и десериализовать его дляпростой класс, но это не элегантное решение для моей проблемы. Я хочу, чтобы у меня была возможность создавать / украшать мои классы таким образом, чтобы десериализация работала без какого-либо изменения реального содержимого XML.