Easiest way to do URL rewrite in .NET - c#

I have a blog that I have built. It uses a web api in c# .NET.
If you click here: http://www.judsondesigns.com/api/blogapi/17
You will see it return an entry from the server. How can I easily rewrite the url to use the blog title instead of the ID?
So instead you can access it via: http://www.judsondesigns.com/api/blogapi/my_blog_tite_here
I have done this with isapi rewrites in the past on linux, but wasnt clear how to in .NET. I have heard different way but would like the less is more approach here. Thanks in advance. -Judson

What you want to do is create a custom RouteBase. This code review post is a good place to start.
The jist of it is:
public class MyRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
// parse url and turn into route
}
public override VirtualPathData GetVirtualPath(
RequestContext requestContext,
RouteValueDictionary values)
{
// create url from route
}
}
Which you then register along with any other routes like
routes.Add(new MyRoute());

By editing the route configuration:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{blogTitle}",
defaults: new { controller = "Home", action = "Index", blogTitle = UrlParameter.Optional }
);
}
}
or rewrite the action to use the name instead and using a named parameter
http://www.judsondesigns.com/api/blogapi/?blogtitle=my_blog_tite_here

Related

Is there any way to make a custom route in C# MVC? [duplicate]

This question already has answers here:
Routing in ASP.NET MVC, showing username in URL
(2 answers)
Closed 4 years ago.
I am new to C# MVC,
This is my default RouteConfig File,
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 }
);
}
}
When I run my project http://localhost:50382 it redirects the default home index method.
How can I build custom url like http://localhost:50382/somestringcode and call a specific ActionMethod. Something Like a custom route that points to specific ActionMethod and the stringcode will be passed as parameter.
public ActionResult Method1( string code)
{
return View();
}
What you are searching for is attribute routing. That means specifying URL routes explicitly.
First, you need to enable it
routes.MapMvcAttributeRoutes();
Then add Route attribute to desired action:
[Route("")]
public ActionResult Method1( string code)
{
return View();
}
Since code parameter is simple type, it will be searched in request URL.
You need to do something like this, where controller1 is the controller name that contains Method1, and make sure you place this first, and leave the original route config, so when it doesn't match this route, it will use default route.
Please note this is bad practice, and it will fail in case route is trying to access default action for a controller "Index" as #stephen mentioned in the comments below, and that's why I would suggest adding a prefix ex "Action1" to the route.
routes.MapRoute
(
name: "Method1",
url: "Action1/{code}",
defaults: new { controller = "controller1", action = "Method1", code = "default"}
);

asp mvc core url localization

I am trying to localize my app's URLs. Unfortunately, most of the pages show me examples of app localization Like :
http://localhost/en-US/Home/Index
This is not what I want. I would to localize the URLs like that:
http://localhost/Welcome
http://localhost/Bienvenue [ welcome word in French ]
The culture has aleady been managed on my side with a cookie and working well with "CookieRequestCultureProvider" class.
So I have this information and localization in pages are OK.
I succeeded to register all the routes I need. Both of example above working and display the page. Thanks to this :
public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{
foreach (var action in controller.Actions)
{
var localizedRouteAttributes = action.Attributes.OfType<LocalizedRouteAttribute>().ToArray();
if (localizedRouteAttributes.Any())
{
foreach (var localizedRouteAttribute in localizedRouteAttributes)
{
var localizedVersions = GetLocalizedVersionsForARoute(localizedRouteAttribute.Name); // GetLocalizedVersionsForARoute contains all routes translated and group by culture.
foreach (var localizedVersion in localizedVersions)
{
if (!action.Selectors.Any(s => s.AttributeRouteModel.Template == localizedVersion.Template))
action.Selectors.Add(new SelectorModel(action.Selectors.First()) { AttributeRouteModel = localizedVersion });
}
}
}
}
}
}
So mvc take the last route register in Selectors (if FR, it take FR route).
I can't manage the other routes by this piece of code because it's load with the app. And can't work with a dynamic use (The app permit to change the lang when I want).
Thanks in advance.
I found this example project works: https://github.com/tomasjurasek/AspNetCore.Mvc.Routing.Localization
Once it's set up, you can tag routes with
[LocalizedRoute("culture", "RouteName")]
Do that for each culture you want a unique name for, and the dynamic route it creates will translate to the proper action and execute it. It's also got a tag helper for creating translated links, though if you want to use Url.Action or Html.ActionLink, I find you have to create extension methods that take the culture into account to get them to work fully.
In your case wanting them at the route level instead of /culture/Controller/Action may take some more work, but it might be a useful starting place for you.
look in this little example I hope to help you :)
1) in your controller :
[RoutePrefix("/")]
public HomeController : Controller {
[HttpGet]
[Route("Welcome")]
public ActionResult Index() {
return View();
}
}
And enable it in route table " routes.MapMvcAttributeRoutes(); " like this
public class RouteConfig {
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//enable attribute routing
routes.MapMvcAttributeRoutes();
//convention-based routes
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = "" }
);
}
}
I suggest reading this article from this URL:
https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/
if you have any other question you can ask me

