.net 将单个数组作为参数的WCF操作是否可以使用MessageContracts?
我正在尝试用WCF服务替换asmx Web服务。我的主要目标是保持SOAP消息不变。调用方不是.NET,需要进行大量的重新工作才能对合同进行微小的更改 我的痛点是,我试图替换的web方法使用了以下属性:.net 将单个数组作为参数的WCF操作是否可以使用MessageContracts?,.net,wcf,soap,messagecontract,.net,Wcf,Soap,Messagecontract,我正在尝试用WCF服务替换asmx Web服务。我的主要目标是保持SOAP消息不变。调用方不是.NET,需要进行大量的重新工作才能对合同进行微小的更改 我的痛点是,我试图替换的web方法使用了以下属性: [SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)] 这将在每个参数周围删除一层额外的XML元素 我知道用WCF模拟这种情况的唯一方法是使用MessageContracts而不是DataContracts,并使用Wrapp
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
这将在每个参数周围删除一层额外的XML元素
我知道用WCF模拟这种情况的唯一方法是使用MessageContracts而不是DataContracts,并使用WrappedName和IsWrapped属性来控制参数的格式
这种方法适用于我的所有方法,但有一种方法除外,它将POCO对象的单个数组作为参数
我的结论是我别无选择。我无法升级此Web服务并维护相同的合同
我的问题是:
1) 是复制的唯一方法:
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
在WCF中的web方法上使用MessageContract
2) 有没有办法让一个方法将单个数组作为参数
下面是一个简单的例子,我一直在用它来展示我所看到的/正在做的事情
[SoapDocumentMethod(ParameterStyle=SoapParameterStyle.Bare)]和消息约定
支持服务代码:
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ServiceModel;
namespace WebApplication1{
/// <summary>
/// The Service Contract
/// </summary>
[ServiceContract]
public interface ISimpleMathService
{
[OperationContract()]
AddResp Add(AddReq add);
}
/// <summary>
/// The Service Implementation
/// </summary>
public class simpleMath : ISimpleMathService
{
[WebMethod()] //Allows the Service to be exposed as a asmx Service
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
public AddResp Add(AddReq add)
{
return new AddResp {result = add.NumOne + add.NumTwo};
}
}
}
ASMX肥皂
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:add>
<tem:NumOne>12</tem:NumOne>
<tem:NumTwo>12</tem:NumTwo>
</tem:add>
</soapenv:Body>
</soapenv:Envelope>
WCF Soap请求(V2):
现在执行此操作时,会出现以下异常,因为AddReq[]不是MessageContract。AddReq[]的类型为System.Array,我无法更改它
无法加载操作“AddArrays”,因为它的参数或返回类型为System.ServiceModel.Channels.Message,或者类型为MessageContractAttribute和其他不同类型的参数。使用System.ServiceModel.Channels.Message或带有MessageContractAttribute的类型时,该方法不得使用任何其他类型的参数
谢谢,
Brian我有点被你的说法难住了,那就是
SoapParameterStyle.Bare
删除了参数周围的一层XML,但是你只能通过使用消息契约来复制它,该契约使用IsWrapped=true
,这反过来基本上又在SOAP负载周围添加了一个XML包装器。。。似乎有点矛盾
您能否向我们展示您的方法的web方法声明,该方法将POCO数组作为其参数?到目前为止,您在WCF中尝试了什么?通常,使用
BasicHttpBinding
并且几乎没有任何选项,您可以非常接近ASMX在过去所做的工作。事实证明,您可以添加一个IsWrapped=false的“主机类”,并且它可以正常工作
根据原始问题中的示例,以下是包装器类的外观:
[DataContract,MessageContract(IsWrapped=false)]
public class AddArraysReq
{
[DataMember]
[MessageBodyMember]
public AddReq[] AddReqs;
}
public AddResp AddArrays(AddArraysReq addInput)
{
AddResp resp = new AddResp {result = 0};
foreach (var addrequest in addInput.AddReqs)
{
resp.result += (addrequest.NumOne + addrequest.NumTwo);
}
return resp;
}
这就是这个方法的样子:
[DataContract,MessageContract(IsWrapped=false)]
public class AddArraysReq
{
[DataMember]
[MessageBodyMember]
public AddReq[] AddReqs;
}
public AddResp AddArrays(AddArraysReq addInput)
{
AddResp resp = new AddResp {result = 0};
foreach (var addrequest in addInput.AddReqs)
{
resp.result += (addrequest.NumOne + addrequest.NumTwo);
}
return resp;
}
生成的SOAP请求:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:tem="http://tempuri.org/"
xmlns:web="http://schemas.datacontract.org/2004/07/WebApplication1">
<soap:Header/>
<soap:Body>
<tem:AddReqs>
<web:AddReq>
<web:NumOne>10</web:NumOne>
<web:NumTwo>10</web:NumTwo>
</web:AddReq>
<web:AddReq>
<web:NumOne>10</web:NumOne>
<web:NumTwo>10</web:NumTwo>
</web:AddReq>
</tem:AddReqs>
</soap:Body>
</soap:Envelope>
10
10
10
10
我没有意识到IsWrapped=false从请求中删除了该类的所有表示。Marc,感谢您的回复。我已经添加了围绕SoapParameterStyle.Bare的通用代码示例,以及我如何使用消息契约来重播asmx Soap格式。我的意图不是说我必须使用IsWrapped=true,而是使用属性属性来获得预期的效果。我希望我的样品能阐明我的意思。在这种情况下,“非常接近”还不够接近。我可能能够处理元素名称的更改,但是如果元素的嵌套更改,我就会遇到问题。
[DataContract,MessageContract(IsWrapped=false)]
public class AddArraysReq
{
[DataMember]
[MessageBodyMember]
public AddReq[] AddReqs;
}
public AddResp AddArrays(AddArraysReq addInput)
{
AddResp resp = new AddResp {result = 0};
foreach (var addrequest in addInput.AddReqs)
{
resp.result += (addrequest.NumOne + addrequest.NumTwo);
}
return resp;
}
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:tem="http://tempuri.org/"
xmlns:web="http://schemas.datacontract.org/2004/07/WebApplication1">
<soap:Header/>
<soap:Body>
<tem:AddReqs>
<web:AddReq>
<web:NumOne>10</web:NumOne>
<web:NumTwo>10</web:NumTwo>
</web:AddReq>
<web:AddReq>
<web:NumOne>10</web:NumOne>
<web:NumTwo>10</web:NumTwo>
</web:AddReq>
</tem:AddReqs>
</soap:Body>
</soap:Envelope>