Создание службы wcf в IIS в коде - PullRequest
0 голосов
/ 10 ноября 2011

У меня есть служба saas, которая имеет несколько групп сайтов (каждая группа, принадлежащая разному клиенту), работающих на одном сайте IIS с другим iis-связыванием / именем хоста, так что это план.

Проблема в том, что у меня есть службы WCF для сайтов, и они работают на .net3.5 У меня не может быть нескольких базовых адресов, использующих один и тот же протокол. Я мог бы обновить до .net4 и , чтобы включить , но я бы предпочел запускать только те службы, которые мне нужны, в настоящее время по одному сайту на группу, а также не нужно продвигать обновление.

Я пытался сделать это, создавая службы в коде (две попытки ниже). Это дает мне полный контроль над тем, когда и где создаются сервисы (а также за счет удаления фрагмента почти никогда не меняющегося конфигурации wcf из web.config).

Исходная попытка:

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Web;

[ServiceContract(Namespace = "WcfInIis")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Tiny
{
    [OperationContract]
    public bool IsTiny()
    {
        return true;
    }
}

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        Uri requestUri = HttpContext.Current.Request.Url;
        //some logic to decide if this context is allowed to run the wcf service requested
        ServiceHost host = new ServiceHost(typeof(Tiny), new Uri(requestUri.OriginalString.Replace(requestUri.LocalPath, string.Empty)));
        WSHttpBinding binding = new WSHttpBinding(SecurityMode.None);
        host.AddServiceEndpoint(typeof(Tiny), binding, "_service/tiny");
        host.Open();
    }
}

Проблема с кодом в том, что когда он запускается, я получаю AddressAccessDeniedException: HTTP could not register URL http://+:56134/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details).]. Очевидно, что это работает в Кассини, но я получаю то же сообщение при запуске в IIS.

Когда я перехожу по ссылке и выполняю команду, которую она предлагает netsh http add urlacl url=http://+:56134/ user=domain\username Я получил пустой экран, поскольку ни один из asp.net не выполняется, и служба недоступна по указанному URL.

В итоге проблемы:

  1. Нужно запустить команду netsh (это изменение конфигурации, которое мне не нужно записывать и вносить для каждого сайта, на котором запущены службы wcf)
  2. разрывает страницы asp.net

Пересмотренная попытка

Используя предложение @Nick Nieslanik, я построил следующее

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Web;
using System.Web.Routing;

[ServiceContract(Namespace = "WcfInIis")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Tiny
{
    [OperationContract]
    public bool IsTiny()
    {
        return true;
    }
}

public class ffServiceHandler : IRouteHandler, IHttpHandler
{
    #region IRouteHandler Members

    public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return this;
    }

    #endregion

    #region IHttpHandler Members

    public bool IsReusable
    {
        get { return false; }
    }

    public void ProcessRequest(HttpContext context)
    {
        Uri requestUri = context.Request.Url;
        //some logic to decide if this context is allowed to run the wcf service requested
        ServiceHost host = new ServiceHost(typeof(Tiny), new Uri(requestUri.OriginalString.Replace(requestUri.LocalPath, string.Empty)));
        WSHttpBinding binding = new WSHttpBinding(SecurityMode.None);
        host.AddServiceEndpoint(typeof(Tiny), binding, "_services/tiny");
        host.Open(); // throws AddressAlreadyInUseException
    }

    #endregion
}

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        RouteTable.Routes.Add(new Route
        (
                "_services/tiny",
                new ffServiceHandler()
        ));
    }
}<code>
</code>

У этой исправленной попытки есть проблемы:

  1. Еще нужно запустить команду netsh (это изменение конфигурации, которое мне не нужно записывать и вносить для каждого сайта, на котором запущены службы wcf)
  2. Теперь я получаю [AddressAlreadyInUseException: HTTP could not register URL http://+:56134/ because TCP port 56134 is being used by another application.], когда пытаюсь зайти на сайт. Это вызвано тем, что служба пытается запустить службу wcf на том же порту, на котором работает сайт.

Краткое описание

Может кто-нибудь помочь мне заставить одного из них работать так:

  1. служба wcf запускается успешно
  2. служба работает только по своему полному URL (не только по пути)
  3. не мешает страницам asp.net
  4. Не требует изменений конфигурации на сервере (т. Е. Не выполняется команда netsh)

Я думаю, что альтернативным решением может быть создание динамического файла .svc, как объяснено здесь . Я попробую и опубликую свои результаты. Похоже, именно так asp.net обрабатывает файлы .svc при их запросе, потому что как еще можно избежать исключения AddressAlreadyInUseException?

Спасибо

Keith

1 Ответ

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

Один из способов сделать это - использовать ASP.NET UrlRouting и реализовать объект IRouteHandler, который будет ускорять хосты службы WCF ...

http://msdn.microsoft.com/en-us/library/system.web.routing.iroutehandler.gethttphandler.aspx

http://msdn.microsoft.com/en-us/library/cc668201.aspx

Я делал это в прошлом, когда настраивал службы данных WCF, и я не понимаю, почему это не может работать и здесь.

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