RedirectToAction() to different folder - c#

Hey Guys I have easy problem, I want to change start page.
In HomeControllers.cs I have:
public ActionResult Index()
{
if (Session["LoginId"] == null)
{
return RedirectToAction("Login.aspx");
}
return View();
}
It redirects to: http://localhost/TutorialCS/Home/Login.aspx
But I want to get rid off the /Home
When in Global.asax.cs I change;
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
to one without {Controller}:
routes.MapRoute(
"Default", // Route name
"{action}/{id}", // URL with parameters
new { action = "Index", id = "" } // Parameter defaults
);
It redirects to correct repository, but page dosen't work anymore I suppose this changes a lot of paths.

RedirectToAction has another overload that accepts controller name as the second parameter:
protected internal RedirectToRouteResult RedirectToAction(
string actionName,
string controllerName
)
So:
return RedirectToAction("Login", "Account");
Update: If you want to redirect to this URL:
http://localhost/TutorialCS/Login.aspx
You should use Redirect method:
return Redirect("~/TutorialCS/Login.aspx");

You just need to use method call with two parameters: Action name and Controller Name:
RedirectToAction("Login", "Account")

Related

URL Routing with an MVC

I am making a website that displays a bunch of articles. It is built off a MVC I want to be able to search for articles by day and then by an ID number via url.
If the domain name is website.com, I'm trying to figure out how to make routes so that website.com/yyyymmdd hits a specific controller+method and displays all the articles for that day and website.com/yyyymmdd/111 searches that day's articles for article #111.
The issue I'm having is that all the tutorials for routing within an MVC assume I will specify the controller and method in the URL. They show something like:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" });
}
If anybody could suggest a way to automatically make "website.com/yyyymmdd/111" use a specified controller and method, that'd be amazing. Thanks in advance!
EDIT:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Today",
"{date}/{id}",
new { controller = "Articles", action = "Index", date = DateTime.Today.ToString("yyyyMMdd"), id = UrlParameter.Optional });
}
I've done this as my route and my method is as follows:
public ActionResult ArticlesByDate(string date, int id)
{
if(id > 1)
{
return View(Contact());
}
else
{
return View(About());
}
}
I hope I am understanding your guys' suggestions, but this is giving me a "Resource can not be found" error when i try to navigate to: "http://localhost:52159/20160908/2"
One way this can be solved by using the date as a parameter to the action.
Your action would look like
public ActionResult Index(string articleDate,string id) ...
The your route definition would be something like
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Default",
"{controller}/{action}/{articleDate}/{id}",
new { controller = "Home", action = "Index",articleDate=DateTime.Today.ToString("yyyyMMdd"), id = "" });
}
Then you can take it from there
Second route for default mvc routing mechanism.
First route is for articles.Controller and action value is static. You can change date and id values for website.com/20160911/111 , website.com/20160912/112 etc.
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
name: "Articles",
url: "{date}/{id}",
defaults: new { controller = "Articles", action = "Info"});
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
public class ArticleController : Controller {
public ActionResult Info(string date, int id){
return View();
}
}
you cant redirect two view in an action. Use one view and partial views within.
for example
Info.cshtml
#if(id > 1)
{
#Html.Partial("_Contact")
}
else
{
#Html.Partial("_About")
}

MVC4 Custom Routing - Validating Personalized Urls

