where to write a log file? - c#

I'm using nlog to write log files for debugging purposes. Currently the log file location is set to:
<target
name="file"
xsi:type="File"
fileName="${specialfolder:folder=LocalApplicationData}/x/y.log"
but this is resulting in a the file being written to c:\x\y.log, not %windir%\ServiceProfiles\NetworkService\AppData\Local\x\y.log, as I would expect with asp.net/IIS running under NETWORK SERVICE account.
Checking the value for Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) from the web application yields an empty/null string, which at least explains why my logs are ending up in the root.
So really two questions:
We have services written and running under NETWORK SERVICE account that resolve this path correctly. What's special about asp.net/IIS such that no value is returned for this special folder?
Where is a safe and sensible place to write a log to, given that my asp.net process is running under NETWORK SERVICE account?

If my knowledge is correct, the problem is that IIS doesn't load the profile for the user Network Service.
You could adjust this setting in the properties of the application pool (source)
If you set this parameter to true, the call to Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) should return a correct result.
See also:
Wrong path returned by Environment.GetFolderPath(Environment.SpecialFolder.ApplicationFolder) under IIS6 WebService
http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/890fa85a-b11a-4fbe-a333-cbe69abd72a7/
You can now load the user profile of the application pool identity
If it does not work, I would recommend to create a folder with the appropriate rights for the service account for logging purposes.

Related

Delete and upload files into Azure webapp local storage programatically

