Programmatically retrieving IIS log file location in an ASP.NET application - asp.net

I'm trying to determine the location of the IIS log file location of my ASP.NET application. I tried WMI, but wasn't able to find it. Any suggestions?
Note: I want to be able to retrieve the location programmatically; inside my application for further use.
Edit: Here's my code: This works but does not give me the actual physical directory location of the logs. So this is basically useless.
ManagementPath p2=new ManagementPath("IIsLogModule.Name='logging/Microsoft IIS Log File Format'");
ManagementObject log = new ManagementObject(scope, p2, objectGet);
log.Get();
logPath.Text = log["__PATH"].ToString();

On IIS7 you could use Microsoft.Web.Administration assembly, Site class has a property named LogFile, you can get various info about log file for site, for example log file directory can be obtained with this code:
ServerManager manager = new ServerManager();
Site mySite = manager.Sites["SiteName"];
Response.Write("Log file directory : " + mySite.LogFile.Directory + "\\W3svc" + mySite.Id.ToString());
I don't like very much that hardcoded part with directory prefix for site, but didn't find any other better way

You should able to use ADSI (or WMI) to do that - browse IIS metabase and look for 'LogFileDirectory' property for the web site node. For example,
var root = new DirectoryEntry(#"IIS://localhost/W3SVC");
var sites = root.Children;
foreach(DirectoryEntry site in sites) {
var name = site.Properties["ServerComment"][0];
var logFile = site.Properties["LogFileDirectory"][0];
}
Disclaimer: Untested code
See this powershell example using similar idea.

Related

virtual directory - How to load image files for asp.net viewing?

There are so many similar questions around the web, but none of them have helped me with this.
I have an asp.net application on a company intranet server. It is used to access a database on another file server, which also contains a number of images relevant to each record in the database.
I am a developer, but not a network person. I know a little bit about IIS, and using the IIS Manager, I created a virtual directory inside the asp.net application folder that maps to the UNC address on the other server where the images are. Using IIS Manager, I can explore the virtual directory and see all the files there. The problem is getting them to show up in my asp.net application.
I've tried setting permissions on the folder for Network Service, IUSR_aspnetserver, and my own credentials; I've tried various permutations of the path string, with / or // or \ or \, etc. I've tried impersonation, but I don't know if I am doing it right. I've placed a "debug" label on the page that tells me the path of the image while the app is running, and it is correct. Nothing seems to work.
Obviously there's something I am missing, but my network comprehension is around zero, my IIS experience is hardly any better, and I can't seem to get our staff of IT "experts" to help. And before you jump to any conclusions, I have a great personality.
Any ideas would be appreciated.
Thanks!
EDIT for #MohsinMehmood:
(I hope this is not too convoluted)
The page has a mapped drive in IIS to UNC share \\OtherServer\AppName\Images to a folder named ReceiptImages.
The web.config file has this entry:
<appSettings>
<add key="ImageFilePath" value="ReceiptImages/"/>
</appSettings>
And in the PageLoad event I have
ViewState("ImagesPath") = ConfigurationManager.AppSettings("ImageFilePath")
To create a global path string.
Then in code (VB) it's:
Dim btnReceiptThumbnailButton As New ImageButton
With btnReceiptThumbnailButton
.ID = "btn" & LineItem
.CssClass = "thumbnails"
.ImageAlign = ImageAlign.AbsMiddle
.Visible = True
.BackColor = Drawing.Color.White
.BorderColor = Drawing.Color.Black
.BorderWidth = 1
.ImageUrl = ViewState("ImagesPath") & LineItem
.CommandName = "GetReceiptImage"
.CommandArgument = LineItem
End With
I don't know if it was important enough to mention that the image is being placed in a button control to make it a thumbnail.

How to get the root url at startup in an OWIN asp.net Web API

I have found many posts very similar to this, but I didn't find any that worked for me.
I have an asp.net Web Api2 (not vnext) application, running under IIS, and using the Owin Startup class.
When installed, the root url to this will be something like
http://localhost/appvirtualdirectory
where appvirtualdirectory is the name of the virtual directory it is configured to run under in IIS.
IS there a way at startup where I have no Request property, ie in the Startup.Configure method, to get the root URL including the virtual directory being used?
Try this
HttpRuntime.AppDomainAppVirtualPath
This is valid in both global and owin startup
More details here https://msdn.microsoft.com/en-us/library/system.web.httpruntime(v=vs.110).aspx
I would use:
//you have some options but i will show you the easiest
var request = HttpContext.Current.GetOwinContext().Request;
var path = request.Scheme +
Uri.SchemeDelimiter +
request.Host +
request.PathBase;
Info about the properties I'm referencing.
https://msdn.microsoft.com/en-us/library/microsoft.owin.owinrequest(v=vs.113).aspx

What's the recommended way to load an internal file on the web site?

We've got a certain image in the \Images folder of our web site. We need to include that image in an OpenXml file we're generating internally, and for that we're using the following snippet:
var logo = Server.MapPath(#"~\Images\logo-new.png");
var imagePart = mainPart.AddImagePart(ImagePartType.Png); // mainPart is of type MainDocumentPart
using (var stream = new FileStream(logo, FileMode.Open))
{
imagePart.FeedData(stream);
}
Then later imagePart is used for embedding in the document.
This code works fine in development, but in deployment we're getting a System.UnauthorizedAccessException when we try to open the file for streaming.
Clearly there is an access permission problem, since Server.MapPath() is converting the web path to an absolute path on the server drive, and the IIS user doesn't have rights to that. We might be able to get around it by granting access to everyone, but something tells me that this is not the textbook way of doing it. Surely there must be a way of accessing this file that doesn't require us to start futzing with access permissions to the web deployment folder?
Solved, by including the file as a resource rather than by trying to access it through the file system:
var logo = Resources.logo_new;
var imagePart = mainPart.AddImagePart(ImagePartType.Png);
using (var stream = logo.ToStream(ImageFormat.Png))
{
imagePart.FeedData(stream);
}
Hat tip to this answer for the .ToStream() extension.

Save file in a folder above the site files

My host has the following structure:
/Web -> Where is the content of the site
/Data -> Folder permissions to read and write
How do I upload a file to the Data folder?
The code below does not work, since "~" returns the directory / web.
//Save Image
var serverPath = Server.MapPath(Href("~/Data/") + id);
Directory.CreateDirectory(serverPath);
imgOri.Save(Path.Combine(serverPath, fileName));
Server.MapPath() is designed to map a path up to the root directory of the application. As you are trying to upload a file above the root it won't work.
You can upload a file above the root by specifying the exact file path (if the host can provide it):
var serverPath = "C:\YourFolder\Data\") + id);
I'm surprised your host is allowing you to upload a file outside of the root directory as there are a number of dangers in doing this...you may also run into Trust issues.
You can obtain the path to a directory which sits at the same level of your site root by using Server.MapPath as below:
#{
var root = Server.MapPath(".");
var temp = root.Split('\\');
temp[temp.Length - 1] = "Data";
var newpath = string.Join("\\", temp);
}
Hosting companies used to provide "data" directories outside of the root folder as a safe place for things like Access mdb databases. You cannot directly browse to a directory which is outside of the root of your site. ASP.NET did away with the need for these things with the introduction of App_Data. The only reason you would want to use this kind of folder nowadays is if you want to apply some kind of authentication prior to serving the contents of the directory. Then you need to use a handler, or a simple cshtml file will do. You can combine the WebSecurity helper with the WebImage helper to first authenticate the user, and then retrieve and display the image if they pass the test. The src in your img tag will point to the cshtml file, with a querystring or UrlData value so you know which image to display.
If you don't need to validate users prior to displaying image, storing the image files outside of the root adds an unnecessary level of complication.

How do I get the complete virtual path of an ASP.NET application

How do I know the the complete virtual path that my application is currently hosted? For example:
http://www.mysite.com/myApp
or
http://www.mysite.com/myApp/mySubApp
I know the application path of HttpRequest but it only returns the folder name that my application is currently hosted, but how do I get the initial part?
The domain name part of the path is not really a property of the application itself, but depends on the requesting URL. You might be able to reach a single Web site from many different host names. To get the domain name associated with the current request, along with the virtual path of the current application, you could do:
Request.Url.GetLeftPart(UriPartial.Authority) + Request.ApplicationPath
Technically, an "application" is a virtual directory defined in IIS and Request.ApplicationPath returns exactly that. If you want to get the folder in which the current request is handled, you can do this:
VirtualPathUtility.GetDirectory(Request.Path)
ASP.NET has no idea how to distinguish your sub-application from a bigger application if it's not defined as a virtual directory in IIS. Without registering in IIS, it just sees the whole thing as a single app.
Request.Url
it contains several points that you might consider to use, see the image below:
The below code will solve the purpose, however you have to do a bit tuning for two types of scenarios:
Hosted as separate web application.
Hosted as Virtual application within a web application.
HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + HttpRuntime.AppDomainAppVirtualPath;
In .NET 4.5
VirtualPathUtility.ToAppRelative(path)
Try this (Haven't tried it)
public string GetVirtualPath(string physicalPath)
{
string rootpath = Server.MapPath("~/");
physicalPath = physicalPath.Replace(rootpath, "");
physicalPath = physicalPath.Replace("\\", "/");
return "~/" + physicalPath;
}
Link 1
Link 2
Url.Content("~") worked great for me and is nice and simple. I used it in the view like this:
<a href="#(Url.Content("~" + attachment))">
Here my attachment is a path like "/Content/Documents/Blah.PDF".
When my app is published to a IIS site that uses a virtual directory, Url.Content("~") resolves to just the virtual directory name like, "/app-test", for example.

Resources