I have an existing Web application that was developed in ASP.NET 4.0. I want to add MVC functionality to the app, so I've integrated MVC into the app as per Scott Hanselman's article Integrating ASP.NET MVC 3 into existing upgraded ASP.NET 4 Web Forms applications. Because MVC routing is greedy, I added the following code to my Global.asa so that an empty URL will go to my Default.aspx:
routes.MapPageRoute("WebFormsDefault", "", "~/Default.aspx");
The problem now is that ActionLinks and RouteLinks don't form correctly. If I try to create an action link using:
#Html.ActionLink("Item List Page", "List", "Item")
the following URL is created:
"/SiteName/?action=List&controller=Item
I've found several posts from others with this same problem, but none of them have any answer. Is this just a bug? Is integrating MVC into a WebForms app just a bad idea in general? Or is there a way to fix this so that my Default.aspx page will be displayed when a user first enters the site and ActionLinks and RouteLinks will work correctly?
Coming to this a bit late, but I figure better late than never. I was having this exact same issue and I solved it by grouping my MapPageRoute code and my MapRoute code and then always calling the MapRoute code first. Example:
Originally my routing looked like this -
routes.MapPageRoute("401", "401/", "~/Views/Error/401.aspx");
routes.MapPageRoute("404", "404/", "~/Views/Error/404.aspx");
routes.MapPageRoute("500", "500/", "~/Views/Error/500.aspx");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
etc etc
This was causing all of my form actions to direct to a url formatted as so:
/mysite/401?action=x&controller=y
Clearly that was not useful. By making sure that I always setup all of my MVC routes first, the problem resolved itself. I ended up making two seperate methods, one for configuring MVC routes and one for configuring Webform routes as so:
RouteConfig.RegisterMvcRoutes(RouteTable.Routes); // contains only MapRoute
RouteConfig.RegisterWFRoutes(RouteTable.Routes); // contains only MapPageRoute
(these calls go into the Global.asax file as usual and replace RouteConfig.RegisterRoutes)
I would not advise mixing webforms with MVC, but I did manage to get this working by using this helpful posting:
http://bartwullems.blogspot.com/2011/04/combining-aspnet-webforms-and-aspnet.html
I also had to be rather careful about the ordering of the routes so that my most generic route went after the aspx page I wanted to be served up as a default.
Here is my complete RouteConfig:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute({resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "SignUp",
url: "SignUp",
defaults: new { controller = "Profile", action = "SignUp", shortUrl = UrlParameter.Optional });
routes.MapRoute(
name: "Admin",
url: "Admin",
defaults: new { controller = "Admin", action = "Index", shortUrl = UrlParameter.Optional });
//used to get aspx page to render
routes.MapPageRoute("WebForms", "", "~/WebForms/Default.aspx", false, null, new RouteValueDictionary(new { controller = new IncomingRequestConstraint() }));
//this generic route must go last
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
public class IncomingRequestConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return routeDirection == RouteDirection.IncomingRequest;
}
}
Related
I have asp.net mvc application.
And I have html page. called lp.html.
i want to rewrite page name url from lp.html to something else, lets say appndomainname.com/location
how can I do this, because in this case I am dealing with simple html pages. No controller or controller method.
So code like this won't be needed
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
any help will be appreciated, thanks
I have used the most conventional way to build routes:
routes.MapRoute(
name: "Client",
url: "{controller}/{id}",
defaults: new { controller = "Client", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
"Default,
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
But I have trouble in some routes, and I came across a new way to create routes in MVC 5.
The next example:
public class ClientController : BaseController
{
[HttpGet]
[Route"({controller}/{id})"]
public ActionResult Index(string id = null)
{
}
[Route"({controller}/{action}/{id})"]
public ActionResult GetAllClients(string id = null)
{
}
}
I wonder if it works well , and what is the real difference between them. Someone can help me?
Your first example is the configuration-based routing system, where you are handed a route builder and add your routes to it. This centralizes your route configuration code.
The second example is known as attribute routing. It allows you to specify the routes by applying attributes to controllers and action method.
They both still function. It comes down to a choice as to how you'd like to organize your code. And that's opinion based, so I will not delve into that discussion. Test both of them, and pick the one that you like best.
Note, these are not the only two options for routing. For example, SharpRouting adds functions to each controller to be called that create the routes through a fluent API. There are probably other options out there, or you can create your own!
For more information about routing in ASP.NET, see Microsoft's documentation.
Full disclaimer I work with the developer that created SharpRouting and we use it in our software (it may have been originally developed for our application, I'm not sure).
In my MVC 4 web appication if I access the Home page I call the following url:
sitename/Home
I now added a subfolder called Mobile to the Controllers folder.How can I configure routing to be able to call the Home controller in the Mobile folder like this
sitename/Mobile/Home
Here's my RegisterRoutes method:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "Test.Controllers" }
);
routes.MapRoute(
name: "Mobile",
url: "Mobile/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "Test.Controllers.Mobile" }
);
}
ASP.NET MVC routes are order dependant and should go in order of most specific to most generic.
At the moment, if you type the url Mobile/Home/Index the routing will try and map that to:
controller: Mobile
action: Home
id: Index
using the default route and never get to your intended route map.
If you swap the MapRoute declarations around, then MVC will see that it starts with "Mobile" and use that route as intended.
#dav_i is 100% correct in that the route needs to be before the other one. The URL for mobile has Mobile in the URL, so you would have to have Mobile in any action links or redirects... So ideally, in your global.asax, you'd try to detect whether the browser is mobile, and redirect within there... But you still have to manage having Mobile in the URL. That's because functions like Url.Action and Html.ActionLink expect the controller and action to be the full URL, and this:
#Url.Action("Action", "Control")
produces:
/Control/Action
And as such, you'd have to handle this. Alternatively, you could use mobile views without having to worry about this. See this tutorial.
Am building a CMS using MVC4. My experience with MVC is limited and trying to create a MapRoute that can handle the page structured created by the CMS. URLs for the pages would be along the lines of website.com/About
To handle this I have come up with the following
routes.MapRoute(
name: "Default",
url: "{p}",
defaults: new { controller = "Home", action = "Index", p = UrlParameter.Optional }
);
This works fine for root level pages but if I want sub pages like website.com/About/OurTeam
I get a 404. Ideally what I would like is just be able pass either the whole url after the .com bit as a string and sort it out in the controller or to split the levels up as an array of parameters and pass that through as 'p'.
Hope that makes sense. Any ideas?
You can use:
routes.MapRoute(
name: "Default",
url: "{*p}",
defaults: new { controller = "Home", action = "Index", p = UrlParameter.Optional }
);
The asterisk indicates that it's a catch-all route. Keep in mind that these routes are extremely greedy, make sure that this stays below any specific routes.
You could also add a route constraint to this route which can determine whether the page exists in the database or something. See this post for more info.
I have an mvc 2 application that is running in ii6 in the test environment and production server.
The test enviroment runs just fine, but after moving to production all pages except the home page server up 404 errors.
I have followed step 2, here: http://blog.codeville.net/2008/07/04/options-for-deploying-aspnet-mvc-to-iis-6/ and added a .aspx extension to the route, and have tried the wildcard mapping. It doesn't appear to make any difference.
I put the diagnostic file found here: http://bradwilson.typepad.com/blog/2010/03/diagnosing-aspnet-mvc-problems.html into the directory and loaded it, but it does not report any errors or problems.
I even wiped the test server and reinstalled the app from scractch, setup the wildcard mapping and it worked fine.
Right now the pages are being routed like: Home.aspx/About and my routing table looks like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?favicon.ico(/.*)?" });
routes.MapRoute(
"Default", // Route name
"{controller}.aspx/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"NewEmployee",
"{controller}.aspx/{action}",
new { controller = "NewEmployee", action = "Index" }
);
routes.MapRoute(
"Admin",
"{controller}.aspx/{action}",
new { controller = "Admin", action = "Index" });
routes.MapRoute(
"AccessMaster",
"{controller}.aspx/{action}/{id}/{subid}",
new { controller = "AccessMaster", action = "Index", id=UrlParameter.Optional,subid=UrlParameter.Optional });
routes.MapRoute(
"Root",
"",
new { controller = "Home", action = "Index", id = "" }
);
}
I'm at a loss here. Am I doing something wrong? Is there something wrong with the server?
Try registering ASP.NET with IIS using the following command:
aspnet_regiis /i
Also make sure that you have enabled the correct version of ASP.NET in IIS (Web Service Extensions folder):
You also have many unnecessary routes routes. For example the NewEmployee and Admin routes are totally equivalent meaning that only the first route in this list will ever be matched. But that's another problem, it is unrelated to the deployment errors you are getting. You could fix your routes once you make your application successfully run.
It looks like deleting and recreating the virtual directory magically fixed whatever was wrong with it.