我正在尝试使用C#来使用SOAP Web服务,并且当使用SOAPUI甚至使用带有SUDS的Python时似乎还可以(我想确保它不在服务器端),而从C#中使用它时,我总是会得到null值(通过Fiddler进行的拦截表明它实际上包含数据)。
可能是C#创建的代理对象未正确处理SOAP数组。
由于我是WSDL的新手,所以我可能错过了一些东西,我在网络上看到许多类似的(与Ladon部分无关)麻烦的解决方法,但是没有什么帮助的。
谢谢你的帮助。
ps:一些代码,因此可以重现此错误。
步骤0:添加:服务Web参考,如此处所述:http://webservices20.blogspot.fr/2008/10/interoperability-gotcha-visual-studio.html
我的被称为“ albumsWRn”
此错误的C#演示在这里:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using ConsoleApplication6.albumsWRn; // PUT HERE THE NAME OF THE "Web References" you provide @ step 0
namespace ConsoleApplication6
{
public static class PrettyPrinter
{
// from: http://www.jberndsen.nl/2012/05/c-pretty-printer/
// the main function to be called to pretty print an object
public static void PrettyPrint(object myData, StreamWriter sw)
{
// output to StreamWriter, in our case, representing a text file
if (sw == null) throw new ArgumentNullException("sw");
sw.WriteLines(GetPropValues(myData));
}
// to standard output
public static void PrettyPrint(object myData)
{
StreamWriter sw = new StreamWriter(Console.OpenStandardOutput());
sw.AutoFlush = true;
Console.SetOut(sw);
PrettyPrint(myData, sw);
}
// extension for the streamwriter to write lists of strings
private static void WriteLines(this StreamWriter sw, IEnumerable<string> lines)
{
foreach (var line in lines)
{
sw.WriteLine(line);
}
}
// generates spaces for indentation
private static string Spaces(int i)
{
return (i > 0) ? " " + Spaces(i - 1) : string.Empty;
}
private static string GetValue(object o)
{
if (o == null)
{
return "null";
}
if (o is DateTime)
{
return ((DateTime)o).ToShortDateString();
}
return o.ToString();
}
private static List<string> GetPropValues(object element, int depth = 0)
{
var result = new List<string>();
// primitives
if (element == null || element is ValueType || element is string)
{
result.Add(Spaces(depth) + GetValue(element));
}
else
{
// enumerations
var enumerableElement = element as IEnumerable;
if (enumerableElement != null)
{
foreach (var item in enumerableElement)
{
result.AddRange(GetPropValues(item, depth + 1));
}
}
// composite types
else
{
// get all the members and iterate through them
var members = element.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance);
foreach (var member in members)
{
var fieldInfo = member as FieldInfo;
var propertyInfo = member as PropertyInfo;
if (fieldInfo != null || propertyInfo != null)
{
// get the type of the member and check if its a primitive
var t = fieldInfo != null ? fieldInfo.FieldType : propertyInfo.PropertyType;
if (t.IsValueType || t == typeof(string))
{
// print the primitive member, its name and its value
var localResult = member.Name + ": ";
localResult += GetValue(fieldInfo != null ? fieldInfo.GetValue(element) : propertyInfo.GetValue(element, null));
result.Add(Spaces(depth) + localResult);
}
else
{
// print the non-primitive member, its name and recursively pretty print its value
var o = fieldInfo != null ? fieldInfo.GetValue(element) : propertyInfo.GetValue(element, null);
result.Add(Spaces(depth) + member.Name + ": ");
result.AddRange(GetPropValues(o, depth + 1));
}
}
}
}
}
return result;
}
}
class Program
{
static void Main(string[] args)
{
AlbumService albumService = new AlbumService();
var filteredAlbums = albumService.listAlbums("The");
PrettyPrinter.PrettyPrint(filteredAlbums);
if (filteredAlbums.item == null)
{
Console.WriteLine("null contained, while it should not!");
}
}
}
}
soapUI:这是在使用soapUI检查它实际时使用的查询。
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:AlbumService">
<soapenv:Header/>
<soapenv:Body>
<urn:listAlbums soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<search-frase xsi:type="xsd:string">The</search-frase>
</urn:listAlbums>
</soapenv:Body>
</soapenv:Envelope>
WSDL在这里可见:http://ladonize.org/python-demos/AlbumService/soap11/description
(这是Ladon创作者的演示站点:http://ladonize.org/python-demos/AlbumService)
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:AlbumService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="urn:AlbumService" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="urn:AlbumService" name="AlbumService">
<wsdl:types>
<xsd:schema targetNamespace="urn:AlbumService">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<xsd:complexType name="ArrayOfunicode">
<xsd:sequence>
<xsd:element type="xsd:string" name="item" nillable="true" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Band">
<xsd:sequence>
<xsd:element type="ns2:ArrayOfunicode" name="album-titles" nillable="true" minOccurs="0" maxOccurs="1" />
<xsd:element type="xsd:string" name="name" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Album">
<xsd:sequence>
<xsd:element type="ns2:Band" name="band" minOccurs="1" maxOccurs="1" />
<xsd:element type="ns2:ArrayOfunicode" name="songs" nillable="true" minOccurs="0" maxOccurs="1" />
<xsd:element type="xsd:string" name="title" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ArrayOfAlbum">
<xsd:sequence>
<xsd:element type="ns2:Album" name="item" nillable="true" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ArrayOfBand">
<xsd:sequence>
<xsd:element type="ns2:Band" name="item" nillable="true" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="listAlbums">
<wsdl:part type="xsd:string" name="search-frase" />
</wsdl:message>
<wsdl:message name="listAlbumsResponse">
<wsdl:part type="ns2:ArrayOfAlbum" name="result" />
</wsdl:message>
<wsdl:message name="listBands">
<wsdl:part type="xsd:string" name="search-frase" />
</wsdl:message>
<wsdl:message name="listBandsResponse">
<wsdl:part type="ns2:ArrayOfBand" name="result" />
</wsdl:message>
<wsdl:portType name="AlbumServicePortType">
<wsdl:operation name="listAlbums">
<wsdl:documentation>Fetch a list of albums matching search_frase</wsdl:documentation>
<wsdl:input message="tns:listAlbums" />
<wsdl:output message="tns:listAlbumsResponse" />
</wsdl:operation>
<wsdl:operation name="listBands">
<wsdl:documentation>Fetch a list of albums matching search_frase</wsdl:documentation>
<wsdl:input message="tns:listBands" />
<wsdl:output message="tns:listBandsResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding type="tns:AlbumServicePortType" name="AlbumService">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="listAlbums">
<soap:operation style="rpc" soapAction="http://ladonize.org/python-demos/AlbumService/soap11/listAlbums" />
<wsdl:input>
<soap:body namespace="urn:AlbumService" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</wsdl:input>
<wsdl:output>
<soap:body namespace="urn:AlbumService" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="listBands">
<soap:operation style="rpc" soapAction="http://ladonize.org/python-demos/AlbumService/soap11/listBands" />
<wsdl:input>
<soap:body namespace="urn:AlbumService" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</wsdl:input>
<wsdl:output>
<soap:body namespace="urn:AlbumService" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="AlbumService">
<wsdl:documentation>Ladon generated service definition</wsdl:documentation>
<wsdl:port name="AlbumService" binding="tns:AlbumService">
<soap:address location="http://ladonize.org/python-demos/AlbumService/soap11" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Fiddler截获的答案(因此,它不是NULL):
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns="urn:AlbumService" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<ns:listAlbumsResponse>
<result>
<item>
<band>
<album-titles>
<item>Album Of The Year</item>
<item>KING FOR A DAY - FOOL FOR A LIFETIME</item>
</album-titles>
<name>Faith No More</name>
</band>
<title>Album Of The Year</title>
<songs>
<item>Ashes To Ashes.mp3</item>
<item>Mouth To Mouth.mp3</item>
<item>Last Cup Of Sorrow [Sharam Versus Fnm Club Mix] [Bonus Track].mp3</item>
<item>Paths Of Glory.mp3</item>
<item>Pristina.mp3</item>
<item>Light Up And Let Go [Bonus Track].mp3</item>
<item>Helpless.mp3</item>
<item>The Big Kahuna [Bonus Track].mp3</item>
<item>She Loves Me Not.mp3</item>
<item>Stripsearch.mp3</item>
<item>Last Cup Of Sorrow.mp3</item>
<item>Collision.mp3</item>
<item>Home Sick Home.mp3</item>
<item>She Loves Me Not [Spinna Crazy Dub Mix] [Bonus Track].mp3</item>
<item>Last Cup Of Sorrow [Rammstein Mix] [Bonus Track].mp3</item>
<item>Naked In Front of The Computer.mp3</item>
<item>Got That Feeling.mp3</item>
<item>Ashes To Ashes [Hardknox Alternative Mix] [Bonus Track].mp3</item>
</songs>
</item>
<item>
<band>
<album-titles>
<item>Paint The Sky With Stars - The Best Of Enya</item>
</album-titles>
<name>Enya</name>
</band>
<title>Paint The Sky With Stars - The Best Of Enya</title>
<songs>
<item>Watermark.mp3</item>
<item>Boadicea.mp3</item>
<item>Storms In Africa.mp3</item>
<item>Book Of Days.mp3</item>
<item>Caribben Blue.mp3</item>
<item>The Celts.mp3</item>
<item>Anywhere Is.mp3</item>
<item>Shepherd Moons.mp3</item>
<item>China Roses.mp3</item>
<item>Marble Halls.mp3</item>
<item>On My Way Home.mp3</item>
<item>Ebudae.mp3</item>
<item>The Memory Of Trees.mp3</item>
<item>Paint The Sky With Stars.mp3</item>
<item>Only If....mp3</item>
<item>Orinoco Flow.mp3</item>
</songs>
</item>
<item>
<band>
<album-titles>
<item>Zitilites</item>
<item>No Balance Palace</item>
<item>Home Dead</item>
<item>Travelogue</item>
<item>Cruzential</item>
<item>The Good Life</item>
</album-titles>
<name>Kashmir</name>
</band>
<title>The Good Life</title>
<songs>
<item>Gorgeous.mp3</item>
<item>New Year's Eve.mp3</item>
<item>Lampshade.mp3</item>
<item>It's OK Now.mp3</item>
<item>Graceland.mp3</item>
<item>Miss You.mp3</item>
<item>Mudbath.mp3</item>
<item>Mom In Love, Daddy In Space.mp3</item>
<item>Kiss Me Goodbye.mp3</item>
<item>Make It Grand.mp3</item>
</songs>
</item>
<item>
<band>
<album-titles>
<item>The Wall CD2</item>
<item>The Wall Part I</item>
</album-titles>
<name>Pink Floyd</name>
</band>
<title>The Wall CD2</title>
<songs>
<item>Nobody Home.mp3</item>
<item>Waiting For The Worms.mp3</item>
<item>Bring The Boys Back Home.mp3</item>
<item>The Trial.mp3</item>
<item>Is There Anybody Out There?.mp3</item>
<item>Comfortably Numb.mp3</item>
<item>Run Like Hell.mp3</item>
<item>The Show Must Go On.mp3</item>
<item>Vera.mp3</item>
<item>In The Flesh.mp3</item>
<item>Outside The Wall.mp3</item>
<item>Hey You.mp3</item>
<item>Stop.mp3</item>
</songs>
</item>
<item>
<band>
<album-titles>
<item>The Wall CD2</item>
<item>The Wall Part I</item>
</album-titles>
<name>Pink Floyd</name>
</band>
<title>The Wall Part I</title>
<songs>
<item>The Happiest Days Of Our Lives.mp3</item>
<item>Another Brick In The Wall (Part 1).mp3</item>
<item>Goodbye Cruel World.mp3</item>
<item>One Of The Turns.mp3</item>
<item>In The Flesh?.mp3</item>
<item>Empty Spaces.mp3</item>
<item>The Thin Ice.mp3</item>
<item>Goodbye Blue Sky.mp3</item>
<item>Another Brick In The Wall (Part 2).mp3</item>
<item>Another Brick In The Wall (Part 3).mp3</item>
<item>Young Lust.mp3</item>
<item>Mother.mp3</item>
<item>Don't Leave Now.mp3</item>
</songs>
</item>
</result>
</ns:listAlbumsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
最佳答案
当Ladon 0.8.1仅提供RPC / Encoded时,.NET SOAP客户端似乎默认情况下期望Document / Literal WSDL。
我没有找到使C#客户端与RPC / Encoded一起工作的方法,因此我为提供文档/文字WSDL的Ladon(请参见https://bugs.launchpad.net/ladon/+bug/1096004的自定义界面)进行了工作。仅供参考,我遵循了本指南http://wso2.com/library/knowledge-base/convert-rpc-encoded-wsdl-document-literal-wrapped-wsdl。
更新:我的修复程序最近在Ladon 0.8.2中生效(请参阅
http://bazaar.launchpad.net/~ladon-dev-team/ladon/ladon/revision/105)。