I have a website in MVC4 that I am developing that requires some custom routing. It is a simple website with a few pages. For example:
/index
/plan
/investing
... etc.. a few others
Through an admin panel the site administrator can create "branded" sites, that basically mirror the above content, but swap out a few things like branded company name, logo etc. Once created, the URLs would look like
/{personalizedurl}/index
/{personalizedurl}/plan
/{personalizedurl}/investing
... etc... (exact same pages as the non branded pages.
I am validating the personalized urls with an action filter attribute on the controller method and returning a 404 if not found in the database.
Here is an example of one of my actions:
[ValidatePersonalizedUrl]
[ActionName("plan")]
public ActionResult Plan(string url)
{
return View("Plan", GetSite(url));
}
Easy-peasy so far and works pretty well with the following routes:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Admin",
url: "Admin/{action}/{id}",
defaults: new { controller = "Admin", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{action}",
defaults: new { controller = "Default", action = "Index" }
);
routes.MapRoute(
"Branded", // Route name
"{url}/{action}", // URL with parameters
new { controller = "Default", action = "Index" } // Parameter defaults
);
/*
routes.MapRoute(
"BrandedHome", // Route name
"{url}/", // URL with parameters
new { controller = "Default", action = "Index" } // Parameter defaults
);
*/
}
The problem I currently have is with the bottom commented out route. I'd like to be able to go to /{personalizedurl}/ and have it find the correct action (Index action in default controller). right now with the bottom line commented out, I get a 404 because it thinks its an action and its not found. When I un-comment it, the index pages, work however the individual actions do not /plan for example because it thinks its a pUrl and can't find it in the database.
Anyway, sorry for the long question. Any help or suggestions on how to set this up would be greatly appreciated.
James
The problem is that MVC will use the first matching url and since the second route is:
routes.MapRoute(
name: "Default",
url: "{action}",
defaults: new { controller = "Default", action = "Index" }
);
and that matches your /{personalizedurl}/ it will route to Default/{action}.
What you want gets a bit tricky! I assume the personalizing is to be dynamic, not some static list of branded companies and you wouldn't want to recompile and deploy every time you add/remove a new one.
I think you will need to handle this in the controller, it won't work well in routing; unless it is a static list of personalized companies. You will need the ability to check if the first part is one of your actions and to check if it is a valid company, I will give you an example with simple string arrays. I believe you will be building the array by query some sort of data store for your personalized companies. I also have created a quick view model called PersonalizedViewModel that takes a string for the name.
Your routing will be simplified:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Admin",
url: "Admin/{action}/{id}",
defaults: new { controller = "Admin", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{url}/{action}",
defaults: new { controller = "Default", action = "Index", url = UrlParameter.Optional }
);
}
Here is the view model my example uses:
public class PersonalizedViewModel
{
public string Name { get; private set; }
public PersonalizedViewModel(string name)
{
Name = name;
}
}
And the Default controller:
public class DefaultController : Controller
{
private static readonly IEnumerable<string> personalizedSites = new[] { "companyA", "companyB" };
private static readonly IEnumerable<string> actions = new[] { "index", "plan", "investing", "etc" };
public ActionResult Index(string url)
{
string view;
PersonalizedViewModel viewModel;
if (string.IsNullOrWhiteSpace(url) || actions.Any(a => a.Equals(url, StringComparison.CurrentCultureIgnoreCase)))
{
view = url;
viewModel = new PersonalizedViewModel("Default");
}
else if (personalizedSites.Any(s => s.Equals(url, StringComparison.CurrentCultureIgnoreCase)))
{
view = "index";
viewModel = new PersonalizedViewModel(url);
}
else
{
return View("Error404");
}
return View(view, viewModel);
}
public ActionResult Plan(string url)
{
PersonalizedViewModel viewModel;
if (string.IsNullOrWhiteSpace(url))
{
viewModel = new PersonalizedViewModel("Default");
}
else if (personalizedSites.Any(s => s.Equals(url, StringComparison.CurrentCultureIgnoreCase)))
{
viewModel = new PersonalizedViewModel(url);
}
else
{
return View("Error404");
}
return View(viewModel);
}
}

MVC URL re-writing

I have Login action method in my home controller like this
[HttpGet]
public ActionResult Login()
{
return View();
}
I am having this Action method as start page of my application, however I want to re-write it like this
www.abc.com/MySite/security/login
I write this attribute after [HttpGet]
[Route("MySite/security/Login")]
Now the problem is,when I am running the application,its giving me error
The resource cannot be found.
This is my RoutConfig
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 = "Login" , id = UrlParameter.Optional }
);
}
How can I fix this issue,Also I am having same name method with HttpPost attribute,should I have to write Rout Attribute on it as well?
This should do the work:
[RoutePrefix("MySite/Security")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpGet]
[HttpPost]
[Route("Login")]
public ActionResult Login()
{
return View("~/Views/Home/Index.cshtml");
}
}
EDITED:
There is one way, but I'm not sure if it's the best way. You need to create another controller called DefaultController like this:
public class DefaultController : Controller
{
//
// GET: /Default/
public ActionResult Index()
{
return RedirectToAction("Login","Home");
}
}
In your RouteConfig.cs, change the 'Default' route with this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
This should do the job. I'm still trying to find other better ways.
First, you should add custom route on the top of a default route, since you have 2 action methods with different HTTP protocols and want to make custom routing with same action name.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
// custom route
routes.MapRoute(
name: "Login",
url: "MySite/{controller}/{action}/{id}",
defaults: new { controller = "Security", action = "Login", id = UrlParameter.Optional }
);
// default route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home" , action = "Index" , id = UrlParameter.Optional }
);
}
Note that your controller with Login method should be named SecurityController, then you can set attribute routing like this code:
// set all default prefix to /Security path
[RoutePrefix("Security")]
public class SecurityController : Controller
{
[Route("Login")]
public ActionResult Login()
{
return View();
}
}
Additionally, make sure you already registered the route in Global.asax file.
Any improvements & suggestions welcome.

