Retrieve embedded static resources (css/img/etc) using Virtual Path Provider instead of GetWebResourceUrl - asp.net

I have an asp.net 4.0 webforms website with a CSS stylesheet which I've embedded into a separate assembly.
If I load the css using ClientScript.GetWebResourceUrl it loads, but does it with that /WebResource.axd?whateverlongstringofstuff
I was hoping that I could use a Virtual Path provider so that i can simply reference it by linking to say ~/Custom/my.css
where ~/Custom/* would go through the VPP and serve it from the embedded resource.
the reason I was doing this is I want users to be able to easily override my css by adding the actual css file in that location so it serves that one instead.
However, no matter what I try, I get a 404 on that resource url, even though in my custom ResourceResolver, the fileExists resolves to true (because it does find it in the resources assembly).
So I suspect this is because IIS is configured to serve static files (css, jpg, png, etc) directly, bypassing anything I could add to the pipeline, and the only way around this would be to have my users change their web.config or IIS settings.
Is this true? because if it is I'll abandon this and go back to the WebResource.axd, but it would really be nice if this could be done

Related

Serving extensionless static files in ASP.NET MVC; getting 404s

For whatever reason (ugh, just assume we have to), we have a JavaScript file and a CSS file without an extension in our ASP.NET MVC application. The JavaScript file is at path ~/Scripts/js and the CSS file is at ~/Styles/css. These are static files containing JS and CSS respectively, but without file extensions.
Right now, when I try to load the resources in a browser, I get a 404 for those two paths. What do I need to do to make my ASP.NET MVC application serve these extensionless files (and serve them with the correct MIME types)? Something in the web.config and mapping a particular URL pattern to the HTTP handler for static files, I'm guessing. Apparently my Googling skills are inadequate—forgive me.
I think esmoore68 probably has the best answer... but... if you don't want to do that, I wonder if you could declare the style (and the script) on the page (rather than reference the files), and maybe use labels on the pages where you need these, and actually open the files in code-behind, read them as text, then write them into the labels on the page load?
I haven't tried anything like that, specifically, but it seems like it would work.
If it does, maybe you could create a user control so you can just put that in all the pages, rather than repeating it every time.

Cannot route static files in ASP.NET WebForms

We have legacy code to maintain and, to solve a specific customer customization problem, we want to route calls to some files to other files. That is, when the app calls a particular ASPX, it will end up hitting another ASPX.
If you call:
www.foo.com/admin/admin.aspx
It will actually hit:
www.foo.com/customizations/customer1/admin/admin.aspx
This is not a good design but this is legacy code. We just want to solve this.
We are using the System.Web.Routing framework to solve it. This works fine when you set RouteExistingFiles to true, except for static files (CSS, JavaScript and Images).
When I first tried it, it retrieved this error:
There is no build provider register for the extension '.css'.
So I did register a build provider in the web.config file for the .css extension. I used this build provider: PageBuilderProvider because someone recommended it in the internet.
It works! But the CSS is being served with text\html content type.
How do I achieve this?
TL;DR: I want to use routes in ASP.NET Web Forms to make a call for a specific CSS file to actually retrieve another one. A customer needs this for customization.
Try coding a HttpHandler. I had to do something similar but for PDF files, I coded a custom HttpHandler in the end - works very well. You can even set the content type in the HttpHandler code and have a pattern matched path the handler will be used for in the web.config. You can also configure it in web.config not to execute if the path does not point to an existing file e.g. so a 404 is returned without having to code that in the handler itself. I can't post my code (VB.NET) ATM because I'm using a tablet but google search for tutorials. You will also probably need to use the TransmitFile function to actually write out the css file. Is it a web forms project or web site? If its a web site there is a special way of registering the HttpHandler in the web.config.

asp.net static content in separate project. now how to refer?

Project1.csproj is the website project and StaticContent.csproj is the static content project to hold all .css, .js and image files. I am keeping it separate so that designers can work without touching the main project file and may be use cdn in future. But the problem is how do my .ascx and .aspx pages will refer to these css and js files as that when I run in localhost, it still picks up.
I think the best way is you create a website in IIS for the Static project, and reference it trough something like static.myproject.com (having the appropiate setup) on the other one.
You can still use Webdevserver on Project1.
Is most like what you will have when deploy, and you can put the URL on web.config for easy change

Custom VirtualPathProvider unable to serve URLs ending with a directory

As part of a CMS, I have created a custom VirtualPathProvider which is designed to serve a single file in place of an actual file structure. I have it set up such that if a file actually exists on the server, that file will be served. If the file does not exist, the virtual content stored for that address will be served instead. This is similar to the concept of serving a website from files stored in a database, though in this case the content is stored in XML files on the server.
This setup works perfectly when a request is made to a specific page. For example, if I ask for "www.mysite.com/foobar.aspx", the content that is stored for "foobar.aspx" will be served. Further, if I ask for "www.mysite.com/subdir/foobar.aspx", the appropriate content will also be served.
The problem is this: If I ask for something like "www.mysite.com/foobar", things begin to fall apart. If the directory exists on disk (and doesn't have a configured default page in IIS, such as index.aspx), I will get a "Directory Listing Denied" error. If the directory does not exist, I'll simply get a 404 - Resource Not Found.
I've tried several things, and so far nothing I've done has made a bit of difference. It seems as though IIS is simply noting the nonexistence of a directory (or default file in an existing directory) and serving up its own error code, without ever asking my application what to do with the request. If it ever did get to the application, I would be able to solve the problem, but as it stands, I'm quite lost. Does anyone know if there is some setting in IIS that is causing this?
I've looked for every resource I can find on the subject, and am coming up empty. I know this should be possible, because I have read tutorials on serving content from both databases and ZIP files. HELP!
p.s., I am running IIS6 and .NET 3.5
IIS will only pass a request to the ASP.NET process if it is configured to do so for the particular extension. The default is aspx, ascx, etc. In other words, if you request a .html file, ASP.NET will never see that HTTP request. Likewise for empty extension.
To change this behavior, add a wildcard mapping to the ASP.NET process. Load IIS Manager, go to the Properties for your web site and look at the Home Directory tab. Click on "Configuration" and there you will see the extension-to-applicaiton mappings.

Programmatically deciding what file a URL should point to with ASP.NET 3.5 and IIS 7

Is it possible to programmatically resolve a URL to a file using ASP.NET and IIS? Specifically I'd like the file to be outside of my Virtual Directory (could be anywhere on the local file system). So if a URL comes in like http://mysite/somepicture.jpg I'd like to be able to return c:\mypicture.jpg. I looked into creating an IHttpModule for URL rewriting but that isn't quite what I need - it's limited to URLs within the existing site.
You cannot achieve it by URL rewriting as the file is not hosted on your Web site. You should use Response.WriteFile method in an HttpModule or HttpHandler to manually stream the file to the user.
I would like to add to Mehrdad's response by saying that you need to make sure your app has rights to the folder the files you want live in. That way you can dish it out as Mehrdad suggested.

Resources