.NET MVC3 : Create Virtual file URL and redirect to controller - c#

Suppose I got a MVC3 website with a URL like this:
http://www.anything.com/feed.xml
The trick is, the file feed.xml does not really exist, it will be generated dynamically by a controller at runtime. That way, it will be transparent to people. Any idea how should I bind the controller to the virtual URL?
Thank you very much.

Is this what you need?
routes.MapRoute("", "feed.xml", new { controller = "Feed", action = "Index" });

Create custom route and return File result from action. Look at this links:
Back to Basics: Dynamic Image Generation, ASP.NET Controllers,
Routing, IHttpHandlers, and runAllManagedModulesForAllRequests
(in your situation no need for custom RouteHandler)
ASP.NET MVC Uploading and Downloading Files (how return file)

Related

C# View page URL

I've created a controller, called ClientController.cs and VS automatically created the necessary View files in /Views/Client. But I wanted to get these pages in a different URL... So, it is /Client but I need it at /admin/client.
What should I change?
Thank you!
It's not clear what your functionality will be in the long run, but here are a few options that allow you to get the URL format you want:
Perhaps you want a controller called "Admin" and an action called "Client". This would give you a path of /Admin/Client by default
Alternatively, you can change your route maps. For example, the following with route /Admin/Client to the Index of your Client controller:
routes.MapRoute(
"Default", // Route name
"Admin/Client/{action}", // URL with parameters
new { controller = "Client", action = "Index" } // Parameter defaults
);
Or maybe even go a far as using "Areas", depending on what you need. Have a Google of that if you're interested in learning more
If you want it to be admin/client, then using the default routing you should create an Admin Controller with an ActionResult method called Client. Your views folder should have an admin folder with your client view inside.
I haven't done a lot of MVC but i believe this is what you do.

How do I know which controller this page is hitting?

Pretty new to MVC I have a page on an open source application I have downloaded that is at the url...
http://localhost:51930/admin/login?databaseIssue=true
Obviously Im trying to find which controller and view this maps to in the application. How do I work this out? What should I search for and where to look?
Also how do I work out which actions process this view?
This should help you out. This tool is awesome!
http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx
This guide should get you started. Basically you work with a collection of routes and their arguments, in the global.asax.cs file. The guide there also has a section on custom routes.
By the defaulting routing rules, it's {controller}/{action}/
Which would make the controller in http://localhost:51930/admin/login?databaseIssue=true admin and the action Login.
By convention, MVC routes are generated in form
{app_base}/{controller}/{action}
Check out this stackoverflow question for more information.
So in your case, you'll want to look for an admin.cs class in your Controllers folder.
global.asax is where the route mapping is defined.
You'll see/set something like:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
so by default, your example maps to admin = {controller} and login = {action} and login action method would take the databaseissue=true bit as a parameter.
All these answers are good, except in the case where someone may have created a custom route to the specific url in question. By default, they are all correct, but if a custom route was setup, it could be going to the StackController and referencing the Overflow action.
Like Jamie R Rytlweski suggested above, reference RouteDebugger in your project, add the hook in your global.asax and try going to that page, it will show you a listing of all the routes defined in your application and then show you which routes the current page matches

ASP.NET MVC: how to make all unspecified URLs direct to one controller

I've got an ASP.NET MVC app that's working nicely with a handful of controllers, e.g. "Home", "Services" and "Go". The "Go" controller is where all the content is.
Now the marketing folks have come and said they don't want to see the word "go" in the URL. In other words, instead of:
http://mydomain.com/go/geography/africa
they want to have:
http://mydomain.com/geography/africa
I cannot create a controller for every path that they might want... so is there any way of writing my routing in Global.asax.cs in such a way that requests to "services" and "home" will be treated the normal way, but anything else will implicitly be routed to the "go" controller?
Are you on IIS7? It might be easiest to just implement URL rewriting on the server for this, rather than hacking about with your routes in Global.asax.cs.
EDIT: I've only ever done URL rewriting in Apache. For what it's worth that would be done using something like this:
RewriteEngine On
RewriteRule ^go/(.+)$ /$1 [R=301,L]
Have a look at http://learn.iis.net/page.aspx/460/using-the-url-rewrite-module/ and http://learn.iis.net/page.aspx/461/creating-rewrite-rules-for-the-url-rewrite-module/. Hopefully they'll give you enough info to be able to get this working in IIS 7
Hey, I worked it out myself, without URL rewriting!
Inside RegisterRoutes() in Global.asax.cs:
routes.MapRoute("Services", "services/{action}/{*qualifier}",
new { controller = "Services", action = "Index", qualifier = UrlParameter.Optional });
// and other controllers that I want to work the normal way
routes.MapRoute("Default", "{*path}",
new { controller = "Go", action = "Index", path = UrlParameter.Optional });
And in my GoController class
public ActionResult Index(string path) { ... }
Works perfectly!
You could try adding a mapping that does "geography/{country}" and have it specify the controller manually and add the country as a parameter. I've seen it done to prevent things like "Dashboard/Dashboard" etc.
An example can be seen at Kazi Manzur Rashid's Blog - ASP.NET MVC Best Practices (Part 2) #15 for what I am describing.
Have you seen this: http://www.iridescence.no/post/Defining-Routes-using-Regular-Expressions-in-ASPNET-MVC.aspx ?
you could try mapping a route of "{action}/{id}" with a default set for the controller. But that'll also match anything of the form "{controller}/{action}" too - unless you can do some clever constraining.

