Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 将单个数组作为参数的WCF操作是否可以使用MessageContracts?_.net_Wcf_Soap_Messagecontract - Fatal编程技术网

.net 将单个数组作为参数的WCF操作是否可以使用MessageContracts?

.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

我正在尝试用WCF服务替换asmx Web服务。我的主要目标是保持SOAP消息不变。调用方不是.NET,需要进行大量的重新工作才能对合同进行微小的更改

我的痛点是,我试图替换的web方法使用了以下属性:

[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>