首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >手工编写WCF POX帖子

手工编写WCF POX帖子
EN

Stack Overflow用户
提问于 2009-07-02 19:16:26
回答 2查看 1.3K关注 0票数 1

假设我有一份WCF合同,比如

代码语言:javascript
复制
[ServiceContract]
public interface IContract
{
    [OperationContract]
    [WebInvoke(Method="POST", RequestFormat=WebMessageFormat.Xml, BodyStyle=WebMessageBodyStyle.Wrapped)]
    string ComplexPost(string name, ComplexType data);
}

和一份数据合同:

代码语言:javascript
复制
[DataContract(Name="ComplexType", Namespace="")] // don't know if those atts are req'd or not but saw them in another example
public class ComplexType
{
    public string StringData { get; set; }
    public int IntData { get; set; }
    public DateTime DateValue { get; set; }
}

我知道,必须包装请求才能有多个输入参数,显然,您不能拥有一个具有多个根的XML文档。

问题是,关于您必须用什么包装它的文档非常稀少。

目标不是用WCF来使用它,它需要作为一个通用的XML服务被客户端访问。他们可能对WCF一无所知,甚至没有使用.NET。

显然,从我所收到的异常中可以看出,它期望一个名称为ComplexPost (与方法名称相同)的元素具有命名空间http://tempuri.org/,因为我还没有指定任何其他内容,因此我知道我需要这样做:

代码语言:javascript
复制
<ComplexPost xmlns="http://tempuri.org/">

...what exactly?

</ComplexPost>

其目标并不是具体地坚持REST原则。我并不是在寻找将一些参数嵌入到UriTemplate中的答案,只留下一个复杂的对象,使工作变得简单。我正在寻找一个包含POST正文中所有数据的通用解决方案。

与Fiddler

根据我使用Fiddler发现的结果,下面是大致的结果。

代码语言:javascript
复制
<ComplexPost xmlns="http://tempuri.org/">
    <name>Value of name parameter</name>
    <data xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <StringData>The StringData property value</StringData>
        <IntData>10</IntData>
        <DateValue>2009-07-07T15:38:39.7738012-05:00</DateValue>
    </data>
<ComplexPost>

因此,包装器元素是方法名,包含在ServiceContract上指定的XML命名空间,如果不是,则为temppuri.org。

每个参数依次成为子元素,基本类型很容易序列化成字符串表示形式。

我用可空值进行了测试,包括一个可空的DateTime。显然,xmlns:i="http://www.w3.org/2001/XMLSchema-instance“的声明必须发生在需要它之前,然后对于空值,它是一个带有i:nil="true”的封闭元素。

代码语言:javascript
复制
<NullableDateProperty i:nil="true" />

对于DataContract对象来说,拥有子复杂类型甚至复杂对象列表也是非常容易的。

代码语言:javascript
复制
....
<ChildObjectPropertyName>
    <PropertyOfChildObject>value</PropertyOfChildObject>
    ...
</ChildObjectPropertyName>
<ListProperty>
    <ObjectType>
        <ObjectProperty>value</ObjectProperty>
        ....
    </ObjectType>
    ...
</ListProperty>

这可能是不完整的,但教训肯定是让一个WCF客户端工作,然后检查交换与Fiddler。谢谢芝士!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-07-02 21:06:46

如果我这样做,发布一个基于WCF的REST/POX服务,并且我想让“任何人和任何东西”都可以使用它,我将使用一个调试HTTP代理,比如Fiddler2,并捕获一个从WCF客户端到WCF服务器的成功请求。

这可以作为开始文档和示例以及一组脚本测试的基础。

WCF本身也有一种打开消息跟踪的方法,但我不知道。我总是用费德勒。事实上我现在已经打开了。

票数 1
EN

Stack Overflow用户

发布于 2009-07-02 21:10:09

我不太明白你的目标.

“正常”WCF服务是SOAP服务--它本质上可以与任何讲SOAP的东西(例如Java、PHP )互操作--您可以将其命名为SOAP。您就不能创建您的WCF服务和伴随的DataContract作为一个成熟的SOAP服务并与您的客户进行互操作吗?

如果没有--如果使用REST,基本上会发生什么,那就是您的DataContract (服务的数据表示)将被DataContractSerializer序列化为XML。您可以使用以下代码片段在代码中轻松地手动测试:

代码语言:javascript
复制
DataContractSerializer dcs = new DataContractSerializer(typeof(YourDataContract));

FileStream outputFile = new FileStream(@"C:\output.xml");
dcs.WriteObject(outputFile, yourTestDataInstance);

"yourTestDataInstance“(类型为"YourDataContract")的序列化输出将写入C:\output.xml并随时准备检查。

当然,当浏览到服务URL时,您可以看到其余的结果。因此,您可能需要稍微调整一下结果--但是您应该能够轻松地实现您感兴趣的目标。

Name=上的“DataContract”属性允许您为XML中的根元素指定不同的名称--例如,如果您想要“根”而不是"YourDataContract",则使用"Name=Root“属性。

Namespace=属性的目的是允许您将数据契约放入一个独立的XML名称空间中--就像.NET名称空间一样,它允许您消除数据的歧义,使其完全唯一,并确保您自己的“客户”不会与来自其他地方的另一个名为"Customer“的XML元素发生冲突。

这两个属性都是可选的--如果不愿意,则不需要指定它们。

Marc

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1076187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档