How do I route images through ASP.NET routing?

I'd like to create a dynamic thumbnail resizer so that you can use the following URL to get a resized image:
http://server/images/image.jpg?width=320&height=240
I tried setting up a route like this:
routes.MapRoute(null,
"{filename}",
new { controller = "Image", action = "Resize" });
But if the file exists at the URL, ASP.NET will bypass the routing and return you just the file instead. How do I force ASP.NET to route the images instead of returning what's on disk?
Why not just use an action to do this? A controller's action can stream back an image. Otherwise, the typical way, say with ASPX, is that a handler or handler factory listens for the file extension and processes it accordingly. Or use URL rewriting to rewrite the URL in the request.
Thats how asp.net routing works, there is no away around that... you have to use Rewrite if you want to intercept requests for existing files.
Update
Seems like i was a bit too fast on the trigger there. There seems to be a property you can set which allows you to enforce a route even for existing files.
RouteCollection.RouteExistingFiles Property
http://msdn.microsoft.com/en-us/library/system.web.routing.routecollection.routeexistingfiles.aspx
Gets or sets a value that indicates whether ASP.NET routing should handle URLs that match an existing file. True if ASP.NET routing handles all requests, even those that match an existing file; otherwise, false. The default value is false.
You could also consider:
Writing a Module to handle these image routes before it hits routing (registered in Web.Config)
Write your own route handler specifically to handle these images.
Both would allow you to remove the need to write as a controller, I think this is cleaner.
Very basic example of your own route handler (from memory)...
Register as a normal route:
/* Register in routing */
routes.Add("MyImageHandler",
new Route("my-custom-url/{folder}/{filename}",
new ImageRouteHandler())
);
/* Your route handler */
public class ImageRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
string filename = requestContext.RouteData.Values["filename"] as string;
string folder = requestContext.RouteData.Values["folder"] as string;
string width = requestContext.HttpContext.Request.Params["w"] as string;
string height = requestContext.HttpContext.Request.Params["h"] as string;
// Look up the file and handle and return, etc...
}
}
Hope these help. Lots of ways to extend and achieve :)
The simplest way would be to route all images through the controller and store your images in a separate location
routes.MapRoute("Images",
"/images/{filename}",
new { controller = "Image", action = "Resize" });
/sitebase/images/image.jpg //public image location
/sitebase/content/images/image.jpg //real image location
Your controller would then see which image was being requested and load the appropriate file from the file system. This would allow you to do what you want without any special handling.
How about:
routes.MapRoute("Images",
"/images/{filename}.jpg",
new { controller = "Image", action = "Resize" });
That Should ensure that only URLs with .jpg as an extension get matched to that route and get routed appropriately.
Also remember you want to add your actions in order of most specific to least specific, with your default one being added last.
Of course, your action still needs to serve up the Image using a filecontentresult.

ASP.NET MVC in a virtual directory

I have the following in my Global.asax.cs
routes.MapRoute(
"Arrival",
"{partnerID}",
new { controller = "Search", action = "Index", partnerID="1000" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
My SearchController looks like this
public class SearchController : Controller
{
// Display search results
public ActionResult Index(int partnerID)
{
ViewData["partnerID"] = partnerID;
return View();
}
}
and Index.aspx simply shows ViewData["partnerID"] at the moment.
I have a virtual directory set up in IIS on Windows XP called Test.
If I point my browser at http://localhost/Test/ then I get 1000 displayed as expected. However, if I try http://localhost/Test/1000 I get a page not found error. Any ideas?
Are there any special considerations for running MVC in a virtual directory?
IIS 5.1 interprets your url such that its looking for a folder named 1000 under the folder named Test. Why is that so?
This happens because IIS 6 only
invokes ASP.NET when it sees a
“filename extension” in the URL that’s
mapped to aspnet_isapi.dll (which is a
C/C++ ISAPI filter responsible for
invoking ASP.NET). Since routing is a
.NET IHttpModule called
UrlRoutingModule, it doesn’t get
invoked unless ASP.NET itself gets
invoked, which only happens when
aspnet_isapi.dll gets invoked, which
only happens when there’s a .aspx in
the URL. So, no .aspx, no
UrlRoutingModule, hence the 404.
Easiest solution is:
If you don’t mind having .aspx in your
URLs, just go through your routing
config, adding .aspx before a
forward-slash in each pattern. For
example, use
{controller}.aspx/{action}/{id} or
myapp.aspx/{controller}/{action}/{id}.
Don’t put .aspx inside the
curly-bracket parameter names, or into
the ‘default’ values, because it isn’t
really part of the controller name -
it’s just in the URL to satisfy IIS.
Source: http://blog.codeville.net/2008/07/04/options-for-deploying-aspnet-mvc-to-iis-6/
If you are doing this on Windows XP, then you're using IIS 5.1. You need to get ASP.Net to handle your request. You need to either add an extension to your routes ({controller}.mvc/{action}/{id}) and map that extension to ASP.Net or map all requests to ASP.Net. The http://localhost/Test works because it goes to Default.aspx which is handled specially in MVC projects.
Additionally, you need to specify http://localhost/Test/Search/Index/1000. The controller and action pieces are not optional if you want to specify an ID.
There are a number of considerations when using virtual directories in your application.
One is particular is that most browsers will not submit cookies that came from one virtual directory to another, even if the apps reside on the same server.
Try set virtual path: right click on mvc project, properties, web tab, there enter appropriate location.

Categories

Resources