gpt4 book ai didi

c# - 从 WCF 中的通用契约(Contract)继承

转载 作者:太空狗 更新时间:2023-10-29 20:32:39 24 4
gpt4 key购买 nike

更多 WCF 问题...:)

我所有的工作流程都实现了相同的 3 种方法。经过大量的复制和粘贴,我决定让它们继承相同的接口(interface):

[ServiceContract(Namespace = "http://schema.company.com/messages/")]
public interface IBasicContract<TRequest, TResponse>
where TRequest : class
where TResponse : class
{
[OperationContract(Name = "GetReport",
Action = "http://schema.company.com/messages/GetReport",
ReplyAction = "http://schema.company.com/messages/GetReportResponse")]
TResponse GetReport(TRequest inquiry);

[OperationContract(Name = "GetRawReport",
Action = "http://schema.company.com/messages/GetRawReport",
ReplyAction = "http://schema.company.com/messages/GetRawReportResponse")]
string GetRawReport(string guid);

[OperationContract(Name = "GetArchiveReport",
Action = "http://schema.company.com/messages/GetArchiveReport",
ReplyAction = "http://schema.company.com/messages/GetArchiveReportResponse")]
TResponse GetArchiveReport(string guid);
}

我还决定创建服务客户端的通用实现:

public class BasicSvcClient<TRequest, TResponse> : ClientBase<IBasicContract<TRequest, TResponse>>, IBasicContract<TRequest, TResponse>
where TRequest : class
where TResponse : class
{
public BasicSvcClient()
{
}

public BasicSvcClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}

public BasicSvcClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public BasicSvcClient(string endpointConfigurationName, EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public BasicSvcClient(Binding binding, EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}

public TResponse GetReport(TRequest inquiry)
{
return Channel.GetReport(inquiry);
}

public string GetRawReport(string guid)
{
return Channel.GetRawReport(guid);
}

public TResponse GetArchiveReport(string guid)
{
return Channel.GetArchiveReport(guid);
}
}

问题是当我尝试使用它时:

using (var client = new BasicSvcClient<TRequest, TResponse>())
{
var response = client.GetReport(inquiry);

context.Response.ContentType = "text/xml";
context.Response.Write(response.AsXML());
}

我总是收到一条错误消息,说它找不到契约(Contract) IBasicContract 的配置,在 .NET 使用的那种奇怪的语法中:

Could not find default endpoint element that references contract 'BasicWorkflow.IBasicContract`2...

我试过这样做:

using (var client = new BasicSvcClient<TRequest, TResponse>("myConfig"))

它没有帮助 - 它仍在寻找该特定契约(Contract)。

我知道 ServiceContract 属性有一个 ConfigurationName 参数,但我不能在编译时使用它,因为我有 许多 从同一个程序调用的工作流(因此有很多配置条目) .有没有办法在运行时设置 ConfigurationName?我认为这是 ClientBase 构造函数应该做的,但显然不是。

[编辑] 这是 .config 文件中的端点,我认为它在这种情况下不是很有用:

<endpoint address="https://localhost/services/Contract.svc"
binding="basicHttpBinding"
bindingConfiguration="httpsDataEndpoint"
contract="IContract" name="IContractSvc" />

[Edit2] 好吧...我找到了一种可行的方法,尽管我对它仍然不完全满意:

using (var wf = new BasicSvcClient<TRequest, TResponse>(
new BasicHttpBinding("httpsDataEndpoint"),
new EndpointAddress("https://localhost/services/Contract.svc")))

我现在遇到的唯一问题是我更愿意从 .config 文件中检索端点地址(使用实际的契约(Contract)名称,如 IContract)。谁能帮我解决这部分问题?

[Edit3] 终于找到了完整的解决方案 :) Reflector 万岁!

var cf = (ClientSection) ConfigurationManager.GetSection("system.serviceModel/client");
foreach (ChannelEndpointElement endpoint in cf.Endpoints)
{
if (endpoint.Name != "ContractSvc")
continue;

using (var wf = new BasicSvcClient<TRequest, TResponse>(
new BasicHttpBinding("httpsDataEndpoint"),
new EndpointAddress(endpoint.Address.ToString())))
{
//... call wf.GetReport()
}
break;
}

最佳答案

“.NET 使用的那种奇怪的语法”实际上是在运行时绑定(bind)到特定类型的通用类型的类型名称。 Typename`n[[Type],...] 其中 n 表示泛型类型中包含的类型参数的数量。

您的端点配置看起来如何?

关于c# - 从 WCF 中的通用契约(Contract)继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/903977/

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