NLog in WCF Service - wcf

Can I use NLog in a WCF Service? I am trying to but cannot get it to work.
First I set up a simple configuration in a Windows Forms application to check that I was setting up correctly and this wrote the log file fine (I am writing to a network location using name and not IP address).
I then did exactly the same thing in the WCF Service. It did not work.
To check permissions I then added some code to use a TextWriter.
TextWriter tw = new StreamWriter(fileName);
tw.WriteLine(DateTime.Now);
tw.Close();
This worked OK so I know I can write to the location.

Check that your NLog.config file is in the same directory as your .svc file and NOT the Bin directory.
If you've just added the config file to the WCF project, then published it you will probably find your config file has been copied to the bin directory which is why NLog can't find it. Move it to up a level then restart the website hosting the service (to make sure the change is picked up).
This had me stumped for a while this morning!

Put your NLog config in the web.config file. Like so:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
. . . (lots of web stuff)
<nlog>
<targets>
<target name="file" xsi:type="File" fileName="${basedir}/logs/nlog.log"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="file" />
</rules>
</nlog>
</configuration>

See my comment to your original question for how to turn on NLog's internal logging.
To turn on NLog's internal logging, modify the top of you NLog config to look like this:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.mono2.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Trace"
internalLogFile="nlog_log.log"
>
The key parts are internalLogLevel and internalLogFile.
You can also set internalLogToConsole to true or false to direct the internal logging to the console.
There is another setting, throwExceptions, that tells NLog whether or not to throw exceptions. Ordinarily, this is set to false once logging is successfully configured and working. You can set it to true to help determine if your problem is due to an NLog error.
So, if you had all of those options enabled, the top of your NLog configuration might look like this:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.mono2.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Trace"
internalLogFile="nlog_log.log"
internalLogToConsole="true"
throwExceptions="true"
>
My first guess is that NLog is not finding the config information. Are you using an external config file (NLog.config) or "inline" configuration (in your app.config or web.config)? In your project, is(are) your config file(s) marked (in Properties) as Copy Always?

Related

.Net core request filtering and file downloads

We have an .net core Web application which simply hosts files for some of our client applications updates.
We decided to add Application insights in one of these client applications, and the file ApplicationInsights.config is a part of update.
The request to https://server/path/to/update/ApplicationInsights.config throws 404 error.
So far I’ve tried :
Add “.config” extension in static files definition on the startup : no effect (This worked for .exe and .dll)
Enable folder browsing for this folder, still no effect
It seems to be related to some out-of-box requests filtering.
The question is :
How do I disable all download restriction on a specific folder (Best)
OR
How do I disable ALL filtering for *.config files
Thank you in advance
That's because the default FileExtensionContentTypeProvider doesn't provide a mapping for *.config files.
To make it serve *.config files, simply create your own ContentTypeProvider, or add mapping for *.config :
var myContentTypeProvider= new FileExtensionContentTypeProvider();
myContentTypeProvider.Mappings.Add(".config","text/plain");
app.UseStaticFiles(new StaticFileOptions{
RequestPath = "/path/to/update",
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(),"path/to/update"),
ExclusionFilters.None
),
ContentTypeProvider = myContentTypeProvider,
});
[Update]
After a discussion, the following Web.Config ( by OP) works:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<fileExtensions>
<remove fileExtension=".config" />
<add fileExtension=".config" allowed="true" />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>
</configuration>

How can i tell if my connectionStrings section is encrypted or not?

I have followed Microsoft's instructions here in order to encrypt my connection strings for my application. I have opted to move my connection strings to their own configuration file, connections.config. My code is as posted below (bottom of page) - nearly identical to the snippets provided by Microsoft. After performing the operations, the command: MessageBox.Show(String.Format("Protected={0}", connectionStringsSection.SectionInformation.IsProtected)) prints True, indicating the operation was successful.
However, Microsoft states that "The following configuration file fragment shows the connectionStrings section after it has been encrypted:"
configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAH2... </CipherValue>
</CipherData>
</EncryptedData>
This does not appear to be true in my case. Despite printing True when asking if my sectionInformation.IsProtected, Both my app.config and my connections.config files remain unchanged when visually inspecting them. This leads me to my questions:
Does the description of my problem indicate that in fact my section is not protected after all?
Why is sectionInformation.IsProtected printing True, but no <EncryptedData> attributes have been added to my sectionInformation?
If you carefully read Microsoft's instructions in the link above, they provide explanations for creating both your own connections.config file outside of app.config, as well as encrypting your connections section. However, they do not explicitly say that following their instructions for encrypting connectionStrings section will do so in the external configuration file, connections.config as well. Is the attribute tag in app.config, <connectionStrings configSource="connections.config" />, sufficient to ensure this behavior?
How do I test that my application's connection strings are indeed encrypted correctly, other than a MessageBox printing the IsProtected property?
NOTE
This is NOT an ASP.Net application, this is a Winforms application
I have tested the above with my connectionStrings in both their own connections.config file, as well as within app.config file, and the result is the same.
The relevant sections of my code are posted below:
*app.config*
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<!-- ... -->
</configSections>
<system.diagnostics>
<!-- ... -->
</system.diagnostics>
<userSettings>
<!-- ... -->
</userSettings>
<connectionStrings configSource="connections.config" />
</configuration>
*connections.config*
<connectionStrings>
<!--Manhattan Connection-->
<add name="MANHATTAN"
connectionString="Data Source=xxx;Initial Catalog=xxx;Persist Security Info=False;Integrated Security=False" />
<add name="DENVER"
connectionString="Data Source=xxx;Initial Catalog=xxx;Persist Security Info=False;Integrated Security=False" />
<add name="DESMOINES"
connectionString="Data Source=xxx;Initial Catalog=xxx;Persist Security Info=False;Integrated Security=False" />
</connectionStrings>
*The connection source code*
Private Sub ToggleConfigurationEncryption(ByVal executableName As String)
Try
Dim configManager = ConfigurationManager.OpenExeConfiguration(executableName)
Dim connectionStringsSection = configManager.GetSection("connectionStrings")
If connectionStringsSection.SectionInformation.IsProtected Then
connectionStringsSection.SectionInformation.UnprotectSection()
Else
connectionStringsSection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")
End If
configManager.Save()
MessageBox.Show(String.Format("Protected={0}", connectionStringsSection.SectionInformation.IsProtected))
Catch ex As Exception
ExceptionController.LogException(ex)
ExceptionController.DisplayException(ex)
End Try
End Sub
Your issue is happening in your if statement.
If connectionStringsSection.SectionInformation.IsProtected Then
connectionStringsSection.SectionInformation.UnprotectSection()
...
This example shows how to toggle between encrypting and decrypting. In the code posted by you, you're simply decrypting the file if it's already encrypted. Your code should be something like this:
If (Not connectionStringsSection.SectionInformation.IsProtected) Then
connectionStringsSection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")
End If
You only want to encrypt if the file has not been encrypted. Don't worry about decrypting the file and trying to read. It will automatically decrypt it for you.
I don't see the how you're calling the ToggleConfigurationEncryption method. You need to pass the correct name of the output config file. After you launch your app (if in debug mode) you can go to project directory in bin\debug folder and look for your connections.config file. When you open it you'll see that it's encrypted.