MVC Conventional and Attribute routing not working together

I am using conventional routing on an ASP.Net MVC project and would like to enable Attribute routing in parallel. I have created the following but I am getting a 404 on the conventional route when enabling attribute routing
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 }
);
}
Controller
[RoutePrefix("Registration")]
public class RegistrationController : Controller
{
[HttpGet]
[Route("Add/{eventId}")]
public ActionResult Add(int eventId)
{
}
}
Calling
http://localhost/Registration/Add/1
Works, while calling
http://localhost/Registration/Add?eventId=1
No longer works and responds with 404 NotFound
Should work if you make the {eventId} template parameter optional in the route template
[RoutePrefix("Registration")]
public class RegistrationController : Controller {
//GET Registration/Add/1
//GET Registration/Add?eventId=1
[HttpGet]
[Route("Add/{eventId:int?}")]
public ActionResult Add(int eventId) {
//...
}
}
The reason the two were not working is that the route template Add/{eventId} means that the route will only match if the {eventId} is present, which is why
http://localhost/Registration/Add/1
works.
By making it (eventId) optional eventid? it will allow
http://localhost/Registration/Add
to work as the template parameter is not required. This will now allow query string ?eventId=1 to be used, which the routing table will use to match the int eventId parameter argument on the action.
http://localhost/Registration/Add?eventId=1
I also got this issue. Which MVC version are you using?
I faced this issue with MVC in asp.net core.
I think this is a flaw as if you provide Routing attribute on any action method, its conventional route is over ridden and is not longer available so you get 404 error.
For this to work, you can provide another Route attribute to your action method like this. This will work
[Route("Add/{eventId}")]
[Route("Add")]

MVC RouteConfig routes one path to Controller but not another

I have two routes mapped in my RouteConfig:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Content",
url: "Content/{item}.css",
defaults: new
{
controller = "Content",
action = "GetContent"
}
);
routes.MapRoute(
name: "Reports",
url: "SubFolder/App/Views/OtherFolder/Reports/{report}.html",
defaults: new
{
controller = "Reports",
action = "GetReport"
}
);
}
For a URL like
http://example.com/SubFolder/App/Views/OtherFolder/Reports/someReport.html
The 2nd Route correctly fires off the GetReport method in ReportsController:
public ActionResult GetReport(string report) { .... }
But for a URL like
http://example.com/Content/app.css
I would expect the 1st Route to fire off the GetContent method in ContentController:
public ActionResult GetContent(string item) { ... }
but it does not. Any ideas how I can get this routed properly? Ideally I'd like any GET request for anything under the Content folder to be routed to ContentController, but I'm just starting with css files directly in that folder.
I'm on IIS 8.0, MVC 4.0, and using VS2012 if that makes a difference.
By default, MVC does not route static files and just tries to serve a static .css file under the requested path.
Just remove the .css ending and the route will be used.
Edit: To be clearer the IIS tries to serve these static files before the MVC routehandling even comes into play.

How to define routes in more than one location?

Is it possible to define routes in various parts of a website.
Example, if I wanted to break functionality of my website out into modules, and each module would define the routes it needs.
Is this possible? How?
Consider using ASP.NET MVC's built-in Areas.
An "Area" is essentially your module, and Areas allow you to register routes for each specific area.
If you've not used them before there is an MSDN walkthrough here:
http://msdn.microsoft.com/en-us/library/ee671793.aspx
Essentially, you have a directory for each area, which contains all your area-specific controllers and views, and in the route of that directory you place a file that registers the routes for that particular area like so:
public class MyAreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return "My Area"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"news-articles",
"my-area/articles/after/{date}",
new {controller = "MyAreaArticles", action = "After"}
);
// And so on ...
}
}
In global.asax.cs you need to register all these extra areas, along with your other primary routes:
public static void RegisterRoutes(RouteCollection routes)
{
AreaRegistration.RegisterAllAreas();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Products",
"products/show/{name}",
new {controller = "Products", action = "Show", name = UrlParameter.Optional}
);
...
}
You can put a DefineRoutes(RouteCollection routes) method in each module, then call them all in Global.asax.cs.

Categories

Resources