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();
}
}
Related
I am trying to prevent user to access abc.com/Home/Index, instead i want user to be able to access home page via abc.com only. I use the following code but not work.
// This code restict user to access abc.com/home/index
// Only allow user to access abc.com/home
routes.MapRoute(
"OnlyAction",
"{action}",
new { controller = "Home", action = "Index" }
);
// This code does not work, I am expecting this code to allow
// user to access home only at abc.com
routes.MapRoute(
"Home",
"",
new { controller = "Home", action = "Index"}
);
You just need to ignore the URL:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Ignore the alternate path to the home page
routes.IgnoreRoute("Home/Index");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Then the server will return a 404 not found instead of a page.
Of course, if you wanted to remove all of the alternate paths for the entire application, you would need to remove the default values of the Default route, which will make them required.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Ignore the alternate path to the home page
routes.IgnoreRoute("Home/Index");
routes.MapRoute(
name: "Home",
url: "",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { id = UrlParameter.Optional }
);
}
}
Now you won't be able to access the home page by /Home/, either (which is another route that accesses it using the default route).
Of course, the best option is to use the canonical tag to ensure no additional routes that may slip through damage your SEO score.
<link rel="canonical" href="http://example.com/" />
I'm building an intranet where I have the following home controller:
[Route("{action=index}")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View(HomeModelBuilder.BuildHomeModel());
}
public ActionResult FormsHome()
{
return View(HomeModelBuilder.BuildFormsHomeModel());
}
}
I'm trying to get my forms homepage to have a url of http://intranet/forms so I thought I could do this using the following routing attribute:
[Route("~/forms")] // have also tried 'forms' and '/forms'
public ActionResult FormsHome()
but when I go to the url, it complains that multiple controllers have that route:
The request has found the following matching controller types:
HRWebForms.Website.Controllers.ChangeDetailsController
HRWebForms.Website.Controllers.InternalTransferController
HRWebForms.Website.Controllers.LeaverController
...
I have also tried adding [RoutePrefix("")] to the controller but this didn't work either
Is there a way to give that action a url of "forms" (without any controller or without adding a separate forms controller with an index) by just using routing attributes?
You could try adding [RoutePrefix("forms")] to your controller, but this will result in all your actions expecting the same prefix.
There is a walkaround for this too (by using [Route("~/RouteParam/AnotherRouteParam")] to have Route "RouteParam/AnotherRouteParam") but it seems to me that FormsController would cost less work.
Ok so ranquild's comment pushed me in the right direction. In my route config, I had the default route of
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
So that my homepage would still work on the url with nothing in. If I changed this to
// Needed for homepage
routes.MapRoute(
name: "Home",
url: "",
defaults: new { controller = "Home", action = "Index" }
);
// Needed for Html.ActionLink to work
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = UrlParameter.Optional, action = UrlParameter.Optional }
);
It seemed to solve the problem
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" });
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"
);
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)