ASP .NET MVC, раутинг

Разработка на C# для Gentoo,
 
Why do we need Routing anyways?
Because the web server knows nothing about your code. It knows how to map URLs to files, but not to controllers.
solution is having a tool that can deeply understand your code. In one word, Reflection.

Why Routing?

SEO friendly

RESTfully configured routing facilitates the Search Engine Optimization (SEO) of your content. A site’s URL is one of the top criteria that impacts site ranking. By converting www.yourwebsite.com/articles/show/123 to www.yourwebsite.com/how-to-peel-potatoes you encourage search engines to rank it higher for keyphrases related to “how to peel potatoes.”
Also, when you have a URL that is more descriptive, it is easier for users to correctly anticipate the content, leading to increased time on page, which also impacts SEO and your overall page authority.

URLs do not need to map a file

Without routing, an incoming request would be mapped to a physical file. With routing we have full control of the request, allowing us to decide what action and controller we execute when a certain HTTP request comes in.

Long URLs and file extensions can be eliminated

Routing helps to shorten the URL in instances where many parameters and filters are in play. By eliminating the file extension, we can hide what kind of environment we are working in.
https://stormpath.com/blog/routing-in-asp-net-core
2008-08-19, Stephen Walther, ASP.NET MVC Routing Overview
    Здесь просто вкратце описывается, какая была задумка по основному сценарию использования
Но нехватает следующих вещей:
1) что и зачем написано в web-config
2) как разбираются формулы в составе шаблона route (ну, которые с фигурными скобочками {} )
3) как определяется какой controller и какой action будут вызваны, если эти слова не встречаются в шаблоне формулы (например если там чётко путь указан, то какой метод будет вызван?)

https://msdn.microsoft.com/en-us/library/cc668201.aspx
    Здесь много чего написано.

ASP.NET MVC framework maps browser requests to controller actions.

https://maxtoroq.github.io/2014/02/why-aspnet-mvc-routing-sucks.html

Once you start using custom routes the convention over configuration principle is dead.

There are visual tools like Route Debugger and Glimpse.
http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx/
http://getglimpse.com/

Convention Routing (vs Attribute Routing)

MVC 1
Routing is the ability to have URLs represent abstract actions rather than concrete, physical files.

AreaRegistration

https://habrahabr.ru/post/74061/
Появилась начиная с MVC2
Метод RegisterAllAreas обнаруживает в домене приложения все типы, производные от AreaRegistration, и вызывает их методы RegisterArea.
public static void RegisterAllAreas()

{area}/{controller}/{action}/{id}
MVC 2 introduced a feature called Areas. This is not only about having an additional level in your resource hierarchy, it also attempts to provide a better organization of your codebase.
Although there are documented ways to split areas into their own projects, it’s not the default behavior.

в MVC 5 писать можно в атрибуте:
[RouteArea(“BackOffice”, AreaPrefix = “back-office”)]

Areas doesn’t really help you design a deep resource hierarchy, or organize your codebase in a clean way. In my view, code is and should be organized using namespaces and projects, not some artificial concept that doesn’t really help. In respect to routing, areas is just the default route with an additional segment. Areas only help you in two ways:

Dynamic Data applications.

MVC3
https://msdn.microsoft.com/en-us/library/cc488545.aspx

Attribute Routing

MVC 5

[RoutePrefix("Users")]
public class HomeController : Controller  
{
    [Route("~/")] //Specifies that this is the default action for the entire application. Route: /
    [Route("")] //Specifies that this is the default action for this route prefix. Route: /Users
    public ActionResult Index() { ... }
} 

Until now, there has been a routing table that you can define either in the Global.asax or in the RouteConfig.cs and all incoming requests would look it up to decide the rendering of a target view.
http://www.davidhayden.me/blog/asp-net-mvc-5-attribute-routing
http://www.c-sharpcorner.com/UploadFile/bhushangawale/attribute-based-routing-in-Asp-Net-mvc-5/

to turn on attribute based routing in ASP.NET MVC 5 when you register your routes in RouteConfig. It is a simple one line statement.
public static void RegisterRoutes(RouteCollection routes) {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

tes.MapMvcAttributeRoutes(); //Enables Attribute Based Routing  
  
    routes.MapRoute(  
        name: "Default",  
        url: "{controller}/{action}/{id}",  
        defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }  
    );  
}
The joy here is that it is easy to see the route to a controller action by looking at the RoutePrefix and Route Attributes on the controller and action. You don't have to find it somewhere else.
When the route definitions are co-located with the actions, within the same source file rather than being declared on an external configuration class, it can make it easier to reason about the mapping between URIs and actions.
This makes it really convenient for troubleshooting routes.

This works with ASP.NET Web API 2.

there was nothing really wrong with the previous approach of routing and in fact you can still use it in MVC 5 or use this new routing method in conjunction with the old one.

Here are a few advantages of attribute based routing: Use a tilde (~) on the method attribute to override the route prefix if needed

