gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 02:57:19 24 4
gpt4 key购买 nike

我正在尝试用 WCF 服务替换 asmx WebService。我的主要目标是保持 SOAP 消息相同。调用方不是 .NET,需要大量返工才能对契约(Contract)进行细微更改。

我的痛点是我试图替换 webmethod 的 web 方法使用以下属性减速:

[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]

这将删除每个参数周围的额外 XML 元素层。

我知道用 WCF 模拟这个的唯一方法是使用 MessageContracts 而不是 DataContracts,并使用 WrappedName 和 IsWrapped 属性来控制参数的格式。

这种方法适用于我的所有方法,除了一个方法,它以 POCO 对象的单个 Array 作为参数。

我的结论是我别无选择。我无法升级此网络服务并维护相同的契约(Contract)。

我的问题是:

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};
}
}
}

POCO 对象:(带有数据契约的 V1)
    using System.Runtime.Serialization;
using System.ServiceModel;

namespace WebApplication1
{
[DataContract]
public class AddReq
{

[DataMember]
public int NumOne { get; set; }

[DataMember]
public int NumTwo { get; set; }
}



[DataContract]
public class AddResp
{

[DataMember]

public int result{ get; set; }


}
}

ASMX SOAP
<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>

SOAP 请求,使用 WCF 数据协定
<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:Add>
<tem:add>
<web:NumOne>10</web:NumOne>
<web:NumTwo>10</web:NumTwo>
</tem:add>
</tem:Add>
</soap:Body>
</soap:Envelope>

让我们在我们的参数和返回类型上使用消息契约:
POCO 对象:(带有 MessageContracts 的 V2)
namespace WebApplication1
{
[DataContract]
[MessageContract(WrapperName="add", IsWrapped = true)] //Default Wrapper Name is "Add", not add
public class AddReq
{

[DataMember]
[MessageBodyMember]
public int NumOne { get; set; }

[DataMember]
[MessageBodyMember]
public int NumTwo { get; set; }
}



[DataContract]
[MessageContract(IsWrapped = true)]
public class AddResp
{

[DataMember]
[MessageBodyMember]
public int result{ get; set; }


}
}

WCF SOAP 请求 (V2):
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
<soap:Header/>
<soap:Body>
<tem:add>
<tem:NumOne>19</tem:NumOne>
<tem:NumTwo>12</tem:NumTwo>
</tem:add>
</soap:Body>
</soap:Envelope>

这就是我现在正在做的,它满足了我所需要的 90%。

问题是,我想在 WCF 中实现这样的方法并保持契约(Contract)不变:
[WebMethod()]
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
public AddResp AddArrays(AddReq [] addInput)
{
AddResp resp= new AddResp{result=0}
foreach (var addrequest in addInput)
{
resp.result += (addrequest.NumOne + addrequest.NumTwo);
}
return resp;
}

当我现在这样做时,我得到以下异常,因为 AddReq [] 不是 MessageContract。 AddReq [] 是 System.Array 类型,我无法更改。

无法加载操作“AddArrays”,因为它具有 System.ServiceModel.Channels.Message 类型的参数或返回类型,或者具有 MessageContractAttribute 和其他不同类型参数的类型。使用 System.ServiceModel.Channels.Message 或具有 MessageContractAttribute 的类型时,该方法不得使用任何其他类型的参数。

谢谢,
布赖恩

最佳答案

事实证明,您可以添加一个 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;
}

生成的 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>

我没有意识到 IsWrapped=false 从请求中删除了该类的所有表示。

关于.net - 将单个数组作为参数的 WCF 操作可以使用 MessageContracts 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2389534/

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