gpt4 book ai didi

.net - 在 WCF 服务中,如何公开只能访问某些方法的第二个端点?

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

我有一项服务,其中包含一系列用于为我们的网站创建和管理 Assets 的方法。它还具有两个需要从外部访问的方法,例如“GetConfiguration”和“GetElement”。我想使用不同的 ServiceContracts 在不同的端点公开相同的服务。但我希望这两种方法在两个端点都可用。

这是我的 App.Config 的相关部分:

  <service name="Manager.Manager" behaviorConfiguration="Manager.ManagerBehavior">
<endpoint address="" binding="customBinding" bindingConfiguration="NetHttpBinding" contract="Manager.IManager" />
<endpoint address="Runtime" binding="customBinding" bindingConfiguration="NetHttpBinding" contract="Manager.IPublicManager" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>

当我将这个东西加载到 IIS 并尝试访问它时,我收到以下错误:

 An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior
contract: http://tempuri.org/:IPublicManager ----> System.InvalidOperationException: The Manager.IPublicManager.GetConfiguration operation references a message element [http://tempuri.org/:GetConfiguration] that has already been exported from the Manager.IManager.GetConfiguration operation. You can change the name of one of the operations by changing the method name or using the Name property of OperationContractAttribute. Alternatively, you can control the element name in greater detail using the MessageContract programming model.
at System.ServiceModel.Description.MessageContractExporter.AddElementToSchema(XmlSchemaElement element, String elementNs, XmlSchemaSet schemaSet)
at System.ServiceModel.Description.MessageContractExporter.ExportWrappedPart(Message message, String elementName, String elementNs, XmlSchemaSet schemaSet, Boolean skipSchemaExport)
at System.ServiceModel.Description.DataContractSerializerMessageContractExporter.ExportBody(Int32 messageIndex, Object state)
at System.ServiceModel.Description.MessageContractExporter.ExportMessage(Int32 messageIndex, Object state)
at System.ServiceModel.Description.MessageContractExporter.ExportMessageContract()
at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension)
--- End of inner ExceptionDetail stack trace ---
at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension)
at System.ServiceModel.Description.WsdlExporter.CallExportContract(WsdlContractConversionContext contractContext)
at System.ServiceModel.Description.WsdlExporter.ExportContract(ContractDescription contract)
at System.ServiceModel.Description.WsdlExporter.ExportEndpoint(ServiceEndpoint endpoint, XmlQualifiedName wsdlServiceQName)
at System.ServiceModel.Description.WsdlExporter.ExportEndpoints(IEnumerable`1 endpoints, XmlQualifiedName wsdlServiceQName)
at System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata()
at System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized()
at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.InitializationData.InitializeFrom(ServiceMetadataExtension extension)
at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.GetInitData()
at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.TryHandleDocumentationRequest(Message httpGetRequest, String[] queries, Message& replyMessage)
at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.ProcessHttpRequest(Message httpGetRequest)
at SyncInvokeGet(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

所以它不喜欢操作具有相同的名称。有任何想法吗?它们都使用相同的服务类。也许我只是以完全错误的方式处理问题?

最佳答案

虽然这并不能完全解决你的问题,但希望能对你有所帮助。我使用 webHttpBinding,因为我对此最熟悉。

这里的想法是将公共(public)和私有(private)功能分成两个单独的接口(interface):

[ServiceContract]
public interface IPrivate : IPublic
{
[WebGet(UriTemplate = "/admin")]
[OperationContract]
int PrivateStuff();
}

[ServiceContract]
public interface IPublic
{
[WebGet(UriTemplate = "/common")]
[OperationContract]
int PublicStuff();
}

正如您所看到的,IPrivate 的实现者还必须实现 IPublic,为什么服务实现 IPrivate 以便可以同时公开。

服务实现现在可以公开为 IPublicIPrivate,并且端点可以在服务下公开(“service1.svc”):

    <system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="ManagerService.Service">
<endpoint address="private" behaviorConfiguration="rest" contract="ManagerService.IPrivate" binding="webHttpBinding"/>
<endpoint address="public" behaviorConfiguration="rest" contract="ManagerService.IPublic" binding="webHttpBinding" />
<endpoint address="/private/mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<endpoint address="/public/mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>

该服务现在在 http://host/service1.svc/common 的公共(public)部分公开,而私有(private)版本在 http://host/service1.svc 公开/管理员

元数据交换似乎无法正常工作,但这可能是由于绑定(bind)类型造成的。

关于.net - 在 WCF 服务中,如何公开只能访问某些方法的第二个端点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8452126/

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