![tc3.0内联汇编](https://i-blog.csdnimg.cn/blog_migrate/1e40f9895a057d02a98080284c7b061c.png)
tc3.0内联汇编
ASP.NET supports both attribute routing as well as centralized routes. That means that you can decorate your Controller Methods with your routes if you like, or you can map routes all in one place.
ASP.NET支持属性路由和集中式路由。 这意味着您可以根据需要用路由装饰控制器方法,也可以将所有路由映射到一个地方。
Here's an attribute route as an example:
下面以属性路由为例:
[Route("home/about")]
public IActionResult About()
{
//..
}
And here's one that is centralized. This might be in Startup.cs or wherever you collect your routes. Yes, there are better examples, but you get the idea. You can read about the fundamentals of ASP.NET Core Routing in the docs.
这是集中式的。 这可能在Startup.cs中或收集路线的任何地方。 是的,有更好的例子,但是您明白了。 您可以在文档中阅读有关ASP.NET Core Routing的基础知识。
routes.MapRoute("about", "home/about",
new { controller = "Home", action = "About" });
A really nice feature of routing in ASP.NET Core is inline route constraints. Useful URLs contain more than just paths, they have identifiers, parameters, etc. As with all user input you want to limit or constrain those inputs. You want to catch any bad input as early on as possible. Ideally the route won't even "fire" if the URL doesn't match.
内联路由约束是ASP.NET Core中路由的一个非常好的功能。 有用的URL不仅包含路径,还包含标识符,参数等。与所有用户输入一样,您希望限制或约束这些输入。 您想尽早发现任何不良输入。 理想情况下,如果URL不匹配,则路由甚至不会“触发”。
For example, you can create a route like
例如,您可以创建一条路线,例如
files/{filename}.{ext?}
This route matches a filename or an optional extension.
该路由与文件名或可选扩展名匹配。
Perhaps you want a dateTime in the URL, you can make a route like:
也许您想在URL中使用dateTime,您可以进行如下路由:
person/{dob:datetime}
Or perhaps a Regular Expression for a Social Security Number like this (although it's stupid to put a SSN in the URL ;) ):
或像这样的社会安全号码正则表达式(尽管在URL中放入SSN是很愚蠢的;)):
user/{ssn:regex(d{3}-d{2}-d{4})}
There is a whole table of constraint names you can use to very easily limit your routes. Constraints are more than just types like dateTime or int, you can also do min(value) or range(min, max).
您可以使用整个约束名称表轻松地限制路线。 约束不仅仅是诸如dateTime或int之类的类型,您还可以执行min(value)或range(min,max)。
However, the real power and convenience happens with Custom Inline Route Constraints. You can define your own, name them, and reuse them.
但是,真正的功能和便利性发生在“自定义串联路由约束”中。 您可以定义自己的名称,为它们命名并重复使用。
Lets say my application has some custom identifier scheme with IDs like:
可以说我的应用程序有一些ID的自定义标识符方案,例如:
/product/abc123
/ product / abc123
/product/xyz456
/产品/ xyz456
Here we see three alphanumerics and three numbers. We could create a route like this using a regular expression, of course, or we could create a new class called CustomIdRouteConstraint that encapsulates this logic. Maybe the logic needs to be more complex than a RegEx. Your class can do whatever it needs to.
在这里,我们看到三个字母数字和三个数字。 当然,我们可以使用正则表达式创建这样的路由,也可以创建一个名为CustomIdRouteConstraint的新类来封装此逻辑。 也许逻辑需要比RegEx更复杂。 您的班级可以做任何需要做的事情。
Because ASP.NET Core is open source, you can read the code for all the included ASP.NET Core Route Constraints on GitHub. Marius Schultz has a great blog post on inline route constraints as well.
由于ASP.NET Core是开源的,因此您可以在GitHub上阅读所有包含的ASP.NET Core路由约束的代码。 Marius Schultz在在线路线约束方面也有出色的博客文章。
Here's how you'd make a quick and easy {customid} constraint and register it. I'm doing the easiest thing by deriving from RegexRouteConstraint, but again, I could choose another base class if I wanted, or do the matching manually.
您将按照以下方法制作快速简便的{customid}约束并进行注册。 我正在通过从RegexRouteConstraint派生来做最简单的事情,但是同样,如果愿意,我可以选择另一个基类,或者手动进行匹配。
namespace WebApplicationBasic
{
public class CustomIdRouteConstraint : RegexRouteConstraint
{
public CustomIdRouteConstraint() : base(@"([A-Za-z]{3})([0-9]{3})$")
{
}
}
}
In your ConfigureServices in your Startup.cs you just configure the route options and map a string like "customid" with your new type like CustomIdRouteConstraint.
在Startup.cs的ConfigureServices中,您只需配置路由选项并使用新类型(如CustomIdRouteConstraint)映射一个字符串(如“ customid”)。
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.Configure<RouteOptions>(options =>
options.ConstraintMap.Add("customid", typeof(CustomIdRouteConstraint)));
}
Once that's done, my app knows about "customid" so I can use it in my Controllers in an inline route like this:
一旦完成,我的应用程序就会知道“ customid”,因此我可以在控制器中以内联方式使用它,如下所示:
[Route("home/about/{id:customid}")]
public IActionResult About(string customid)
{
// ...
return View();
}
If I request /Home/About/abc123 it matches and I get a page. If I tried /Home/About/999asd I would get a 404! This is ideal because it compartmentalizes the validation. The controller doesn't need to sweat it. If you create an effective route with an effective constraint you can rest assured that the Controller Action method will never get called unless the route matches.
如果我请求/ Home / About / abc123,则它匹配并且得到页面。 如果我尝试/ Home / About / 999asd,我会得到404! 这是理想的,因为它可以分隔验证。 控制器不需要费力。 如果您创建具有有效约束的有效路由,则可以放心,除非路由匹配,否则将不会调用Controller Action方法。
![If the route doesn't fire it's a 404 If the route doesn't fire it's a 404](https://i-blog.csdnimg.cn/blog_migrate/c72f076707a1356ef07bf86f02767095.png)
单元测试自定义串联路由约束 (Unit Testing Custom Inline Route Constraints)
You can unit test your custom inline route constraints as well. Again, take a look at the source code for how ASP.NET Core tests its own constraints. There is a class called ConstrainsTestHelper that you can borrow/steal.
您也可以对自定义内联路由约束进行单元测试。 再次查看一下ASP.NET Core如何测试其自身约束的源代码。 您可以借用/窃取一个名为ConstrainsTestHelper的类。
I make a separate project and setup xUnit and the xUnit runner so I can call "dotnet test."
我创建了一个单独的项目,并设置了xUnit和xUnit运行器,以便可以将其称为“ dotnet测试”。
Here's my tests that include all my "Theory" attributes as I test multiple things using xUnit with a single test. Note we're using Moq to mock the HttpContext.
这是我的测试,其中包括我所有的“理论”属性,因为我使用xUnit一次测试多个项目。 请注意,我们使用Moq来模拟HttpContext。
public class TestProgram
{
[Theory]
[InlineData("abc123", true)]
[InlineData("xyz456", true)]
[InlineData("abcdef", false)]
[InlineData("totallywontwork", false)]
[InlineData("123456", false)]
[InlineData("abc1234", false)]
public void TestMyCustomIDRoute(
string parameterValue,
bool expected)
{
// Arrange
var constraint = new CustomIdRouteConstraint();
// Act
var actual = ConstraintsTestHelper.TestConstraint(constraint, parameterValue);
// Assert
Assert.Equal(expected, actual);
}
}
public class ConstraintsTestHelper
{
public static bool TestConstraint(IRouteConstraint constraint, object value,
Action<IRouter> routeConfig = null)
{
var context = new Mock<HttpContext>();
var route = new RouteCollection();
if (routeConfig != null)
{
routeConfig(route);
}
var parameterName = "fake";
var values = new RouteValueDictionary() { { parameterName, value } };
var routeDirection = RouteDirection.IncomingRequest;
return constraint.Match(context.Object, route, parameterName, values, routeDirection);
}
}
Now note the output as I run "dotnet test". One test with six results. Now I'm successfully testing my custom inline route constraint, as a unit. in isolation.
现在,在运行“ dotnet测试”时记下输出。 一项测试有六项结果。 现在,我已经成功地测试了自定义内联路线约束,作为一个单元。 隔离中。
xUnit.net .NET CLI test runner (64-bit .NET Core win10-x64)
Discovering: CustomIdRouteConstraint.Test
Discovered: CustomIdRouteConstraint.Test
Starting: CustomIdRouteConstraint.Test
Finished: CustomIdRouteConstraint.Test
=== TEST EXECUTION SUMMARY ===
CustomIdRouteConstraint.Test Total: 6, Errors: 0, Failed: 0, Skipped: 0, Time: 0.328s
Lots of fun!
很有意思!
Sponsor: Working with DOC, XLS, PDF or other business files in your applications? Aspose.Total Product Family contains robust APIs that give you everything you need to create, manipulate and convert business files along with many other formats in your applications. Stop struggling with multiple vendors and get everything you need in one place with Aspose.Total Product Family. Start a free trial today.
赞助者:在您的应用程序中使用DOC,XLS,PDF或其他业务文件? Aspose.Total产品家族包含强大的API,可为您提供创建,处理和转换业务文件以及应用程序中许多其他格式所需的一切。 停止与多个供应商进行斗争,并通过Aspose.Total产品系列将所需的一切集中在一个地方。 立即开始免费试用。
翻译自: https://www.hanselman.com/blog/adding-a-custom-inline-route-constraint-in-aspnet-core-10
tc3.0内联汇编