ASP.NET 4 Web forms Routing images - asp.net

I'm using ASP.NET 4 Web forms routing, for example like this:
routes.MapPageRoute("page-browse", "{Language}/{Label}", "~/Default.aspx")
So the webadress could look like: http://localhost/mywebsite/eng/home
In the root of my website I have a folder "Images".
Image display works when I'm in the root of my website, e.g. by using http://localhost/mywebsite/default.aspx
But when using routing it doesn't work, because the image relative url will look at http://localhost/mywebsite/eng/images instead of http://localhost/mywebsite/images
Is there a way to prevent this using ASP.NET 4 Routing mechanism? Or is the only way to use absolute url's to images?

Two things you could try.
1) Set RouteExistingFiles to false. This will stop routing on any file that the server matches as already existing. Only "virtual" urls that match a route will actually be routed:
routes.RouteExistingFiles = false;
2) Use a StopRoutingHandler route. For example, this would stop routing on all jpgs. You could also set it up to ignore the entire images directory.
routes.Add(new Route("*\.jpg", new StopRoutingHandler()));

Create an IHttpHandler implementation that locates the file's absolute path from the virtual path and renders it as a filestream.
Create an IRouteHandler implementation that returns the http handler I just described if the file has an image extension, or uses the default routing mechanism otherwise.
Register the route handler to be used in the route.

