Самостоятельно размещенный WCF-сервис Asp.net с относительными путями - PullRequest
3 голосов
/ 25 февраля 2009

Я работаю над приложением WCF, которое по пути будет развернуто на различных серверах, и мне не нужно помнить о необходимости изменять app.config каждый раз, когда я выполняю развертывание. Сначала мой раздел app.config serviceModel выглядел так:

<system.serviceModel>  
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" />  
<behaviors>  
    <serviceBehaviors>  
        <behavior name="MyDefaultServiceBehavior">   
            <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8888/MyService" />  
            <serviceDebug includeExceptionDetailInFaults="true" />  
        </behavior>  
    </serviceBehaviors>  
</behaviors>  
<services>  
    <service behaviorConfiguration="MyDefaultServiceBehavior" name="MyService">   
        <endpoint address="net.tcp://localhost:9001/MyService" binding="netTcpBinding" contract="IMyService" name="NetTcpBinding_IMyService" />  
    </service>  
</services>  

Это прекрасно работает при разработке, когда я обращался к службе, работающей на моей локальной машине. Когда я развернул его, WSDL содержал абсолютные пути, которые все еще указывали на localhost:

<xsd:import schemaLocation=http://localhost:8888/MyService?xsd=xsd0 namespace="http://tempuri.org/" />

Итак, я могу изменить httpGetUrl в app.config следующим образом:

<serviceMetadata httpGetEnabled="true" httpGetUrl=http://devserver1:8888/MyService />

И теперь wsdl корректно работает на этом сервере. Проблема в том, что мне приходится вручную устанавливать адрес в каждом развернутом app.config.

Есть ли способ либо:
1. В wsdl уже есть все, чтобы не было импорта?
или
2. Использовать относительные пути в операторах импорта wsdl?

Или любые другие предложения будут оценены. У меня есть два сервера разработки, на которых развертывание автоматизировано, если бы не эта проблема с wsdl.

Поскольку это только для генерации прокси-сервера, я полагаю, что мог бы сгенерировать прокси-сервер и распространять его самостоятельно, но я бы предпочел, чтобы пользователи сами генерировали прокси-сервер.

Спасибо! Daniel

Ответы [ 2 ]

3 голосов
/ 27 февраля 2009

Вы можете программно установить значение httpGetUrl и задать для него абсолютный адрес, включающий имя компьютера сервера, на котором размещаются службы. Операторы импорта в сгенерированном WSDL также будут использовать имя компьютера сервера.

Если ваш хост WCF создается для вас (например, вы используете хостинг под IIS), вам нужно будет создать пользовательский ServiceHostFactory , чтобы получить доступ к ServiceHost . Например:

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

namespace WebApplication
{
  public class TestServiceHostFactory : ServiceHostFactory
  {
     protected override ServiceHost CreateServiceHost(Type serviceType, 
                                                      Uri[] baseAddresses)
      {
        ServiceHost host = base.CreateServiceHost(serviceType, 
                                                  baseAddresses);
        ServiceMetadataBehavior metadataBehavior = 
                                new ServiceMetadataBehavior();
        metadataBehavior.HttpGetEnabled = true;
        metadataBehavior.HttpGetUrl = new Uri(string.Format(
                              "http://{0}/WebApplication/TestService.svc", 
                              Environment.MachineName));
        host.Description.Behaviors.Add(metadataBehavior);
        return host;
      }
  }
}

Затем вы указываете эту фабрику в файле .svc службы:

<%@ ServiceHost Language="C#" 
                Service="WebApplication.TestService" 
                CodeBehind="TestService.svc.cs" 
                Factory="WebApplication.TestServiceHostFactory" %>

Если вы создаете хост WCF самостоятельно, ваш код будет выглядеть примерно так:

ServiceHost host = new ServiceHost(typeof(WebApplication.TestService));
ServiceMetadataBehavior metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = new Uri(string.Format(
                              "http://{0}/WebApplication/TestService.svc", 
                              Environment.MachineName));
host.Description.Behaviors.Add(metadataBehavior);
2 голосов
/ 03 марта 2009

Ответ, оставленный Даниэлем Ричардсоном выше, является хорошим, и я думаю, что для большинства людей это было бы предпочтительным решением. Однако из-за структуры нашей сети и нескольких людей, которым потребуется доступ к нашему серверу, я делаю что-то немного другое.

Я изменил свой app.config, чтобы иметь httpGetUrl, который содержит «myServiceServer»:

<serviceMetadata httpGetEnabled="true" httpGetUrl=http://myServiceServer:8888/MyService />

Чтобы использовать мой сервис, кто-то должен сначала добавить запись в файле хоста, которая сопоставляет «myServiceServer» с правильным IP-адресом. Это хорошо работает для нашей проблемы, потому что IP-адрес не может быть разрешен с любого общего имени компьютера или IP-адреса. Это происходит из-за разделенных сетей, которые подключаются только через VPN с какой-то NAT-обработкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...