Как мне установить bindingNamespace при использовании безфайловой активации? - PullRequest
4 голосов
/ 31 мая 2011

Я пытаюсь удалить файл tempuri.org из службы WCF, размещенной в IIS, с помощью безфайловой активации .Я следовал инструкциям здесь и застрял, когда дело доходит до атрибута bindingNamespace в Web.config, потому что я использую активацию без файлов.

My Web.config просто содержит:

<serviceActivations>
    <add relativeAddress="Foo.svc"
         service="BigCorp.Services.Foo, BigCorp.Services"
         />
</serviceActivations>

Поэтому у меня нет узла <endpoint> для установки bindingNamespace.

Что делать?

Ответы [ 6 ]

4 голосов
/ 01 ноября 2011

Вы все еще можете использовать узлы <services> и, следовательно, <endpoint> с активацией без файлов WCF.Взгляните на следующий пример, где я даже изменяю wsHttpBinding по умолчанию, чтобы добавить безопасность транспорта и включить поведение по умолчанию;все для активации файла "Module1.DES.ExternalDataService" без файлов.

  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding messageEncoding="Mtom">
          <security mode="Transport"/>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service name="Module1.DES.ExternalDataService">
        <endpoint binding="wsHttpBinding" bindingNamespace="" contract="Module1.DES.IExternalDataService"/>
      </service>
    </services>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
      <serviceActivations>
        <add relativeAddress="ExternalDataService.svc" service="Module1.DES.ExternalDataService"/>
      </serviceActivations>

    </serviceHostingEnvironment>
  </system.serviceModel>

Надеюсь, это поможет.

3 голосов
/ 31 мая 2011

Чтобы изменить пространство имен привязки, вы можете использовать собственную фабрику (вместо предоставленной по умолчанию), где вы можете изменить все свойства привязки:

  <serviceActivations>
    <add relativeAddress="Foo.svc"
         service="BigCorp.Services.Foo, BigCorp.Services"
         factory="BigCorp.Services.FooHostFactory, BigCorp.Services"/>
  </serviceActivations>

И фабрика:

public class FooHostFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        return new FooServiceHost(serviceType, baseAddresses);
    }
}
public class FooServiceHost : ServiceHost
{
    public FooServiceHost(Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses) { }

    protected override void OnOpening()
    {
        base.OnOpening();
        foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
        {
            if (!endpoint.IsSystemEndpoint)
            {
                endpoint.Binding.Namespace = "http://services.bigcorp.com/foo";
            }
        }
    }
}
0 голосов
/ 26 марта 2013

Если вы используете функцию активации без файлов в WCF 4.0 через элемент конфигурации serviceActivations, вы можете переопределить базовый метод AddDefaultEndpoints в реализации ServiceHost.

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace MyApp.WS.WCFServiceHost
{

    public class MyHostFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            return new EDOServiceHost(serviceType, baseAddresses);
        }
    }

    public class MyServiceHost : ServiceHost
    {
        public EDOServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses) { }


        public override System.Collections.ObjectModel.ReadOnlyCollection<ServiceEndpoint> AddDefaultEndpoints()
        {
            var endpoints = base.AddDefaultEndpoints();

            foreach (ServiceEndpoint endpoint in endpoints)
            {
                if (!endpoint.IsSystemEndpoint)
                {
                    endpoint.Binding.Namespace = NamespaceConstants.MyNamespace;
                }
            }

            return endpoints;
        }


    }
}

Или вы можете простоиспользуйте только конфигурацию, единственным недостатком этого является то, что вы слегка нарушаете принцип СУХО, поскольку теперь у вас есть две точки для поддержки строки пространства имен, одна в ваших константах и ​​одна в файле конфигурации.

В следующем примереЯ использую поведение WCFExtrasPlus, чтобы «сгладить» WSDL.Вам это не нужно, если вы развертываете на сервере .net 4.5 IIS7, поскольку у вас все равно будет доступ к плоскому WSDL, который является новой функцией, встроенной в платформу 4.5, я отвлекся.

В примере также предполагается, чтодва контракта на обслуживание и две реализации поведения сервиса этих контрактов.

<system.serviceModel>

    <services>
      <service name ="MyApp.WS.ServiceBehaviour.Enquiries">
        <endpoint bindingNamespace="MyApp.WS" binding="basicHttpBinding" contract="MyApp.WS.ServiceContract.IEnquiries" />
      </service>

      <service name ="MyApp.WS.ServiceBehaviour.CallLogging">
        <endpoint bindingNamespace="MyApp.WS" binding="basicHttpBinding" contract="MyApp.WS.ServiceContract.ICallLogging" />
      </service>
    </services>

    <serviceHostingEnvironment>
      <serviceActivations>
        <add relativeAddress="Enquiries.svc" 
             service="MyApp.WS.ServiceBehaviour.Enquiries" 
             />
        <add relativeAddress="CallLogging.svc" 
             service="MyApp.WS.ServiceBehaviour.CallLogging" 
              />
      </serviceActivations>
    </serviceHostingEnvironment>

    <extensions>
      <behaviorExtensions> <!-- The namespace on the service behaviour, the service contract, the data contract and the binding must all be set to the same.-->
        <add name="wsdlExtensions" type="WCFExtrasPlus.Wsdl.WsdlExtensionsConfig, WCFExtrasPlus, Version=2.3.1.8201, Culture=neutral, PublicKeyToken=f8633fc5451b43fc" />
      </behaviorExtensions>
    </extensions>

    <behaviors>
      <endpointBehaviors>
        <behavior>
          <wsdlExtensions singleFile="true" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Для справки контракты на обслуживание;

[ServiceBehavior(Namespace = NamespaceConstants.MyNamespace)]
public class CallLogging : ICallLogging 
{
}

[ServiceBehavior(Namespace = NamespaceConstants.MyNamespace)]
public class Enquiries : IEnquiries
{
}

NB: Пространству имен не нужно http:// в своем имени.Это может быть пространство имен вашего проекта, если вам нравится, например, MyApp.MyProject.Somthing.См URN

0 голосов
/ 03 ноября 2011

В конце я использовал пользовательский BindingNamespaceAttribute, полученный из этого примера .

0 голосов
/ 31 мая 2011

Помимо очевидного изменения пространств имен контракта службы / данных , вы также можете установить пространство имен для самого объекта Binding, а также пространство имен в описании службы:

Binding binding = new BasicHttpBinding();
binding.Namespace = "urn:binding_ns";
ServiceHost host = new ServiceHost(typeof(MyService), address);
var endpoint = host.AddServiceEndpoint(typeof(IMyService), binding, "");
host.Description.Namespace = "urn:desc_ns";

Последнее - это то, что контролирует targetNamespace самого документа WSDL.

0 голосов
/ 31 мая 2011

В вашем сервисном коде вы указываете:

[ServiceContract(Namespace="http://your-url")]
public interface IMyInterface { ... }

, и вы также можете указать его для контрактов данных:

[DataContract(Namespace="http://your-url/data")]
public class MyData { ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...