我得到了一个将xml发布到wcf服务的代码。这是完整的代码
1)WCF服务接口
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "GetData",
RequestFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare)]
string GetData(DataRequest parameter);
2)WCF服务实施
public string GetData(DataRequest parameter)
{
//Do stuff
return "your data here";
}
3)WCF服务中的数据合同(在这种情况下是它的DataRequest)
[DataContract(Namespace = "YourNamespaceHere")]
public class DataRequest
{
[DataMember]
public string ID{ get; set; }
[DataMember]
public string Data{ get; set; }
}
4)发送数据的客户必须正确构建数据! (在这种情况下是C#console app)
static void Main(string[] args)
{
ASCIIEncoding encoding = new ASCIIEncoding();
string SampleXml = "<DataRequest xmlns=\"YourNamespaceHere\">" +
"<ID>" +
yourIDVariable +
"</ID>" +
"<Data>" +
yourDataVariable +
"</Data>" +
"</DataRequest>";
string postData = SampleXml.ToString();
byte[] data = encoding.GetBytes(postData);
string url = "http://localhost:62810/MyService.svc/GetData";
string strResult = string.Empty;
// declare httpwebrequet wrt url defined above
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
// set method as post
webrequest.Method = "POST";
// set content type
webrequest.ContentType = "application/xml";
// set content length
webrequest.ContentLength = data.Length;
// get stream data out of webrequest object
Stream newStream = webrequest.GetRequestStream();
newStream.Write(data, 0, data.Length);
newStream.Close();
//Gets the response
WebResponse response = webrequest.GetResponse();
//Writes the Response
Stream responseStream = response.GetResponseStream();
StreamReader sr = new StreamReader(responseStream);
string s = sr.ReadToEnd();
return s;
}
我的问题是,如果GetData()函数需要两个或更多参数,那我怎么能为GetData()提供值
public string GetData(string xml1,string xml2)
{
//Do stuff return "your data here";
}
所以请指导我如何将两个xml数据传递给GetData()
函数?
答案 0 :(得分:0)
首先,你不能拥有WebMessageBodyStyle.Bare
的服务和一个带两个参数的方法。您需要至少更改为WrappedRequest
:
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "GetData",
RequestFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
string GetData(DataRequest xml1, string xml2);
通过这种方式,让我们看看这种webHttp
绑定需要的线格式。
需要将根元素命名为操作的名称GetData
。接下来是每个参数1的子元素序列。这些元素的默认名称等于变量的名称,因此在示例中它将是xml1
和xml2
。通过使用[MessageParameter(Name="Bar")]
属性修饰参数可以影响这些默认值。
应用基本规则要求您的HTTP Post主体看起来与此类似:
<GetData> <!-- Operation -->
<xml1> <!-- parameter one -->
</xml1>
<xml2> <!-- parameter two -->
</xml2>
</GetData>
不幸的是,这不是它。该服务及其合同具有命名空间。没有任何装饰,名称空间是丑陋的http://tempuri.org/
,我在IService
界面上替换了
[ServiceContract(Namespace="http://service.stackoverflow.com")]
在您的第一个示例中,DataRequest
类型具有命名空间。在我的测试中,我用
[DataContract(Namespace="http://data.stackoverflow.com")]
现在我们需要将这些名称空间(带有名称空间别名)添加到我们的基本xml有效负载中:
<GetData xmlns="http://service.stackoverflow.com"> <!-- Operation with default namespace -->
<xml1 xmlns:a="http://data.stackoverflow.com"> <!-- namespace on type -->
<a:ID>42</a:ID> <!-- members are in the type namespace, use the alias -->
<a:Data>FuBar</a:Data>
</xml1>
<xml2> <!-- parameter two, no explicit namespace so is in the default one -->
BlahBlah
</xml2>
</GetData>
将该有效负载发布到Service1.svc/GetData
的服务会使用包含反序列化数据的参数调用该服务。
要准确回答您的问题,请在服务中更改示例代码:
[ServiceContract(Namespace="http://service.stackoverflow.com")]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "GetData",
RequestFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
string GetData([MessageParameter(Name="Bar")] DataRequest xml1, string xml2);
}
并在客户端:
var yourIDVariable = "foo";
var yourDataVariable = "bar";
string SampleXml = "<xml1 xmlns:a=\"http://data.stackoverflow.com\">" +
"<a:ID>" +
yourIDVariable +
"</a:ID>" +
"<a:Data>" +
yourDataVariable +
"</a:Data>" +
"</xml1>";
string xml2 = "some data";
string wrapper = "<GetData xmlns=\"http://service.stackoverflow.com\">{0}<xml2>{1}</xml2></GetData>";
string postData = String.Format(wrapper, SampleXml, xml2);
在处理WCF服务调用和诊断序列化问题时,在system.serviceModel
的配置中启用WCF消息记录非常方便:
<diagnostics>
<endToEndTracing activityTracing="true" messageFlowTracing="true" propagateActivity="true"/>
<messageLogging
logKnownPii="true"
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="30000"
maxSizeOfMessageToLog="20000"/>
</diagnostics>
和合适的听众:
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="messages.svclog" />
</listeners>
</source>
</sources>
<trace autoflush="true"></trace>
</system.diagnostics>
它为您提供Service Trace Viewer中的确切有效负载: