Создание службы wcf в IIS в коде
У меня есть служба 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.ServiceModel;
using System.ServiceModel.Activation;
использование System.Web;
использование System.Web.Routing;
[ServiceContract (Namespace = "WcfInIis")]
[AspNetCompatibilityRequirements (RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
открытый класс Tiny
{
[OperationContract]
публичный bool IsTiny()
{
вернуть истину;
}
}
открытый класс ffServiceHandler: IRouteHandler, IHttpHandler
{
#region IRouteHandler Участники
public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
{
верни это;
}
#endregion
#region IHttpHandler Участники
public bool IsReusable
{
get {return false; }
}
public void ProcessRequest (контекст HttpContext)
{
Uri requestUri = context.Request.Url;
// некоторая логика, чтобы решить, разрешено ли этому контексту запускать запрошенный сервис wcf
ServiceHost host = new ServiceHost(typeof(Tiny), новый Uri(requestUri.OriginalString.Replace(requestUri.LocalPath, string.Empty)));
WSHttpBinding binding = новый WSHttpBinding(SecurityMode.None);
host.AddServiceEndpoint(typeof(Tiny), привязка, "_services/tiny");
host.Open(); // генерирует AddressAlreadyInUseException
}
#endregion
}
открытый класс Global: System.Web.HttpApplication
{
защищенный void Application_Start(отправитель объекта, EventArgs e)
{
RouteTable.Routes.Add(новый маршрут
(
"_Services / крошечное",
новый ffServiceHandler()));
}
}
Эта пересмотренная попытка имеет проблемы:
- Еще нужно запустить команду 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?
Спасибо
Кит
1 ответ
Один из способов сделать это - использовать 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 Data Services, и я не понимаю, почему это не может работать здесь.