gpt4 book ai didi

c# - 如何通过 post 将 xml 发送到 wcf 服务

转载 作者:太空宇宙 更新时间:2023-11-03 15:56:36 25 4
gpt4 key购买 nike

我得到了一个将 xml 发布到 wcf 服务的代码。这是完整的代码

1) WCF服务接口(interface)

[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# 控制台应用程序)

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() 函数?

最佳答案

首先,您不能使用带有 WebMessageBodyStyle.Bare 的服务和采用两个参数的方法。您至少需要更改为 WrappedRequest:

[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "GetData",
RequestFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
string GetData(DataRequest xml1, string xml2);

让我们看看这个 webHttp 绑定(bind)需要什么样的有线格式。

根元素需要命名为操作的名称,GetData。接下来是一系列子元素,每个参数一个。这些元素的默认名称等于您的变量的名称,因此在示例中它将是 xml1xml2。这些默认值可以通过使用 [MessageParameter(Name="Bar")] 属性装饰参数来影响。

应用上述基本规则要求您的 HTTP Post 正文看起来类似于:

<GetData>    <!-- Operation -->
<xml1> <!-- parameter one -->
</xml1>
<xml2> <!-- parameter two -->
</xml2>
</GetData>

不幸的是,事实并非如此。该服务及其契约(Contract)具有命名空间。没有任何装饰,命名空间是丑陋的 http://tempuri.org/ 我在 IService 接口(interface)上用

替换了它
 [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 中为您提供确切的有效负载:

关于c# - 如何通过 post 将 xml 发送到 wcf 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23287929/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com