I have a web application with a page. The page has a functionality to upload a file.
I have deployed the application on two different servers in IIS7. Both these hosting have a virtual directory pointing to the same physical directory.
Here I am unable to save the posted file in the virtual directory using Server.MapPath.
Is there any sophisticated technique to handle such situation to achieve this functionality?
Well I'd suggest you 2 scenarios:
Share a folder/resource beetween those servers (assuming that
those servers are in the same LAN), then create app key in the
web.config and this key will contain the path of your shared
resource something like //Server/Folder, use this value instead of server.mappath at the time you
save the file in the server
If you have a load balancer share a folder of your main node and
then use the that path in your secondary node something like
//server/folder that route will save the image in the main node, then
set up a replication rule from your main node and the secondary the
configuration of this rule could vary depending on your needs it
could be an update to the seconday node every 5 minutes for example.
you may create a virtual directory but the purpose for this will be only for displaying the images.
that worked for for me some time ago, it's not a fancy solution but it does the job.
Related
I have inherited an .NET app that is hosted on IIS. Previously it would have been its own site within IIS. Now in my Dev environment I have to run it under Default WebSite (in Production it will still run as its own site.
So in Dev I was having problems loading scripts and css files - so I right click Default Web Site in Dev and Add Application - call the new App - MyApp and point to the physical location on disk.
So previously style sheets would have been loaded:
href="/css/folder/mystylesheet.css"
and js files:
src="/jslib/jquery-1.9.1.js"
which worked fine when the application is hosted as its own site within IIS and which still needs to happen in Production (just not in my dev) So in dev I need to change the css and js as below:
href="~/css/folder/mystylesheet.css" (note ~ added)
src="./jslib/jquery-1.9.1.js" (note . added)
and now the js and css files for MyApp under Default website are loaded. However is there something simple I can do in IIS or webconfig to switch this behaviour on/off easily in Dev/Production rather than editing all the places where scripts and css files are loaded - as I know at some point a file will get checked into Production with the path incorrect
The other problem is there is numerous links throughout the site that are all relative so were /Link/Page.aspx which now break in MyApp hosted under Default Website
EDIT
Looking at the answer below from this question
In ASP.NET, many times you will need to use a tilde (~) to get the application's root directory, so your paths would look like ~/stylesheets/main.css
When you specify a path that starts with / you are indicating the server root so if you have you site in a virtual directory, it will not be taken into account, but if the site is hosted as the default site, the path will qualify:
Example: server named foo.net with site hosted in a virtual directory named app /stylesheet will translate to foo.net/stylesheet not foo.net/app/stylesheet
All my paths start with / (i.e going to server root) - what I need to figure out is there something I could add to web.config that for Dev would let me specify The Virtual Application MyApp needs to be taken into account (just for Dev - this could then be removed in Web Transform for Production web.config file
The short answer is no, there is not one single place where you can deal with the site's location. That's because there are many possible outcomes that you might want, including:
site served from IIS root folder and accessed at root of domain (or not)
site served from IIS subfolder and accessed at same path (or not)
IIS rewrite rules (inbound and outbound), which adds layers of mapping between public and private paths
sites mapping to subdomains, DNS wildcard mapping (where requests are distinguished by hostname), etc
sites mapping to child applications, inheriting or not inheriting rewrite rules (and other configuration)
all of the above
At the same time, there are many places where you interface with paths:
internal physical paths, usually for disk access, and usually requiring mapping of virtual path
internal virtual paths
internal ASP.NET paths, like virtual paths except that they can be app-relative (using ~), which IIS doesn't always recognize
public-facing paths
all of the above can be relative or absolute
So yeah, it's a mess.
For your case, the simplest thing is probably to make the development environment mirror the production environment. Unless you're moving the live site, delegating all the path references to a configuration-aware function is probably more trouble than it's worth.
The ~ is added to make the path relative to root directory. One suggestion is to move the folder up a few levels.or down a few levels to make sure your project is in the correct directory. Hope this works
Doing a project between multiple people, and a few components (web app, services app and some others). We will be storing some information inside the Content folder of the web app so it can be accessed directly from the web server with an href, however other components outside of the web app need to access this folder as well, and since we are sharing the project between multiple people using an absolute path is not an option. What options do we have?
EDIT: Trying to explain it a little better.
What i have exactly is, a web project, a "data project" which is just a dll, a "logic" project which is another dll and a services project which is an exe/service.
Both the web project and service project consumes the methods from the logic, and the logic from the data project. Being the last one the responsable for storing data (in a database) and also in the file system.
This "filesystem" path should be configurable, and we are aiming to put it into the content folder of the web project so multimedia files can be accessed directly rather than doing a byte stream.
Now in the web.config(config file of the web app), and app.config(config file of the services app) i could set the absolute path to web/content (the same for both config files) and the data dll would use it without problems. Now the main problem is that we cannot put an absolute path in the config file because each person works on a different computer with obviously different file paths. So if i could just write something like: ~/project/Web/Content rather than C:/myfolder/stuff/blabla/project/web/content in the config files, with ~ resolving the path to the project, this is what i want! Or maybe better ideas about how to share a folder with these apps without adding absolute paths hardcoded somewhere.
What you want to use is:
Server.MapPath("/Content/filepath.ext");
This will give you the absolute path of a file based on it's position within the website, in this case, from the /Content directory.
For a program external to the website, you have a couple options;
The easiest to implement might be a simple configuration value in the external program which points to the directory. My guess is you've already decided that's not ideal, but it may be the quickest way.
Alternatively, there's a Microsoft .NET assembly which gives you easy access to IIS information (I can't recall its name off the top of my head!). You could use this assembly to find the appropriate website, and retrieve its root directory. I'll see if I can find it and get an example, or maybe someone else will see this and post an answer with that information.
Please check the following method "ResolveClientUrl"
MSDN
Use the ResolveClientUrl method to return a URL string suitable for use by the client to access resources on the Web server, such as image files, links to additional pages, and so on.
http://msdn.microsoft.com/en-us/library/system.web.ui.control.resolveclienturl.aspx
I have two web application hosted on different server.For eg. one is main application and the other one is branch application.
In branch application, user will upload their files but we want to keep all uploaded files in main application virtual directory.
So that we put the main application virtual directory path while we upload the files.But We got error message like "Invalid Directory" and can't upload.
Is there any way to upload files from one application to another directly? We are using normal html upload control in asp.net and visual studio 2008.
Code Sample :
main application virtual directory "http://10.10.10.1/mainapp/uploadedfiles/"
branch application virtual directory "http://10.10.10.2/branchapp/"
HttpPostedFile postedFile;
string saveFile = Path.Combine("http://10.10.10.1/mainapp/uploadedfiles/", "File1.pdf");
postedFile.SaveAs(saveFile);
Please guide me the right way and I really appreciated it.
Thanks.
Best Regards,
Chong
In the FileUpload control, the FileUpload.SaveAs(path) method takes a physical path, not a virtual path. So if you have a virtual path, you will need to use the Server.MapPath method to convert it to a physical path. Using your example, you might want to change the last line of your code to:
postedFile.SaveAs(Server.MapPath(saveFile))
Also, you will need to make sure that the account that ASP.Net is running under has ACL write permissions on the physical directory.
I think u can share the directory and ensure both the Apps can access it, because the two apps are in different servers, the directory path maybe just like : \serverA\Files\, and the url of this directory is : http://localhost/files. u can save files to other servers by a relative path if u have the permission.
I have an application with 2 directories (books and export).
If we create a book or a page of a book in the application a directory is added with the id of the page (this is for uploading resources).
If we delete a page, the page (and it's directory) is removed from the database and the filesystem.
However this resulted in a session loss (even an application restart). I've looked up some thing on google and found the following link.
It seems to be a problem in ASP.NET 2.0 (and 3.5).
We are now thinking about writing a service that will clean up the directories at night.
But there has got to be another solution for this no?
Oh and putting the directory outside the virtual directory is not an option.
Try disabling the monitoring of File System. This will prevent your session alive.
This article may be usefull for you.
Oh and putting the directory outside
the virtual directory is not an
option.
Putting the directory outside the virtual directory is the only solution I found (so far). What you can do, is to create a link (junction) in the file system so that the directory appears to be inside the virtual directory, e.g:
Our web site (virtual directory) is located at C:\projectX\website
the data directory (where we create/delete files and folders) is located at C:\projectX\data
then we create a link which makes the data folder available as C:\projectX\website\data
The link is created using the program Linkd.exe (available in the windows resource kit), with the following command:
linkd c:\projectX\website\data c:\projectX\data
Now c:\projectX\website\data is a link/junction which points to the real data directory. You can work with the link as if it were a physical directory.
E.g. in your web site you can access it using this code:
Server.MapPath("~/data")
And you can also used the windows file explorer and browse to C:\projectX\website\data. It appears just like a real directory.
There seems to be a supported hotfix which achieves the same as the article Sachin mentioned (turn off the file change notifications in a web site).
Check this article in the microsoft KB for more information.
But since you mentioned in a comment, that you do not have access to the server, I guess this will also not help in your case.
For storing data files that are frequently updated, created and deleted you need to use App_Data folder in the root of the web site. MSDN for App_Data folder states:
Contains application data files
including MDF files, XML files, as
well as other data store files. The
App_Data folder is used by ASP.NET 2.0
to store an application's local
database, which can be used for
maintaining membership and role
information.
Also check Q&A section for App_Data folder usage: App_Data folder question
I had the same problem. The solution is to externalize the session handling by using the ASP.Net State service. The only draw back is that every object you place in the session needs to be serializable, as it is transferred to the state service and back.
I currently do not have the possibility to provide further links, but google will help you, now that you know what to search for.
I know that there at least two approaches to leverage the web.config file:
using the configSource attribute which was introduced in .NET 2.0 - here is a good blog entry about it.
The file attribute of the appSettings tag which lets you point to an external file with a relative path. Described in the MSDN documentation on the appSettings element.
Now, my problem is that both approaches work well only for physical paths. But I need to address a config file which is in a virtual directory.
Which other method could I use to put my config resources in a virtual directory?
Note: I want to do it this way, because I have multiple instances of my web application on the same server (and that on many servers). To keep deployment easy and clean, I want to keep one directory for all the files (aspx, ascx, images, css, js etc.) and point the web apps in IIS for different customers (=domains, https etc.) to this single directory. In every IIS web I would have a virtual directory called "custom" which points to a different folder for each web.
Update: I'd like to point out that this virtual directory "custom" is not suited to contain an inherited web.config - that web.config would be valid only for the custom folder which doesn't contain aspx/ascx files.
I have the same scenario and after reading you post I realised that asp.net won't let you do this for various security reasons.
Therefore I turned to the OS to find an equivalent to the Linux soft link function which in turn led me to the Junction utility from sysinternals. This can create a directory that is actually any other directory on that volume and asp.net can't tell the difference and so happy loads the config sections that are not actually in a subdirectory of you website. Works for me :)
Virtual Directories can be set as applications, and you can just place another web.config there.
It will inherit any changes from the parent config, and you can add custom settings in it.
I was looking to do the same thing but it did not work, so I decided to do the opposite, as you know the web.config can be inherited, so I pointed IIS to a folder containing the client config (connection string, file path etc) files and the website files i put them on a virtual directory with the rest of the webconfig (where it load dll and other application files needed)
So basically i can use the website files to multple clients and the clients with their own Database connection string and other specific client settings.