我有一个saas服务,它有多个站点组(每个组属于不同的客户端)在一个IIS站点中运行,具有不同的iis绑定/主机名,这就是计划 .
问题是我有网站的WCF服务以及它们在.net3.5上运行我不能有多个使用相同协议的基地址 . 我可以升级到.net4和enable this,但我更愿意只启动我必须的服务,目前每组一个站点,也不必提前升级 .
我一直试图通过在代码中创建服务来做到这一点(下面两次尝试) . 这使我可以完全控制服务的创建时间和位置(以及从web.config中删除几乎不会更改wcf配置的块) .
Original Attempt:
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).] . 显然,这是在Cassini中运行但在IIS中运行时我收到相同的消息 .
当我按照链接并执行命令它建议 netsh http add urlacl url=http://+:56134/ user=domain\username 我得到一个空白屏幕,因为没有asp.net执行,并且该服务在目标网址上不可用 .
总之,问题是:
需要运行netsh命令(这是一个配置更改,我不需要为运行wcf服务的每个站点记录和制作)
打破了asp.net页面
Revised Attempt
使用@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()
));
}
}
此修订后的尝试存在以下问题:
仍然需要运行netsh命令(这是一个配置更改,我不需要为运行wcf服务的每个站点记录和制作)
当我尝试访问该网站时,我现在得到 [AddressAlreadyInUseException: HTTP could not register URL http://+:56134/ because TCP port 56134 is being used by another application.] . 这是因为服务尝试在网站运行的同一端口上启动wcf服务 .
Summary
任何人都可以帮助我让其中一个工作:
wcf服务成功启动
服务仅在其完整URL(不仅仅是路径)上运行
不会干扰asp.net页面
不需要对服务器进行配置更改(即不运行netsh命令)
我认为另一种解决方案可能是创建动态.svc文件,如here所述 . 我'll give that a go and post my results. It seems like that' s asp.net在请求它们时如何处理.svc文件,因为你怎么能避免AddressAlreadyInUseException呢?
谢谢
基思