I aim to get these URIs to work in ASP.NET MVC:
http://localhost:57165/Blas/bla1.xml
http://localhost:57165/Blas/bla2.xml
...
http://localhost:57165/Blas/blan.xml
As you can see the file name can vary and the controller action is ultimately meant to spew out xml file given the file name.
I have this controller:
public class BlasController : Controller
{
// GET: SiteMaps
public ActionResult Index(string fileName)
{
return View();
}
}
and this routing code:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Blas",
"{controller}/{fileName}"
);
}
Unfortunately, I get a 404. Is it possible to get this to work?
PS:
I think this is related:
Create a MVC route ending ".js" and returning JavaScript?
First, you should fix your RegisterRoutes method this way:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
name: "FileRoute",
url: "{controller}/{fileName}",
defaults: new { action = "Index" },
constraints: new { fileName = #"^[\w\-. ]+$" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Second, add this rows to web.config:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
P.S. You can process requests to files only at Index action.
Start using Routes which is available in App_Start/RouteConfig.cs
it has some documentation here:
//This is Static Route.
routes.MapRoute(
name: "BlaBla",
url: "/Blas/bla.txt",
defaults: new { controller = "YourController", action = "YourAction" }
);
if you want to send some file to user try an action in controller to send it as ContentResult for you. then Route all of them in RouteConfig.
You can add route config on the method :
[Route("Blas")]
public class BlasController : Controller
{
[HttpGet("{fileName}")]
public ActionResult Index(string fileName)
{
return View();
}
}
Related
I've a strange behavior of configured route in Route Config in MVC5 app.
So, actually I try to do pretty much easy thing - change default action of a route.
To do that I've changed the defaults of a route, instead of having action = "Index", I've changed it to my required action AddUser (Look at the code below).
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "ManageUser",
url: "{controller}/{action}/{id}",
defaults: new { controller = "ManageUser", action = "AddUser", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
And I've next controller:
[Authorize(Roles ="Admin")]
public class ManageUserController : Controller
{
// GET: ManageUser/AddUser
[HttpGet]
public ActionResult AddUser()
{
return View();
}
}
So, now I expect that whenever user goes by URL: ManageUser/ he'll be redirected to defined default action but it doesn't happen, I just have 404 error. I can fix it simply by adding Index action and then redirect to AddUser, but it doesn't seem right to me. Could somebody help me understand what I've done wrong?
I think, your config should look like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"ManageUser",
"ManageUser/{action}/{id}",
new { controller = "ManageUser", action = "AddUser", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
The first parameter is the name of the route. Second is the URL, which match URLs that start with ManageUser, and allows for other actions in your ManageUser controller. As you can see, it will default to the AddUser action.
And if you want to call AddUser with paramater, you must call it by full url ManageUser/AddUser/1
With respect to this Attibute route when i run application i am getting HTTP 404 Not Found result why?.
[Route("custom/route/{id}/{name}")]
public ActionResult Student(int id, string name)
{
return Content(string.Format("id = {0} & name = {1}", id, name));
}
Result:
Make sure your RouteConfig.cs looks something like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection Routes)
{
Routes.IgnoreRoute("{resource}.ashx/{*pathInfo}");
Routes.MapMvcAttributeRoutes();
Routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
namespaces: new string[] { "YourControllerNamespace.Controllers" },
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Please pay attention to namespace parameter in Routes.MapRoute
This question already has answers here:
Routing in ASP.NET MVC, showing username in URL
(2 answers)
Closed 4 years ago.
I have an Asp.Net MVC project whereby we allow our users to have public profiles.
I would like to improve the url, so that it is more friendly, and shorter.
The existing code is as follows -
public class ProfileController : Controller
{
private readonly IUserProfileService _userProfileService;
public ProfileController(IUserProfileService userProfileService)
{
this._userProfileService = userProfileService;
}
public ActionResult Index(string id)
{
//Get users profile from the database using the id
var viewModel = _userProfileService.Get(id);
return View(viewModel);
}
}
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//Required for the route prefix attributes to work!
routes.MapMvcAttributeRoutes();
routes.MapRoute(
"ProfileUrlIndexActionRemoval",
"Profile/{id}",
new { controller = "Profile", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
The aforementioned code allows the following url to work (based on the default MVC routing) - www.mydomain.com/profile/john-doe
What routing do I need to implement, in order to allow the following url to work instead - www.mydomain.com/john-doe
Thanks.
This is a little tricky as you want the friendly URL in the root of the site while not conflicting with any other routes.
That would mean that if you have any other routes like About or Contact you would need to make sure that are in the route table before the friendly route to avoid route conflicts.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//Required for the route prefix attributes to work!
routes.MapMvcAttributeRoutes();
routes.MapRoute(
"ProfileUrlIndexActionRemoval",
"Profile/{id}",
new { controller = "Profile", action = "Index" }
);
routes.MapRoute(
name: "Home",
url: "Home/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "About",
url: "About/{action}/{id}",
defaults: new { controller = "About", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Contact",
url: "Contact/{action}/{id}",
defaults: new { controller = "Contact", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default_Frieldly",
"{*id}",
new { controller = "Profile", action = "Index" }
);
}
}
And finally because the default route will capture all unmatched routes, you will need to take not found profiles into account.
public class ProfileController : Controller {
//...code removed for brevity
public ActionResult Index(string id) {
//Get users profile from the database using the id
var viewModel = _userProfileService.Get(id);
if(viewModel == null) {
return NotFound();
}
return View(viewModel);
}
}
By having the profile controller prefix in the original URL it made it unique so as to avoid route conflicts, but in wanting the root friendly URL, while not impossible, you see the hoops needed to jump through in order to get the desired behavior.
This is how I would do it. Register a route that matches any string after the root slash.
Note that this severely limits the routes you can use for the application since not everything matching /{id} may actually be a user ID, which is why applications will typically prefix the route with /profile or /p.
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
name: "UserIdRoute",
url: "{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 }
);
}
public ActionResult Index(string id)
{
//Get users profile from the database using the id
var viewModel = _userProfileService.Get(id);
return View();
}
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")
}
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.