Home Articles

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

Asked
Viewed 237 times
0

我有一个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呢?

谢谢

基思

1 Answer

Related