How are you referencing your images?
You should just be able to use a virtual path to the site root, using a prefix of '/' (unless I'm completely misunderstanding the question)
e.g.
<img src="/mywebsite/images/image.jpg" />

Related

Asp .Net MVC 5 Folder name and Routing conflict

I have an annoying problem with folder names and routes in ASP .NET Mvc 5,
This is the default routes I'm using:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Site", action = "Index", id = UrlParameter.Optional }
);
And I'm also using a custom view engine to map views to the root folder instead of ~/Views so I can have HTML/CSS/JS files organized in a way my team can handle.
The problem is: When I call /Backoffice/Index it goes normally and executes action Index in controller Backoffice, all fine, but when we call /Backoffice, I expected it to presume the action index (by the route configuration), but instead, IIS seems to believe I'm trying to access the folder /Backoffice and gives me a 404 error instead of executing Backoffice::Index().
How can I configure IIS to behave in the intended way in this case? Or, is it really the only best way to keep views in a specific folder?
I did some research and used info from the comments and answers here and got to learn something about how MVC routes work and how IIS handles that.
When we set
routes.RouteExistingFiles = true;
The MVC runtime will ignore every file in the folder and start using the routes and URIs solely to look for controllers and actions, this means by calling /SomeContent it will search for a controller named Somefolder instead of a folder. Then we can configure to serve static content by telling MVC runtime to ignore some specific URI formats:
routes.IgnoreRoute("SomeContent/CSS/{filename}.min.css");
routes.IgnoreRoute("SomeContent/JS/{filename}.min.js");
This causes MVC to ignore URIs that match this pattern and leave it for IIS to resolve what to do with it, then IIS will look out on Web.Config rather there are configurations set to serve this kind of static content and what handler to use and proceeed as usual.
Using this configuration can bring MVC to a whole new level of control where you explicitly define which URI patterns serve static content, everything else explicitly calls an action on a controller, all URIs get to be firstly processed by MVC runtime. I sure wish someone correct me in this last statement if I get it wrong.
MVC routes certain actions based on whether they exist on disk. If you have a folder /BackOffice at the root level, then this appears to be a complication that MVC is going to have issues working around (I knew files were directly routed if they existed; I didn't realize folders were something the framework checked too). Consider renaming the folder or the controller to something else so you don't have this naming conflict. That is a problem with "by convention" approaches....

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.

How to change domain of href

I have one project with one domain and another project with a different domain. I want to have a button on the first project which links to the second project. How can I accomplish this? I currently only know how to change the controller and action with an href
There are no built-in helpers allowing you to generate links across different ASP.NET projects. The url helpers are intended to be used only for generating links to internal controller actions. ASP.NET routing works only for the current project.
You will have to use an absolute url or write custom helpers that could for example use some base url that you would configure in your web.config that will be concatenated with the actual relative url you need to reach.

Getting ASP.NET root path to Flex?

I am working on a project that is primarily ASP.NET based. The main project is meant to be deployed to multiple locations for different clients, so one client might be located at website.com/client1 and another at website.com/client2. Within the application, we regularly use the application root operator ~ to get the path to a resource.
We also have a bunch of Flex applications that get deployed in there, and many rely on web services within the ASP.NET application. What I'm after is a way to reference the services relative to the application root. Here's an example of the location of some files for two client deployments:
Client A
website.com/clientA/swf/FlexApplication.swf
website.com/clientA/services/webService.asmx
Client B
website.com/clientB/swf/FlexApplication.swf
website.com/clientB/services/webService.asmx
FlexApplication and webService are both exactly the same, so what I want to do is something like this in the Flex code:
var myService:CustomService = new CustomService(~/services/webService.asmx);
myService.callMethod("Test");
I would like to avoid using relative paths for the usual reasons. Is there a good way to do this or a good way to pass the root url to the flex application from ASP.NET? Thanks in advance.
Its definitely a good idea to avoid relative URL's. The easiest way is to pass the information in via Flash Vars in the HTML embed statement.
Check out Adobe's documentation on using FlashVars with Flex: http://livedocs.adobe.com/flex/3/html/help.html?content=passingarguments_3.html
Summary:
Add a line to the HTML embed statement like this:
<param name='flashVars' value='serviceRoot=/myserviceRoot'/>
Then access it in Flex via the mx.core.Application.application.parameters accessor
import mx.core.Application;
var parameters:Object = Application.application.parameters;
var serviceRoot:String = parameters['serviceRoot'];
relative to the application root
Flex knows nothing about the application root of a ASP.NET application. The only thing that the Flex app knows is the URL that it is served from. It does not know the URL of the page. Keep in mind that the URL of the page and the URL of the SWF are not the same.
It appears, given your directory structure, that you can use the SWF's URL to get the information you're after.
In a Flex 3 Application, you can get use the url property of the Application tag:
(Application.application as Application).url
In a Flex 4 Spark application, you can also use the url property of the Application Tag, but you have to get it differently:
(FlexGlobals.topLevelApplication as Application).url
Then you can parse it with URLUtils to get your directory structure. Probably store that as a global variable in your Flex application somehow and use it to construct the URL for the service calls you are making to the remote server.
I use this handy little utility to get URL information via javascript inside the .swf.
http://www.flexpasta.com/index.php/category/utility-classes-that-help-you-deal-with-string-numbers-arrays-and-objects-in-actionscript/

Getting web address for local file in ASP.Net

Is there a 'correct' way to get the proper web address for a file under an ASP.Net application? For example, I have content in '/Content/Images/Gallery/2010-01-17/small/', and I would like to iterate through all of those files, and output to the browser a link.
Now, I can do it manually by working out the path from the files FullName or I can do it from knowing the current directory, but is there a proper ASP.Net way to do it?
As you can probably tell, I'd rather use the provided method if it exists :)
Regards
Moo
You can use the method ResolveUrl() for that. If your content directory is located directly under you web app's root directory, then this should work:
// "~" results in an URL to your web app's root directory
string imageBaseUrl = this.ResolveUrl("~/content/gallery/2010-01-17/small");
Then you can append the names of the images to that base URL.
I think ResolveUrl is only part of the answer.
Unfortunately, there is not a built-in function to return a full URL to a particular resource, inclusive of hostname and protocol. Part of the reason for this is that you can access a URL any number of ways... and the server is completely agnostic of the hostname. You have to look at either the Request.Url properties to build a new URL from the user's request, or use ServerVariables.
See this question:
How to Convert "~/default.aspx" to "http://www.website.com/default.aspx" C#?

Resources