WCF File Not Found when hosted on IIS - c#

I have a few XML files in my WCF service that are mapped like
\\servermain\D$\apps\dataservice\bin\Type\FileName.xml
\\servermain\D$\apps\dataservice\bin\Type\Config\ConfigFile.xml
I refer to these files in my program by using
.\\Type\\FileName.xml
.\\Type\\Config\\ConfigFile.xml
When i run my application through the console as a service it works completely fine... when i deploy it to the IIS server i get an error saying the file can't be found...
Here is a bit of text from my result (My WCF service spits out JSON)
"Message":"IO Exception C:\\Windows\\SysWOW64\\inetsrv","Detail":"File does not exist: .\\Type\\Config\\ConfigFile.xml"
I used System.Environment.CurrentDirectory to get the current directory for the error above.
How do i configure it so that my application path is actually
\\servermain\D$\apps\dataservice\bin\
I would prefer if I wouldn't have to hardcode the actual path of the file, because developers would be running this service through their local machines as well.

I would prefer if I wouldn't have to hardcode the actual path of the file, because developers would be running this service through their local machines as well.
That's what you are doing right now. A possible way to resolve this hardcoded paths is pretty easy:
Every WCF service comes with a config file. You can easily add the appSettings element to your config and specify absolute or relative paths to any additional file.
E.g. for executing the console:
<appSettings>
<add key="ConfigFile" value=".\\Type\\Config\\ConfigFile.xml" />
</appSettings>
And instead for the IIS hosted config:
<appSettings>
<add key="ConfigFile" value="\\servermain\D$\apps\dataservice\bin\Type\Config\ConfigFile.xml" />
</appSettings>
You can then access those values via the System.Configuration.ConfigurationSettings class.
UPDATE:
The System.Configuration.ConfigurationSettings is marked as obsolete. Instead, the System.Configuration.ConfigurationManager or System.Configuration.WebConfigurationManager should be used.

Related

Access web.config settings from external program

I have an application residing in a virtual directory. It has the following setting in its Web.config:
<appSettings>
<add key="SomePath" value="C:\Somepath\whatever"/>
........other settings.........
</appSettings>
I have an executable that runs externally to the app that needs to read this value:
System.Configuration.Configuration config =
WebConfigurationManager.OpenWebConfiguration("/MyApplicationVirtualDirectory")
as System.Configuration.Configuration;
string path = config.AppSettings.Settings["SomePath"].Value;
This throws a compilation error:
'System.Configuration.ConfigurationElement.this[System.Configuration.ConfigurationProperty]' is inaccessible due to its protection level
Which I guess makes sense because web.configs in virtual directories contain some sensitive info like connection strings, etc but I wanted to check and make sure that I'm not doing anything wrong and that my understanding is correct. If not, how can I access this setting from my external executable?
This is sort of a round-abound way of solving the problem, but its the way I've done it in the past. You can simply make a page in your Web Application that gives the setting you want back, and then use an HttpWebRequest to access that page in your executable.
Otherwise its a permission issue. You can mess with the permissions on the Web.config file or try running the executable as Administrator.

ASP.Net - use seperate configuration file for database and app settings

I have an asp.net project that is using Entity Framework that is used on several different client servers. This means a different web.config for each for connectionstrings and app settings.
Hasn't been an issue but I changed something that altered the web.config file recently and I manually had to adjust this for each client, I also have to exclude the web.config file in updates to ensure their own one is not overwritten.
What I would like to achieve is store these settings in maybe another config file that the project can pick up and use. Maybe that on Globals Application_Start gets these and imports them/overwrites the current web.config file perhaps.
Essentially I don't want to affect the current code that uses the connection string and ConfigurationManager.AppSettings used throughout the project but I do want to be able to let the web.config file update for each client and use a seperate file for some settings.
NOTE: I do not have access to publish directly to each server so I can't simply write a different deploy web.config for each one. I have to publish the files locally, store as zip and automated routine on servers downloads and extracts accordingly.
EDIT:
Please do say if this is considered a bad idea but an idea I had was to put something similar in Global.asax Application_Start method:
Does config file exist?
If no, create file and append all current settings in web.config
If yes, open and import those settings to the current web.config overwriting the original values
Hopefully then in a few weeks time, after I have asked all clients to perform a manual update they will have this code and I can begin to include the web.config in updates.
In VS, inside the Build menu, the last item is Configuration Manager.
In here you can specify various different release environments which can each have their own web.config transforms.
This is normally used for production/staging/test environments. However, I can see no reason why you could not use this and have a configuration file for each of your servers/environments.
You will then need to create the transformations for each environment, by rightclicking the web.config, then selecting Add Config Transform.
each of the environments you had setup can then override the settings in the main web.config. (That now acts as a template/default settings)
e.g.
In Web.EnvironmentA.Config
<add key="ConnectionString" value="ConStringA" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
In Web.EnvironmentB.Config
<add key="ConnectionString" value="ConStringB" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
Then when you do a publish, you simply setup which config file to use. If you use Azure or the VS publish method, it will save each of these settings, so then you can simply push to the relevant environment easily.
Just make sure you test this works as you intent first, before you start publishing everywhere ;)

