У меня есть служба 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.
В итоге проблемы:
- Нужно запустить команду netsh (это изменение конфигурации, которое мне не нужно записывать и вносить для каждого сайта, на котором запущены службы wcf)
- разрывает страницы 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>
У этой исправленной попытки есть проблемы:
- Еще нужно запустить команду netsh (это изменение конфигурации, которое мне не нужно записывать и вносить для каждого сайта, на котором запущены службы wcf)
- Теперь я получаю
[AddressAlreadyInUseException: HTTP could not register URL http://+:56134/ because TCP port 56134 is being used by another application.]
, когда пытаюсь зайти на сайт. Это вызвано тем, что служба пытается запустить службу wcf на том же порту, на котором работает сайт.
Краткое описание
Может кто-нибудь помочь мне заставить одного из них работать так:
- служба wcf запускается успешно
- служба работает только по своему полному URL (не только по пути)
- не мешает страницам asp.net
- Не требует изменений конфигурации на сервере (т. Е. Не выполняется команда netsh)
Я думаю, что альтернативным решением может быть создание динамического файла .svc, как объяснено здесь . Я попробую и опубликую свои результаты. Похоже, именно так asp.net обрабатывает файлы .svc при их запросе, потому что как еще можно избежать исключения AddressAlreadyInUseException?
Спасибо
Keith