我有一个现在正在使用一年多的WCF,由其他人编码,我正在尝试重构它,但文件夹结构的组织方式和包含这些方法的svc.cs文件不是我的我习惯从WCF样本I completed。
这是我想要实现的目标。由于去年没有任何设置发生变化,我被要求在代码中硬编码所有服务的设置。该服务托管在大型和现有Web应用程序中(我必须将其留在那里),svc文件包含客户端调用的方法,并且此svc.cs文件不位于虚拟目录的根目录但是更深层,让我们说<virtualDirectory>/WebServices/PotatoWebService/PotatoWebService.svc
,确实没有在虚拟目录根目录中导致任何问题吗?
由于我正在将配置移出配置文件,我现在正在创建服务,主机,端点,绑定到Web应用程序的global.axax.cs文件中ApplicationStart()
,这是正确的地方在Web应用程序中启动此服务?
是否可以在代码中移动所有内容,而不仅仅是endPoint,还可以移动web.config文件中的行为,服务和system.ServiceModel的整个内容,以“清理”配置文件,并停止使用他们不需要的设置吓跑支持和配置管理器?
如果是的话,我已经尝试了2天才能让这个工作没有成功。我现在根据netstat得到的是一个服务启动并运行但是当我在浏览器中打开我的svc文件时,一个异常弹出说服务dosent定义了任何端点,尽管根据nstat我运行的服务:
netstat -a | find LISTENING
...
TCP machineName:8097 elamontagne.potato.com:0 LISTENING
...
所以我有一个服务正在运行,但svc文件不知道它并且无法使用它的端点,客户端试图联系服务而无法找到它因为服务没有端点,任何提示都要缩小关于这个问题,有关解决这种情况的提示吗?
//Address
string hostingAddress = "PotatoVirtualDirectory/PotatoService/PotatoService.svc";
// Binding
BasicHttpBinding PotatoServiceBinding = ConfigurePotatoServiceBinding(serviceSecurityMode);
// Contract
Type PotatoContract = typeof(IPotatoService);
// Host
this.PotatoServiceHost = new ServiceHost(typeof(PotatoService), new Uri("http://localhost:8097"));
// Endpoint
this.PotatoServiceHost.AddServiceEndpoint(PotatoContract, PotatoBinding, hostingAddress);
// Behavior
ConfigurePotatoServiceBehavior(this.PotatoServiceHost, PotatoServiceBinding);
// Name
this.PotatoServiceHost.Description.Name = "PotatoNamespace.PotatoService";
//Start!
this.PotatoServiceHost.Open();
这个编译并运行,它为我提供了一个处于打开状态的运行服务。客户端无法在通常的位置找到它,并且svc文件抱怨它在web.config中没有任何内容并且想要一个端点ServiceHasZeroAppEndpoints:“服务没有应用程序(非基础架构)端点”
我在调试中逐步完成代码,所有看起来都很好,服务是开放的,我缺少什么,有什么提示可以缩小这个问题?
编辑:从服务主机工厂派生工作顺利,谢谢!
答案 0 :(得分:2)
您可以编写custom service host factory,您可以在其中以编程方式配置服务,而不是使用配置文件。然后在.svc标记文件中配置此自定义工厂:
<%@ServiceHost Factory="CustomFactory" Service="MyService" %>
答案 1 :(得分:1)
在ApplicationStart()的就是这样的 正确的地方开始这项服务 在Web应用程序中?
没有。您不能同时拥有ASP.NET运行时托管和通过代码显式托管。但是你可以像Darin所描述的那样声明一个自定义服务工厂。
确实没有在虚拟目录根目录中导致任何问题吗?
这没问题。
另外,请问为什么要以编程方式执行此操作?编写和测试所有代码是不是很痛苦?如果您不喜欢Web.config文件中的大块WCF配置,可以将WCF配置放入单独的配置文件中。
通常,WCF服务的配置方式始终相同。无论是自托管还是IIS托管都没有区别。 ServiceHost具有默认实现方式,即如何构造服务描述和结束点。默认情况下,它将尝试在应用程序配置文件中找到服务配置。在你的情况下,Web.config。使用过的ServiceHost在自托管和IIS托管中完全相同。
不同之处在于此ServiceHost是如何实现的。在自托管中,您可以完全控制,因为您必须自己创建ServiceHost实例。在IIS托管方案中,ASP.NET运行时将使用ServiceHostFactory来实例化您的服务主机。
因此,如果您想手动配置ServiceHost,则必须创建自己的ServiceHostFactory并在SVC文件中引用它。
回到你的问题:
如果我理解正确,使用web.config中的设置会自动在iis进程中的aspnet_wp.exe中托管服务
“托管”只是意味着它在Web应用程序中运行。只要将服务部署为Web应用程序的一部分,它就始终由IIS托管。无论您如何以及在何处配置它,都没有其他独立的可执行文件,
并在客户端调用.svc文件时自动启动?
在ASP.NET Web应用程序中,所有请求的HTTP都通过ASP.NET“管道”。管道有一组处理程序,可以拾取和处理请求。对于WCF,这是System.ServiceModel.Activation.HttpHandler。这个稍微简化的处理程序将检查它是否具有有效的ServiceHost,如果没有使用ServiceHostFactory创建一个。处理程序绝对不关心你是否已经在Global.asax中创建了一个ServiceHost。
如果我从global.axax.cs开始使用我的ServiceHost.Open(),那么它会明确地启动它,而不是由iis托管。
没有。您在Web应用程序中运行的任何代码都在IIS托管的应用程序域中运行。
,或者仍由IIS托管,但忽略了svc文件?
是的。但更多的是另一种方式。您的Global.asax代码将被忽略,WCF激活仍会尝试创建另一个服务主机。
然后在这里建议第3个选项,从主机工厂派生的类将从svc调用,服务将以与web.config中的设置相同的方式启动?
这是唯一的选择。抓住RedGates Reflector(它是免费的)并反汇编ServiceHostFactory类。它相当小。你会发现你几乎可以从那里的Global.asax复制你的代码并且你已经完成了。 ......当然也应该有大量的文件......
希望有所帮助!
答案 2 :(得分:0)
听起来你可以使用以下方法。
您可以从Web配置中引用自己的配置文件。 为了让这个想法更进一步,请看看Managing ASP.NET Development, Staging and Production Connection Strings (without pulling your hair out)
<configuration>
<appSettings>
<add key="ServerConfigPath" value="~/ServerConfig.config"/>
</appSettings>
</configuration>