用代码在 IIS 中创建 wcf 服务

Posted

技术标签:

【中文标题】用代码在 IIS 中创建 wcf 服务【英文标题】:Creating wcf service within IIS in code 【发布时间】:2011-12-26 07:43:18 【问题描述】:

我有一个 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 执行并且该服务在预期的 url 上不可用。

总而言之,问题是:

    需要运行 netsh 命令(这是一个配置更改,我不想为每个运行 wcf 服务的站点记录和进行) 破坏了 asp.net 页面

修改后的尝试

使用@Nick Nieslanik 的建议,我构建了以下内容

使用系统;
使用 System.ServiceModel;
使用 System.ServiceModel.Activation;
使用 System.Web;
使用 System.Web.Routing;

[ServiceContract(Namespace = "WcfInIis")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
公共课小

    [运营合同]
    公共布尔 IsTiny()
    
        返回真;
    


公共类 ffServiceHandler : IRouteHandler, IHttpHandler

    #region IRouteHandler 成员

    公共 System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
    
        返回这个;
    

    #endregion

    #region IHttpHandler 成员

    公共布尔 IsReusable
    
        得到返回假; 
    

    公共无效ProcessRequest(HttpContext上下文)
    
        Uri requestUri = context.Request.Url;
        //一些逻辑来决定是否允许这个上下文运行请求的wcf服务
        ServiceHost host = new ServiceHost(typeof(Tiny), new Uri(requestUri.OriginalString.Replace(requestUri.LocalPath, string.Empty)));
        WSHttpBinding 绑定 = 新 WSHttpBinding(SecurityMode.None);
        host.AddServiceEndpoint(typeof(Tiny), binding, "_services/tiny");
        主机.打开(); // 抛出 AddressAlreadyInUseException
    

    #endregion


公共类全球:System.Web.HttpApplication

    protected void Application_Start(object sender, EventArgs e)
    
        RouteTable.Routes.Add(新路由
        (
                "_services/tiny",
                新的 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 文件,如 here 所述。我会试一试并发布我的结果。似乎这就是 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 数据服务时已经这样做了,但我不明白为什么它在这里也不能工作。

【讨论】:

谢谢你的提示,我试试看。 @KeithK 没问题,对不起,我没有提供更详细的信息,我快要出门了。如果我今天有时间,我会尝试更多地充实答案。 刚刚更新了我的问题,尝试使用路由,但出现了 AddressAlreadyInUseException 的新问题。 @KeithK 我今天没时间看这个,但我会尽快处理。

以上是关于用代码在 IIS 中创建 wcf 服务的主要内容,如果未能解决你的问题,请参考以下文章

在客户端应用程序中,在代码中创建 WCF 终结点配置?

WCF IIS Web 服务奇怪的间歇性结果

wcf 端点相对地址

WCF 客户端创建问题

在服务实现中创建 System.Windows.Control 时,WCF 服务不起作用

ASP.NET Web 表单 - 如何异步调用 WCF 异步方法?