My question has 2 parts:
1
My MVC project has folder structure like so:
I want to create a link in the 'Create' page that links to the 'Savings' WebForm
I've tried adding this to the RouteConfig:
routes.MapPageRoute(
"idea-savings-calculator",
"Idea/Savings",
"~/Views/Idea/Savings.aspx"
);
but the default MVC MapRoute function:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
maps to the URL localhost:xxxx/Idea/Savings first and throws an error because there isn't an action called savings in the Idea controller Savings.
Edit: RouteConfig Class:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.MapPageRoute(
"idea-savings-calculator",
"Idea/Savings",
"~/Views/Idea/Savings.aspx"
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
2
Below is a cut from the 'Create' View of the 'Idea' Controller URL: http://localhost:51946/Idea/Create
(red box indicates where I'd like the link to the Savings WebForm)
The Savings WebForm is just a simple calculator; how would I pass the product from the calculations back to the above 'Create' page so that it can be displayed in the bottom text box? I'm guessing it would be as a parameter in the url that the Idea Controller can match? But... How?
Thanks!
So to solve my first problem I moved the WebForms page 'Savings.aspx' to the route of my project and used the MapPageRoute after the MapRoute method.
routes.MapPageRoute(
"idea-savings-calculator",
"Idea/Savings",
"~/Savings.aspx"
);
Related
As explained already in my earlier posts I am newbie to MVC and I am developing a website. Everything works fine except for the little change that I did on my route.config file. I need to direct users to a view which is opened from a button on another view and is dependent on the parent view. It means it should not be allowed to be accessed independently.
Editing it to be more clear.
This is the problem.
customers login to my website and see their account activity page and once in they can choose to make a payment if they have any due amount. When they click on the payment button they are directed to the payment website and once they are done, they are redirected back to my website where they see a confirmation page/view.
So the URLs are like this right now.
http://www.examplesite.com/Homecontroller/Loginview/ - for login.
After login the URL is this
http://www.examplesite.com/Homecontroller/CustActview/
After returning from the payment site, the URL should be related to the custAct View because it is related to an account, So I want it to be as
http://www.examplesite.com/Homecontroller/CustActview/successfulpaymentview
so in order to achieve this I have added that other route in my route.config, but adding that has given me another problem, now if I login, the URL changes to this
http://www.examplesite.com/Homecontroller/CustActview/CustActview
So I m not sure how to handle this. Please help. Hope this is clear.
Route.config
routes.MapRoute(
name: "Properties",
url: "{controller}/CustAcct/{action}/{id}",
defaults: new
{
controller = "HomeController",
action = "successfulpaymentview",
id = UrlParameter.Optional
}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
controller = "HomeController",
action = "LoginView",
id =
UrlParameter.Optional
}
);
In my opinion, it is not necessary to add complexity in routing only to restrict direct access to that view.
Maybe, you should try using Action Filters.
Beyond that comment, in your route config you have defined two actions...
url: "{controller}/CustAcct/{action}/{id}",
CustAcct and {action}
Try something like this:
routes.MapRoute(
name: "Properties",
url: "Home/CustAcct/{param1}/{param2}/..."
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
controller = "Home",
action = "Login",
id = UrlParameter.Optional
}
);
Update:
Ok, I get the idea! You RouteConfig.cs should be:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "AccounInfo-Success",
url: "{controller}/AccounInfo/{action}/"
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional }
);
}
}
and your HomeController:
public class HomeController : Controller {
public ActionResult AccountInfo() {
return View();
}
public ActionResult Success() {
return View();
}
}
I have a requirement in which I have to map the below url
/amer/us/en/ = Home controller
/amer/us/en/login/index = Home controller
/amer/us/en/confirmation = Confirmation controller
along with the regular default action.
Eg if user goes to
http:\\test.com --> http://test/home/index
http:\\test.com/amer/us/en/login/index --> http://test/home/index
http:\\test.com/amer/us/en/ --> http://test/home/index
I was looking into attribute routing and so I added the below code in HomeController
[RoutePrefix("amer/us/en/")]
[Route("{action=index}")]
public class HomeController : Controller
{
}
and I am getting this error
The route prefix 'amer/us/en/' on the controller named 'Home' cannot begin or end with a forward slash and also the default routing is not working now so http://test.com is not loading anything. Below is my default RouteConfig class.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Very new to MVC. Can someone tell me what I am doing wrong here.
Routing in MVC works either by defining your routes in the RouteConfig class or by attribute routing (or you can use Areas). Routing with RouteConfig works with the order you define the routes with. When a request comes, MVC will try your routes from top to bottom and execute the first one that it can match with the requested url. So the routing need in your example can be achieved by:
routes.MapRoute(
name: "RootLogin",
url: "amer/us/en/login/index/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "DefaultAmer",
url: "amer/us/en/{controller}/{action}{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
this will map login as a special route and all the other /amer/us/en/ routes will go to whatever controller comes after and whatever action of it. The last route, if the request does not start with /amer/us/en will perform the default behavior.
Looks like, however, you want to define /amer/us/en/ as an Area, so you might want to take a look into that as well.
I have an nicely functioning ASP.Net MVC site using the simple standard routing scheme:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
My client would like to redirect the static pages to a secondary site, so that they can edit them, template-style, at will. The pages that actually do something will remain on the original site.
What I need to do is set up routes for my functional views/controller-actions and redirect the remaining urls to the external site regardless of whether or not the specified url has a matching controller/action. I don't want to mess with the existing code, but use routing to execute some of the pages and redirect from others.
For example:
mysite.com/sponsors/signup would be executed
mysite.com/sponsors/information would be redirected
Even though the sponsors controller contains actions for both signup and information and there are existing views for both signup and information.
So far, I have been unable to wrap my head around a way to do this.
Any ideas?
You can use attribute routing to make it easier.
Your RouteConfig will look like below:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes(); // enable attribute routing
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
}
Then you can add an action like below:
public class SponsorsController : Controller
{
[Route("sponsors/information")]
public ActionResult RedirectInformation()
{
return RedirectPermanent("http://yoururl.com");
}
}
EDIT ONE
If you don't want to use attribute routing, you are still going to need the action but your RouteConfig will look like below:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//The order is important here
routes.MapRoute(
name: "redirectRoute",
url: "sponsors/information",
defaults: new { controller = "Home", action = "RedirectToInformation"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
In routing like this, if the match is found the rest of the routes are ignored. So, you'd want to put most specific route on top and most general in the bottom
EDIT TWO (based on the comment)
You can put a simple appsettings in Web.config like below:
<appSettings>
<add key="UseAttributeRouting" value="true" />
</appSettings>
Then in RegisterRoutes you can read it like below and make the decision.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
if (Convert.ToBoolean(ConfigurationManager.AppSettings["UseAttributeRouting"]))
{
routes.MapMvcAttributeRoutes();
}
else
{
routes.MapRoute(
name: "redirectRoute",
url: "sponsors/information",
defaults: new {controller = "Home", action = "RedirectToInformation"}
);
}
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
The browser sometimes caches these redirects, so you may want to recommend clearing browser caches if you change these settings. Check this superuser post for clearing the cache for Chrome.
You have two options
i) This is perfect use case to write a custom mvchandler that is instatiated by a custom IRoutehandler. You can follow this example.
http://www.eworldui.net/blog/post/2008/04/aspnet-mvc---legacy-url-routing.aspx.
ii) You can write HttpHandler for these matching paths you can redirect them to the other site.
Step 1: add this to RouteConfig.cs
routes.IgnoreRoute("yourwebpage.aspx");
Step 2: create new file at root of website called "yourwebpage.aspx"
Step3: Inside yourwebpage.aspx put:
<%
Response.RedirectPermanent("http://yourwebsite.com");
%>
It is pretty simple.
Create an Action
public ActionResult ext(string s)
{
return Redirect(s);
}
And in Routeconfig file add
routes.MapRoute(name: "Default17", url: "routeyouwant", defaults: new { controller = "Home", action = "ext", s = "http://externalurl.com" });
I have a controller with an index action.
public ActionResult Index(int id = 0)
{
return view();
}
I wish to pass id into the index action, however it doesnt appear to work in the same way as the details action.
e.g. if I want to pass id 4 into the index action, I have to visit url:
http://localhost:8765/ControllerName/?id=4
With the details Action... I can do this.
http://localhost:8765/ControllerName/Details/4
What I want to do with Index is something like...
http://localhost:8765/ControllerName/4
When I visit this url, I get an error:
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /fix/1
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.17929
Is this possible? How can I get MVC to automatically treat the index action in the same way as the details one?
Thanks
UPDATE - MY CURRENT ROUTES CONFIG
public class RouteConfig
{
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 }
);
}
}
UPDATE NEW RouteConfig Class still doesn't work when I visit localhost:1234/Fix/3
public class RouteConfig
{
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 }
);
routes.MapRoute(
name: "FixIndexWithParam",
url: "Fix/{id}",
defaults: new { controller = "Fix", action = "Index", id = UrlParameter.Optional });
}
}
Update It's worth pointing out, /ControllerName/Index/4 should work with the default route.
With the default route there, it expects the second parameter to be the controller name.
So with the Default Route /ControllerName/4 is being interpereted as ControllerNameController Action 4, which of course does not exist.
If you add
routes.MapRoute(
name: "IndexWithParam",
url: "{controller}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
before the default one it would allow
/Home/4 to be routed to HomeController action Index with id=4
I have't tested this, it may conflict with the default. You may need to specify the controller explicitly in the route, ie:
routes.MapRoute(
name: "HomeIndexWithParam",
url: "Home/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
(Obviously, replace Home with whatever controller you're actually wanting to route to)
This is my first ASP MVC project so I'm not sure how to do this.
I have a section called Admin, which has an Admin controller. I'm using this for just an index page.
In the Admin section, there are different sections. Let's say Company and Line Of Business
I want to handle everything for those in their own CompanyController and LineOfBusinessController
I want the routes to be prefixed with Admin though ie. Admin/Company, Admin/Company/Add
I have achieved this by adding a route before the Default route that is this
routes.MapRoute(
name: "Admin",
url: "Admin/{controller}/{action}/{id}",
defaults: new { controller = "Admin", action = "Index", id = UrlParameter.Optional }
);
The problem is now all my routes choose this one over the default, meaning everything else becomes Admin/Section ie Admin/Home etc.....
I tried using Html.RouteLink instead of ActionLink and the URL's were formatted correctly, but when I go to Admin/Company it can't find because it assumes Company is in AdminController
How can I route this properly?
EDIT
Here are my routes, and then my links
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapRoute(
name: "Admin",
url: "Admin/{controller}/{action}/{id}",
defaults: new { controller = "Admin", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Links
<li>#Html.ActionLink("Home", "Index", new { controller = "Home" }, ViewBag.SelectedNav == "Home" ? new { #class = "active" } : null)</li>
The link ends up /Admin/Home
UPDATE
Did not mark an answer here as I ended up exploring, and ultimately using Areas. It was suggested in the one answer, but the rest of the answer is not correct so I did not want to mislead anyone. Thanks for the Area suggestion however
Have the generic routing below your specific one. The order of routing definition is important. When MVC finds a matching route for a request, it won't process the rest.
routes.MapRoute(
name: "Admin",
url: "Admin/{controller}/{action}/{id}",
defaults: new { controller = "Admin", action = "Index",
id = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index",
id = UrlParameter.Optional } // Parameter defaults
);
Also it is better for your to use Areas in this scenario. It is a better approach when you want to structure your app in to different sections like Admin / Normal user etc..
Since I don't know what the link behavior should be, the best thing I can suggest is to debug your routes and see which route is handling which URL's.
1) Go into Visual Studio and install the RouteDebugger
PM> Install-Package routedebugger
2) Add some code to your global file
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
}
3) Run your site and request your questionable links.
4) Review your results and modify accordingly
Edit: it appears as though RouteDebugger v2 is now RouteMagic
PM> Install-Package RouteMagic
And you can find the source code on github