gpt4 book ai didi

wcf - 使用消息协定的请求/响应中的不同SOAP header

转载 作者:行者123 更新时间:2023-12-04 04:17:48 27 4
gpt4 key购买 nike

我正在构建一些具有通用 header 的服务。此 header 在请求中具有特定的布局,而在响应中具有不同的布局(即,有两个类)。

但是,当我添加引用或使用svcutil时,将在请求和响应类型中使用相同的 header 生成代理。

例如:

[MessageContract]
class Contract<THeader, TBody>
{
[MessageHeader] public THeader Header { get; set; }

[MessageBodyMember] public TBody Body { get; set; }
}

class MyRequestHeader
{
public string RequestorId { get; set; }
}

class MyResponseHeader
{
public string ErrorMessage { get; set; }
}

OperationContract类似于:
[OperationContract]
public Contract<MyResponseHeader, ResponseBody> Process(Contract<MyRequestHeader, RequestBody> data);

代理变为:
var client = new ...; 
var header = new MyRequestHeader();
var body = new RequestBody();

**ResponseBody**

response = client.Process(ref header, body);

如您所见, header (Request)作为ref传递;这可能意味着WCF在请求和响应中具有相同的 header 。并且MyResponseHeader消失了。

任何人都可以对这个问题有所了解吗?

最佳答案

这里发生了一些奇怪的事情。

我试图重现您的问题,并得到以下结果(我必须标记一些类型public,并将[DataContract]添加到您的 header 类中)。

这是WSDL的 View :

生成的代码(svcutil 4.0.30319.18046)在Response消息中也使用MyRequestHeader:

这是由以下XSD引起的:

如您所见,仅为“Header”类生成了一个实例。

我尝试为通用类创建类型,如下所示:

[MessageContract]
public abstract class Contract<THeader, TBody>
{
[MessageHeader]
public THeader Header { get; set; }

[MessageBodyMember]
public TBody Body { get; set; }
}

[DataContract(Name="RequestHeader")]
public class MyRequestHeader
{
public string RequestorId { get; set; }
}

[DataContract(Name = "ResponseHeader")]
public class MyResponseHeader
{
public string ErrorMessage { get; set; }
}

[MessageContract]
public class RequestContract : Contract<MyRequestHeader, string>
{ }

[MessageContract]
public class ResponseContract : Contract<MyResponseHeader, string>
{ }

[ServiceContract]
public interface IService1
{
[OperationContract]
ResponseContract Process(RequestContract data);
}

但这并不能解决问题,生成的客户端ResponseContract仍然是使用RequestHeader类型的Header生成的。

甚至将服务代码更改为使用两个不同的消息协定:
[DataContract(Name="RequestHeader")]
public class MyRequestHeader
{
public string RequestorId { get; set; }
}

[DataContract(Name = "ResponseHeader")]
public class MyResponseHeader
{
public string ErrorMessage { get; set; }
}

[MessageContract]
public class RequestContract<TBody>
{
[MessageHeader]
public MyRequestHeader Header { get; set; }

[MessageBodyMember]
public TBody Body { get; set; }
}

[MessageContract]
public class ResponseContract<TBody>
{
[MessageHeader]
public MyResponseHeader Header { get; set; }

[MessageBodyMember]
public TBody Body { get; set; }
}

[ServiceContract]
public interface IService1
{
[OperationContract]
ResponseContract<string> Process(RequestContract<string> data);
}

无法解决问题:

甚至删除所有共享继承和泛型,如下所示:
[DataContract(Name="RequestHeader")]
public class MyRequestHeader
{
public string RequestorId { get; set; }
}

[DataContract(Name = "ResponseHeader")]
public class MyResponseHeader
{
public string ErrorMessage { get; set; }
}

[MessageContract(WrapperName="RequestMessage")]
public class RequestContract
{
[MessageHeader]
public MyRequestHeader Header { get; set; }

[MessageBodyMember]
public string Body { get; set; }
}

[MessageContract(WrapperName = "ResponseMessage")]
public class ResponseContract
{
[MessageHeader]
public MyResponseHeader Header { get; set; }

[MessageBodyMember]
public string Body { get; set; }
}

[ServiceContract]
public interface IService1
{
[OperationContract]
ResponseContract Process(RequestContract data);
}

仍然导致在ResponseMessage中使用RequestHeader。

我认为答案在 this documentation中:

WSDL Considerations

When generating a Web Services Description Language (WSDL) contract from a service that uses message contracts, it is important to remember that not all message contract features are reflected in the resulting WSDL [sic]. Consider the following points: WSDL cannot express the concept of an array of headers. When creating messages with an array of headers using the MessageHeaderArrayAttribute, the resulting WSDL reflects only one header instead of the array.

The resulting WSDL document may not reflect some protection-level information.

The message type generated in the WSDL has the same name as the class name of the message contract type.

When using the same message contract in multiple operations, multiple message types are generated in the WSDL document. The names are made unique by adding the numbers "2", "3", and so on, for subsequent uses. When importing back the WSDL, multiple message contract types are created and are identical except for their names.

关于wcf - 使用消息协定的请求/响应中的不同SOAP header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16578783/

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