What is the expected contents of Web.config if appSettings entry is parameterized?

I'm trying to parameterize an appSettings entry in my Web.config. Since this is a part of a quite long build process, I'd like to verify that my parameterization actually works before trying it out on our CI server (i.e. trial and error is not a good idea).
So, if I run MSBuild with /T:Package to create my package, I expect that the .zip file created would contain a Web.config with my appSetting entry tokenized, just like a connection string is tokenized.
But, so far I do not get my expected result. Is my assumption wrong?
Is it maybe that the tokenization/replacing happens first in the actually deploy-step?
Here's the tokenized web.config. Notice how my appSetting isn't tokenized:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<lots of stuff here...>
<connectionStrings>
<add name="DefaultConnection" connectionString="$(ReplacableToken_DefaultConnection-Web.config Connection String_0)" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="mySetting" value="monkey"/> <!-- Shouldn't monkey this be tokenized? -->
</appSettings>
<rest of web config here ...>
The con string tokenization is taken care of in the web publishing MSBuild targets. It's not a part of Web Deploy itself. In your scenario I'd expect that the package was created and app settings are not modified.
When the package is created there are two ways you can see the parameters:
Use msdeploy.exe and pass GetParamters - http://technet.microsoft.com/en-us/library/dd569044(v=ws.10).aspx
You can crack open the .zip file and look at the parameters file inside of it

How to run svcutil.exe from behind authenticating proxy

I want to run the svcutil.exe tool to access a web service on the internet. Unfortunately, whenever I try, I get a bunch of errors that include the following message:
The request failed with HTTP status 407: Proxy Authentication Required ( The ISA Server requires authorization to fulfill the request. Access to the Web Proxy filter is denied.
As I have learned from this related post (with more details here), the problem is that I am sitting behind an authenticating proxy. That post explains that I need to edit the app.config file, but I can't figure out how to do that. I think I will use the /svcutilConfig:alternate_app.config switch, but I don't know how to construct a valid .config file to pass to that switch. What is the default app.config file that svcutil.exe uses?
Well, I think I have figured out the answer to my question:
It turns out that the default .config file used by svcutil.exe is called svcutil.exe.config, and (at least for me) it lives in this folder:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin
I decided to just edit that file directly (rather than fumble around with the /svcutilConfig switch). I needed Admin privileges to do so.
The final contents of that file looked like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<generatePublisherEvidence enabled="false" />
</runtime>
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
</configuration>
(with the secret sauce buried in the <system.net> element.)
In order for this all to work, I had to start the Command Prompt as Administrator, navigate to the folder listed above, and run the svcutil.exe command from there.
Hope this helps some other poor soul who gets stuck in this mess! Thanks to #AndrewWebb for the clues that got me going!

appsettings node in web.config WCF file gives an error when trying to debug

i have a WCf project,
when i add the following code to the configuration file (Web.config):
<configuration> <appsettings> <add key="Hello" value="5"/> </appsettings>....
i get this erro whentrying to debug:
"Unable to start debugging on the web server. The web server is not configured correctly. See help for common configuration errors. Running the web page outside of the debugger may provide further information."
when i drop the appsettings, the WCFTestClient opens.
how do i define constants in the web.config if not in that way ?
Solved this problem by putting the AppSettings node as the last node in the section and it works!
<appSettings><add key="hello" value="Monday" /></appSettings></configuration>
funny......
I think it the case problem. the Application settings section is defined as
<appSettings>..</appSettings>
I hope you have define the service settings in your web.config
<system.serviceModel>
<services>..</services>
<bindings>..</bindings>
<behaviors>...</behaviors>
</system.serviceModel>