I've deployed a website into Azure and i want to access programaticaly this path : "D:\home\site\app" from a c# desktop application and delete all files and upload new ones programatically.
i have searched and found many ways but all are for AzureStorage or using Kudu consol or FTP while what i realy want is to access the local storage where the website is deployed programatiacally, and make some edits on files programatically.
Sure thing, the Site Control Manager (Kudu) has an API for that, the VFS API:
https://github.com/projectkudu/kudu/wiki/REST-API#vfs
You can use either of these for authentication:
A Bearer token that you obtain from the STS (reference implementation in ARMClient)
Site-level credentials (the long ugly ones under your Web App → Properties)
Git/FTP credentials (subscription level)
Sample usage (using site-level credentials):
# Line breaks brutally used to improve readability
# /api/vfs/ is d:\home
# Append path as necessary, i.e. /api/vfs/site/app
$ curl -k https://$are-we-eating-too-much-garlic-as-a-people:6sujXXX
XXXXXXq7Zc#are-we-eating-too-much-garlic-as-a-people.scm.azurewebsites.net
/api/vfs/site/wwwroot/ill-grab-this-file-over-vfs-api.txt
There, i did it.
I'm assuming here that you want to do all that from the outside world - since you don't clearly state otherwise.
Well, in my azure code. my task was to save a excel file and upload its contents to SQL server.
I used this plain and simple to access home site.
string fileToSave = string.Format("{0}\\{1}", HostingEnvironment.MapPath(#"~\Temp"), FileUpload.FileName);
if (!Directory.Exists(HostingEnvironment.MapPath(#"~\Temp")))
Directory.CreateDirectory(HostingEnvironment.MapPath(#"~\Temp"));
FileUpload.PostedFile.SaveAs(fileToSave);
you could use something like this to delete and save a new file or other I/O operations.

Load DataCache from Role Entry Point On Start

I want to access my windows Azure Data Cache from my Role Entry StartUp routine. However I keep getting this error:
{"ErrorCode:SubStatus:Server collection cannot be empty."}
However when I do the same from within my Controller class it loads the Data Cache fine and I can go ahead and do things with it.
Is there anything special for the Role Entry class that I have to do to access the Data Cache prior to my application starting?
Or can't I access the Cache in the Role StartUp ?
Cheers
Starting with Azure SDK 1.3, there is a major change - the Full IIS mode. Read this blog post to get full undertanding of full IIS and what is it.
In short - your RoleEntryPoint descendant (where your OnStart method is being executed) lives in whole another AppDomain (and process actually - WaIISHost.exe), while your actual web application just lives in IIS (w3wp.exe). That's why there is no way to do something in OnStart() that would affect your web applicatin or that would be able to directly read your web.config.
If you do read Azure Data Cache in OnStart to do some preload of data for the web application, just do in your Global.asax's Application_Start() event handler.
If you need to read Azure Data Cache in OnStart for reason's specific to the RoleEntryPoint, you have to load the configuration from web.config. Web.config is placed in "./bin/web.config" relative to your AppRoot folder. (there are two copies of your application when you use WebRoles with full IIS - one lives in AppRoot and one lives in SitesRoot).
Hope this helps!
WebRole's OnStart probably does not use your web.config where you probably have specified server names and access keys for your AppFabric DataCache provider.
I would try manually instrumenting the server connection configuration.

How do I switch off WCF client impersonation temporaraly to write to, for example, a log file

I am using the following attribute to implement impersonation on my WCF service, as I need to impersonate the client during the entire execution of the method:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
The problem is that I don't want the users to have rights on the local file system (as this would be a security hole), so I want my logging library to be able to write to the log file with the real credentials that the service is running under. Applying the impersonation just around the necessary code would be tedious and inelegant, as there are many places where it is required. It would be neater if I could temporarily switch it off with a few lines of code in my logging library. What is the simplest way to achieve this?
I've never used impersonation before, but can you just set [OperationBehavior(Impersonation = ImpersonationOption.NotAllowed)] on the logging methods?

How to retrieve on which site the web application is currently running?

I am currently running a WCF service on an AppFabric server and my application needs to load a the web.config file dynamically to retrieve custom configuration sections.
On my development machine I can just load the configuration like this:
WebConfigurationManager.OpenMappedWebConfiguration(webMappedFile, virtualPath);
But on the test machine (AppFabric server) I am getting an exception and it seems that I need to specify a third parameter which is actually the site the web application is running on:
WebConfigurationManager.OpenMappedWebConfiguration(webMappedFile, virtualPath, "MySite");
So I tried to hard code it and it worked. Anyway this is not acceptable, so I need to dynamically provide the site to the WebConfigurationManager because I do not on which site the service will be running in the future. Do anybody knows how to achieve that?
Thanks.
If you are running this code as part of handling a request you could use:
Request.ServerVariables("server_name")
see: http://msdn.microsoft.com/en-us/library/ms525396(VS.90).aspx
Edit based on your comment
The parameter that you need is the Site Name, not the machine name, your code be running on many machines. If the code is running somewhere where it no longer knows that it is on a web site, then it is difficult for it to get the name of the web site that it is running on.
You then have two options:
Send the name as a parameter from a layer that has httpconext
Not sure if this will work: but you could try adding a reference to system.web to your project. It may compile, but you could get a null reference exception when you run it. Probably worth a try.
How about Server.MachineName

Cannot call web service when deploying ASP.NET site to the server but can run on localhost

When I try to run an ASP.NET site by calling a webservice in the sub virtual directory, I get the error below:
"The request failed with HTTP status 401: Unauthorized. "
This is the code that I wrote:
Dim ws As Odyssey.SupportServices.SupportServices
ws = New Odyssey.SupportServices.SupportServices
ws.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials
My virtual directory structure is shown below:
CSACCsupp - Parent : The parent can call webservice without any issues.
Odyssey - Sub : The Sub cannot call webservice as shown in the error above.
I think the problem is in the IIS security. Therefore, I went through the IIS security and compared the parent and sub; they are identical.
I really do not know what to do next as I've tried many ways to set the security in IIS, but I am still in the dark.
Could you please suggest on this issue?
Are the apps running in the same AppPool? If not, what account are they each running under? Are the web.config files identical? Maybe you are setting impersonation in one and not the other?
Checkout your files ntfs permissions, sometimes when copying files windows keeps the original permissions of the files instead of the new ones.
So probably your files e.g. web.config may not have the necessary permission.

Categories

Resources