如何获取WCF应用程序的工作路径?

70
我想获取一个WCF应用程序的工作目录。我该如何获取它?
如果我尝试:
HttpContext.Current.Request.MapPath(HttpContext.Current.Request.ApplicationPath)

我遇到了空引用异常(Http.Current对象为空)。


我所说的“工作目录”是我的WCF服务运行的文件夹。如果我设置aspNetCompatibilityEnabled="true",则会出现以下错误:

服务器没有提供有意义的回复;这可能是由于合同不匹配、过早的会话关闭或内部服务器错误引起的。

7个回答

174

我需要在我的IIS6托管的WCF应用程序中获取相同的信息,我发现这对我有用:

string apPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

像往常一样,结果可能因人而异。


2
这个解决方案对我来说效果最好- 我建议使用它而不是必须进行各种其他的设置更改... - Sam Schutte
我没有 System.Web.Hosting,我真的不知道原因是什么…… - Dzung Nguyen
谢谢 ongle :) 我成功地使用了 AppDomain :) - Dzung Nguyen
2
@nXqd:您需要确保未选择框架的客户端配置文件版本。 - Roger Lipscombe
这个答案救了我的一天。请将其设置为已接受的答案,因为并不总是首选使用ASP.NET兼容性。这个解决方案可以在ASP.NET兼容性开启或关闭时都能工作。 - Roy
这个解决方案对我很有帮助。 - Hidayat Arghandabi

32

请查看下面ongle的回答,它比这个更好。

在获取更多信息后更新

以下内容对我有效。我测试了一个新的WCF服务,通过Service1.svc托管在IIS上。

  1. <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>添加到web.config中。<system.serviceModel>..</ ..> 已存在。
  2. 为服务添加AspNetCompatibilityRequirementsAttribute属性,并设置允许模式。
  3. 使用HttpContext.Current.Server.MapPath(".");获取根目录。

下面是服务类的完整代码。我在IService1接口中没有进行任何更改。

[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
    public void DoWork()
    {
        HttpContext.Current.Server.MapPath(".");
    }
}

下面是从web.config中摘录的一部分内容。

<system.serviceModel>
    <!-- Added only the one line below -->
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

    <!-- Everything else was left intact -->
    <behaviors>
        <!-- ... -->
    </behaviors>
    <services>
        <!-- ... -->
    </services>
</system.serviceModel>

旧答案

你所说的工作文件夹是什么意思?WCF服务可以以多种方式和不同的终结点进行托管,因此工作文件夹有些模糊。

您可以通过调用Directory.GetCurrentDirectory()来检索普通的“工作文件夹”。

HttpContext是一个ASP.Net对象。即使WCF可以在IIS上托管,它仍然不是ASP.Net,因此大多数ASP.Net技术默认情况下都不起作用。 OperationContext是WCF的HttpContext等效项。OperationContext包含关于传入请求、传出响应以及其他信息的信息。

尽管最简单的方法可能是通过在web.config中切换到ASP.Net兼容性模式来运行服务。这应该为您提供访问ASP.Net HttpContext的权限,但它将限制您*HttpBindings和IIS托管。要切换兼容模式,请将以下内容添加到web.config中。

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>

我所指的“工作文件夹”,是我的WCF服务运行的物理路径。我有一个XML文件在那里,我想读取它。Directory.GetCurrentDirectory()不起作用,当我尝试使用您提到的兼容性模式设置时,我遇到了以下错误: 服务器没有提供有意义的回复;这可能是由于合同不匹配、会话过早关闭或内部服务器错误导致的。 - Stefan Filip
9
使用以下代码,可同时兼容ASP.NET上下文和非ASP.NET环境:string path = HttpContext.Current != null ? HttpContext.Current.Server.MapPath("~/folder/file") : System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "folder", "file"); - Simon_Weaver
如果您需要通过多线程调用方法并访问HttpContext.Current,则AspNetCompatibilityMode将无法工作。 - Anchit

21

根据你的需求而定。我通常想要解析一个像"~/folder/file"这样的url。以下是解决方法。

System.Web.Hosting.HostingEnvironment.MapPath("~/folder/file");

19

更普遍地说,我正在使用这一个

AppDomain.CurrentDomain.BaseDirectory

对于没有 System.Web 的解决方案,可以使用 +one。 - Filip

12

虽然aspNetCompatibilityEnabled="true"应该解决了我的问题,但我遇到了以下错误:

服务器没有提供有意义的回复;这可能是由于合同不匹配、会话过早关闭或内部服务器错误引起的。

通过从当前应用程序域获取运行中WCF服务的物理路径来解决了我的问题:

AppDomain.CurrentDomain.BaseDirectory

1
如果您手动运行ServiceHost,则只有AppDomain.CurrentDomain.BaseDirectory指向正确的源代码。谢谢您! - mastak

3
为了引用像HttpContext对象这样的ASP.NET功能,您需要在ASP.NET兼容模式下运行WCF应用程序。这篇文章解释了如何做到这一点。

2

在WCF中使用HostingEnvironment.ApplicationPhysicalPath来查找应用程序的物理路径。 使用命名空间 using System.Web.Hosting;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接