Load custom configuration file in WCF relative to Working Directory
I have a WCF service library that reads a xml file that's located in the WCF publish location. The project is not client profile.
When I debug in the WCF test client it works fine with:
XDocument xDoc = XDocument.Load(@".\PaymentAvailability.xml");
But when consuming the service from a website it says it cannot find PaymentAvailability.xml ... it looks like its trying to get the location of the xml file from the consuming app.
I've tried the answers posted开发者_如何学C here but no luck How to get working path of a wcf application?
System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath
returns null
With AspNetCompatability HttpContext.Current.Server.MapPath(".");
also doesn't return anything
This is a really bad practice, you should place the configuration for your library in the .config file for the application that is using your library, using custom section handlers (which the Configuration Section Designer does very well for you) if you want strongly typed XML configuration.
The reasoning being that it's your application that you are configuring; if your library really operated so independently of your application, then you should reconsider whether or not the library should not be it's own application.
One option that you have to mitigate this to create a custom config section handler and then use the configSource
attribute. While you won't be able to use one single file (the attribute does not allow for absolute paths), you can copy the one file into the bin directory of each application.
Note that you'll have to explicitly get the config section, but you have to do that anyway now to load your file, but at least you'll be more in line with the configuration manager.
In general
System.Reflection.Assembly.GetExecutingAssembly().Location
gives you the phyisical path of the executing assembly.
On the msdn page you can see the difference between GetExecutingAssembly, GetEntryAssembly and GetCallingAssembly.
That said, it may not be a good idea anyways (see casperOne's answer).
This works, but from the other answers, I'm going to see if this is indeed a bad practice and can be done a better way.
ServiceHostBase hostBase = OperationContext.Current.Host;
VirtualPathExtension virtualPathExtension = hostBase.Extensions.
Find<VirtualPathExtension>();
XDocument xDoc;
if (virtualPathExtension != null)
{
/// It’s hosted.
xDoc = XDocument.Load(Path.Combine(
HostingEnvironment.ApplicationPhysicalPath, AvailabilityFileName));
}
else
{
/// It’s not hosted.
xDoc = XDocument.Load(AvailabilityFileName);
}
精彩评论