log4net for IIS WCF service with separate config

I want to use log4net for a WCF Service that is hosted in IIS.
But to change settings easily, I want to use a separate config file.
So I added to the Web.Config (and App.config of the WCF Service library)
<appSettings>
<add key="log4net_config" value="log4net.config" />
</appSettings>
But this leads to the current directory of IIS, which is
C:\Windows\System32\inetsrv
And there will never be my log4net.config file.
But I want to configure log4net something like
var configFile = ConfigurationManager.AppSettings["log4net_config"];
var fileInfo = new FileInfo(configFile);
XmlConfigurator.ConfigureAndWatch(fileInfo);
How can I configure a directory that fits this needs?
First of all you could put full path to your log4.net config file.
Secondly you can use System.Web.Hosting.HostingEnvironment.MapPath for example to resolve path like "~/log4net.config"

How can I let ASP.Net process some XML requests, but still return physical XML files?

Language: C# 5.0
Platform: ASP.Net 4.5 on IIS 7.5
Operating System: Windows Server 2008 R2 Standard 64-bit
I am working on an old Web Forms application to add XML Sitemaps which are dynamically generated from our database. I created a generic handler (.ashx) and am building XML with a XmlWriter. I called site.com/SitemapIndex.ashx and voila! So far so good.
I have a business requirement that the sitemap end with the .xml extension. I added a simple URL rewrite rule to my web.config and my local rig processes SitemapIndex.xml through the SitemapIndex.ashx file.
When I deploy the solution to our staging server, I got a 404 not found error on the SitemapIndex.xml file. But the .ashx still worked, so I added a handler mapping on that server. I used a Managed Handler for the path *.xml that uses the System.Web.UI.SimpleHandlerFactory. When I requested SitemapIndex.xml again the output rendered correctly.
Then I tried to request a physical XML file on the server and received the following error message: "There is no build provider registered for the extension '.xml'. You can register one in the section in machine.config or web.config. Make sure is has a BuildProviderAppliesToAttribute attribute which includes the value 'Web' or 'All'."
For now I can process .xml files dynamically through my .ashx handlers, but real xml files will no longer be served. I need to do both. Any help much appreciated!
I supposed the problem is "returning physical XML files"
So You should set your header information correctly.
In your ashx,
Content type should be
Content-Type: application/octet-stream
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("Content-Transfer-Encoding", "binary");
FileInfo fileInfo = new FileInfo(xmlFileName);
long length = fileInfo.Length;
context.Response.WriteFile(xmlFileName, 0, length);
I hope I understand the question well, there is nothing related with URLRewrite it is about relaying.
The solution I used was to remove the Handler Mapping I had created for *.xml and just add one for the specific files I wanted ASP.Net to handle. Everything was already working fine on my dev rig, so I used a config transform on my staging and release configurations to add the handlers I wanted on deployment. The relevant section of my web.staging.config file looks like this:
<system.webServer>
<!-- Handler mappings for our xml sitemaps-->
<handlers>
<add name="SimpleHandlerFactory-SitemapIndex" path="SitemapIndex.xml" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" resourceType="Unspecified" preCondition="integratedMode" xdt:Transform="Insert" />
</handlers>
</system.webServer>

Read config file from asp.net

I'm creating a web application, which calls a DLL to run unit tests, I also have another DLL(DataAccessLayer) which performs connections and performs queries to SQL which references the main DLL. Both the DLLs use the same config file to read settings.
When running application from VS, the application is working fine. However when the web app is deployed to IIS, it seems the DLLs are unable to read the settings from the config file.
After some research I found that I might have to explicitly define the configuration elements in the web.config file, however I don't know how to implement this. Can someone please point me in the right direction?
I'm actually retrieving the settings using the ConfigurationManager with the following code:-
public string GetValue(string key)
{
var appConfig = ConfigurationManager.OpenExeConfiguration("path to dll");
strKeyValue = appConfig.AppSettings.Settings[key].Value;
return strKeyValue;
}
Thanks.
Use WebConfigurationManager.AppSettings["HelloWorldKey"]; to read AppSettings from the web.config.
Just set all the appSettings values used by the DLL you mention, directly in the web.config PRIOR to deploying the app. You don't need to modify this at run-time (and you shouldn't anyway, since any modification to the web.config will cause the application to restart)
Add the connectionstring or AppSetting or ApplicationSettings used in you app.config into your web.config, I understand this is a manual task but is the only way that the config will read the settings.
Use following code to access connection string
string filePath= WebConfigurationManager.AppSettings["Pathfile"].ToString();
Web config Fie
<configuration>
....
<appSettings>
<add key="Pathfile" value="Path to dll"/>
</appSettings>
....
</configuration>

Categories

Resources