在代码中在IIS中创建wcf服务

时间:2011-11-10 16:10:40

标签: wcf iis-7

我有一个saas服务,它有多个站点组(每个组属于不同的客户端)在一个IIS站点中运行,具有不同的iis绑定/主机名,这就是计划。

问题是我有网站的WCF服务以及它们在.net3.5上运行我不能有多个使用相同协议的基地址。我可以升级到.net4和enable this,但我更愿意只启动我必须的服务,目前每组一个站点,也不必提前升级。

我一直试图通过在代码中创建服务来做到这一点(下面两次尝试)。这使我可以完全控制服务的创建时间和位置(以及从web.config中删除几乎不会更改wcf配置的块)。

原创尝试:

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执行,并且该服务在目标网址上不可用。

总之,问题是:

  1. 需要运行netsh命令(这是一个配置更改,我不需要为运行wcf服务的每个站点记录和制作)
  2. 打破了asp.net页面
  3. 修改后的尝试

    使用@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()
            ));
        }
    }
    

    此修订后的尝试存在以下问题:

    1. 仍然需要运行netsh命令(这是一个配置更改我宁愿不需要为运行wcf服务的每个站点记录和制作)
    2. 当我尝试访问该网站时,我现在获得[AddressAlreadyInUseException: HTTP could not register URL http://+:56134/ because TCP port 56134 is being used by another application.]。这是因为服务尝试在网站运行的同一端口上启动wcf服务。
    3. 摘要

      任何人都可以帮助我让其中一个工作:

      1. wcf服务成功启动
      2. 服务仅对其完整网址(不仅仅是路径)进行操作
      3. 不会干扰asp.net页面
      4. 不需要对服务器进行配置更改(即不运行netsh命令)
      5. 我认为另一种解决方案可能是创建动态.svc文件,如here所述。我会给你一个去发布我的结果。看起来这就是asp.net在请求它们时如何处理.svc文件,因为你怎么能避免使用AddressAlreadyInUseException呢?

        由于

        基思

1 个答案:

答案 0 :(得分:0)

实现此目的的一种方法是使用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数据服务时已经这样做了,我不明白为什么它也不能在这里工作。