MVC routing only applying to certain action results

Do I have to route a special route for every action result in a controller, or do you do one route, and have to live by that standard thought the controller? I thought you could make a default route, and then a special route for any instance you wanted. I keep running into a problem where one of my routes will hit my action Results correctly, but then the others no longer work. This code is probably the wrong way, but hence why I am posting it here. PLease try to clarify this for me if you can. I understand that I am suppose to be able to do {controller}/{action}/{id} for example. So that should hit Settings/GetSite/{siteid} for the following
public ActionResult GetSite(int id);
Routes configuration:
routes.MapRoute(
"SettingsUpdateEnviorment",
"{controller}/{action}",
new { controller = "Settings", action = "UpdateProperties" },
new { httpMethod = new HttpMethodConstraint("POST") }
);
routes.MapRoute(
name: "ProfileRoute",
url: "Profiles/{userId}",
defaults: new
{
controller = "Profile",
action = "Index",
}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"Settings", // Route name
"Settings/{id}", // URL with parameters
new { controller = "Settings", action = "Index" } // Parameter defaults
);
Controller Code:
public ActionResult Index(int id)
{
return View(model);
}
public ActionResult GetSite(int enviornmentID, string name)
{
return RedirectToAction("Index");
}
[HttpPost]
public ActionResult AddSite(int id)
{
return RedirectToAction("Index", new { id = id });
}
So, the URL works as expected for Settings/1 to hit the Index actionresult Index(int id). Then, when I try to do the ActionResult for GetSite(int enviornmentID, string name) using the following actionLink:
#Html.ActionLink(site.Name, "GetSite", "Settings", new { enviornmentID = Model.Enviorment.EnvironmentID, name = site.Name }, null)
It creates the URL correctly as follows: Settings/GetSite?enviornmentID=1&name=CaseyTesting2, but gives me an error stating that I am trying to send a null value to my Index(int id) actionResult. I thought that since I am using the action name and it's same params, that MVC will figure the route out? Why is this not functioning for me, or what I am doing wrong? Thanks!
I realized what I was doing thanks to this article http://www.itworld.com/development/379646/aspnet-mvc-5-brings-attribute-based-routing. I was mixing up the order, when I had everything else correct. Then I was missing the param names being identical, when everything else was correct. So I kept having minor issues when trying to find the problem out. I also switched to MVC5's attribute routing, and like it much more.
So this is my code that is now working:
RoutConfig
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "ProfileRoute",
url: "Profiles/{userId}",
defaults: new
{
controller = "Profile",
action = "Index",
}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The controller code
[Authorize]
[RoutePrefix("settings")]
[Route("{action=index}")]
public class SettingsController : ZenController
{
[Route("{id:int}")]
public ActionResult Index(int id)
{
return View(model);
}
[Route("GetSite/{sitename:alpha}")]
public ActionResult GetSite(string sitename)
{
return RedirectToAction("Index");
}
Thanks again everyone! Happy coding!

RedirectToAction in MVC3 returns "No route in the route table matches the supplied values"

I use this log in controller :
public ActionResult Index(LoginModel model)
{
if (model.usernam == "usernam" && model.password == "password")
{
return RedirectToAction("Index", "Home");
}
return View();
}
This RedirectToAction returns this exception: No route in the route table matches the supplied values.
In my Globa.asax I have this values which I think it may solve the problem but I don't know how
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}/{id1}/", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional, id1= UrlParameter.Optional} // Parameter defaults
);
}
I googled searched the web I found many suggestions, but nothing works.
Is there any solution for this??
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}/{id1}/", // URL with parameters
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional,
id1 = UrlParameter.Optional
} // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}", // URL with parameters
new { controller = "Home", action = "Index" } // Parameter defaults
);
}
If you pay attention to the above code you were missing the default route without parameters.

Categories

Resources