https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/ The following table lists the constraints that are supported.  
Constraint Description Example
alpha Matches uppercase or lowercase Latin alphabet characters (a-z, A-Z) {x:alpha}
bool Matches a Boolean value. {x:bool}
datetime Matches a DateTime value. {x:datetime}
decimal Matches a decimal value. {x:decimal}
double Matches a 64-bit floating-point value. {x:double}
float Matches a 32-bit floating-point value. {x:float}
guid Matches a GUID value. {x:guid}
int Matches a 32-bit integer value. {x:int}
length Matches a string with the specified length or within a specified range of lengths. {x:length(6)}
{x:length(1,20)}
long Matches a 64-bit integer value. {x:long}
max Matches an integer with a maximum value. {x:max(10)}
maxlength Matches a string with a maximum length. {x:maxlength(10)}
min Matches an integer with a minimum value. {x:min(10)}
minlength Matches a string with a minimum length. {x:minlength(10)}
range Matches an integer within a range of values. {x:range(10,50)}
regex Matches a regular expression. {x:regex(^\d{3}-\d{3}-\d{4}$)}
Notice that some of the constraints, such as “min”, take arguments in parentheses.
You can apply multiple constraints to a parameter, separated by a colon

Значения по умолчанию в маршруте

Такая возможность появилась в ASP.NET MVC 5
  1. Возможность задавать прямо в нем значения по-умолчанию для переменных частей маршрута: {controller=Home}/{action=Index}.
  2. Задавать не обязательность переменной части сегмента с помощью символа ?: {controller=Home}/{action=Index}/{id?}.


https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/#default-route
given the following code:
[RoutePrefix("reviews")]
public class ReviewsController : Controller {

   // eg.: /reviews/5
   [Route("{reviewId:int}")]
   public ActionResult Show(int reviewId) { ... }

   // eg.: /reviews/5/edit
   [Route("{reviewId:int}/{action}")]
   public ActionResult Edit(int reviewId) { ... }
}
Why do I need to specify “reviews” in the route prefix, if I could just take that information from the controller name? Same with parameter name and constraint. Update: Can use {controller} instead, but cannot avoid repeating the parameter name and type.
https://weblogs.asp.net/leftslipper/optimizing-your-route-collection-for-url-generation-in-asp-net-mvc-and-more

http://maxtoroq.github.io/2013/02/aspnet-mvc-workflow-per-controller.html
Separating classes by category (Controllers, ViewModels, Filters etc.) is nonsense.If you want to write code for the Home section of your website (/) then create a folder named Home, and put there the HomeController, IndexViewModel, AboutViewModel, etc. and all related classes used by Home actions.
Why separate things that are related (HomeController, IndexViewModel) and keep things together that have no relation at all (HomeController, AccountController) ?
Categorization of information is useful if there’s value in looking at all information of a certain category at once.
I think a controller should implement a single workflow, and that workflow should have its own namespace.
Let’s take MvcAccount for example. There’s a Reset Password function comprised of several actions:
  1. GET /Account/ResetPassword
  2. POST /Account/ResetPassword
  3. GET /Account/PasswordResetVerificationSent
  4. GET /Account/RP (by clicking on e-mail link)
  5. POST /Account/RP
  6. GET /Account/PasswordReset
To successfully reset a password you have go through this sequence of actions from start to finish. This is the Reset Password workflow, and should be represented in code by its own controller.

http://www.make-awesome.com/2012/07/perfectionist-routing-in-asp-net-mvc/

Subdomain routing

http://matrichard.com/post/asp.net-mvc-5-routing-with-subdomain

Web API

http://odetocode.com/blogs/scott/archive/2013/08/12/attribute-routes-and-hierarchical-routing.aspx

Все маршруты в одном месте

http://odetocode.com/blogs/scott/archive/2013/08/12/attribute-routes-and-hierarchical-routing.aspx
Routing in web API and mvc was crap because its order dependent. Because a single route is magic for all calls. This isn't the case with AR.

Как в linux традиционно решают такие вопросы?
Делают директорию, в которую размещают текстовые фрагменты конфигурационных файлов, каждый из которых содержит отдельный элемент. Симлинки возможны, группировка по сценариям использования.
Ну можно вместо директории использовать XML-файл (описание маршрута -> сборка, тип, метод)

IDependencyResolver

Improved Dependency Injection with new IDependencyResolver.

XML-based routing

2010-01-17, Phil Haack, Editable Routes
2011-02-13, Phil Haack, Introducing RouteMagic
    https://github.com/haacked/routemagic

2012-10-14, Vijaya Anand, Building XML based routing system using XRouter
    https://github.com/bbqchickenrobot/XRouter

Я по этому поводу думаю, что можно было бы сделать директорию, в которую складывать такие XML-файлы, при старте их считывать, а при обновлении перечитывать.

2015-11-13, Rick Strahl, Serving URLs with File Extensions in an ASP.NET MVC Application

https://mvccoderouting.codeplex.com/
    https://github.com/maxtoroq/MvcCodeRouting

Site maps

http://stackoverflow.com/questions/2006529/mvc-how-to-route-sitemap-xml-to-an-actionresult

XML config can be transformed into site map (if it will support such feature)
http://rehansaeed.com/dynamically-generating-sitemap-xml-for-asp-net-mvc/
http://joelabrahamsson.com/xml-sitemap-with-aspnet-mvc/

Globalization/Localization

Why URI parts are not passed into methods as parameters?

Routing by file extension

https://weblog.west-wind.com/posts/2015/nov/13/serving-urls-with-file-extensions-in-an-aspnet-mvc-application

Typical problems

http://rdingwall.com/2008/08/09/three-common-aspnet-mvc-url-routing-issues/

Нужна какая-то утилита, которая бы проверяла корректность маршрутов и их соответствие коду.

Не только название сайта, но и QueryString

http://rsdn.org/forum/dotnet.web/4128644.flat#4128644