Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从MVC5管线模板中提取管线参数_C#_Asp.net Mvc 5_Asp.net Mvc Routing - Fatal编程技术网

C# 从MVC5管线模板中提取管线参数

C# 从MVC5管线模板中提取管线参数,c#,asp.net-mvc-5,asp.net-mvc-routing,C#,Asp.net Mvc 5,Asp.net Mvc Routing,我的项目使用以下代码为给定的routeName和routeValue生成MVC路由URL: public class RouteBuilder { public string GetUrl(string routeName, object routeValues) { return RouteTable.Routes.GetVirtualPath( new RequestContext(new MockHttpContextBase(str

我的项目使用以下代码为给定的
routeName
routeValue
生成MVC路由URL:

public class RouteBuilder
{
    public string GetUrl(string routeName, object routeValues)
    {
        return RouteTable.Routes.GetVirtualPath(
            new RequestContext(new MockHttpContextBase(string.Empty), new RouteData()),
            routeName,
            new RouteValueDictionary(routeValues)
        )?.VirtualPath;
    }
}
例如,给定以下管线定义:

public MyController : Controller
{
    [Route("Foo", "{bar}/{quux}")]
    public IActionResult MyControllerMethod(MyModel model) {  }
}
我们呼吁:

// yields "zod/baz"
var routedUrl = RouteBuilder.GetUrl("Foo", new
{
    bar = "zod",
    quux = "baz",
});
传递到
GetUrl
的route values对象出现了问题。出于必要,它可以是任何类型的对象,包括示例中演示的匿名对象。但这是有问题的,因为如果对象的定义中存在任何打字错误,则路由模板将不匹配,并且不会生成URL:

// yields null!
var routedUrl = RouteBuilder.GetUrl("Foo", new
{
    baz = "zod", // oops, typo in 1st param name!
    quux = "baz",
});
这是一个更大的问题,因为它只能在运行时捕获

一个潜在的解决方案是:

public class MyControllerMethodRouteParameters
{
    string bar { get; set; }
    string quux { get; set; }
}

public MyController : Controller
{
    [Route("Foo", "{" + nameof(MyControllerMethodRouteParameters.bar) + "}/{" + nameof(MyControllerMethodRouteParameters.quux ) + "}")]
    public IActionResult MyControllerMethod(MyModel model) {  }
}

public class RouteBuilder
{
    private string GetUrl(string routeName, object routeValues) { /* as before */ }

    public string GetUrl(MyControllerMethodRouteParameters params)
    {
        return GetUrl(GetRouteNameFor(params.GetType(), params));
    }
}
但是它在开发人员的努力方面有一个很大的缺点:当添加一个新的控制器方法时,您还必须记住为它添加一个路由参数类、一个
GetUrl
重载以及一个routename=>route parameters类型映射。很容易忘记,而且感觉像是不必要的重复,因为所有必要的参数及其类型都已在
RouteAttribute
中定义

因此,我的想法是通过T4模板生成所需的代码,方法是对程序集进行反思,获取所有
RouteAttribute
s并从中提取路由名称和模板,然后解析模板以获取路由参数类的属性名称。这是我遇到的最后一个障碍,因为虽然我知道我可能可以编写一个正则表达式来匹配并从模板中提取路由参数,但我更愿意使用现有的功能来实现这一点


问题是,我找不到任何对我有帮助的东西。最接近的似乎是内部类
System.Web.Mvc.Routing.InlineRouteTemplateParser
,但我的实验并没有特别有成效。有什么我可以或应该用来实现这一点,或者我应该向黑暗的正则表达式之神屈服吗?

我认为你无法解释/编码开发人员的拼写错误;当然,在您的入住登记上运行的测试证实了这些问题。我只是想弄明白你想要达到的目标是否真的有必要?我的意思是,如果对象的定义中有任何拼写错误,那么我会期望开发人员编写一个测试来检查这一点,假设TDD开发方法已经到位?这看起来很混乱。我不能把我的手指放在上面,但有些东西不适合我。我认为查询字符串是字符串,而不是对象。在编辑T4模板之前,我会再次检查您是否不能使用方法名和特定路由表,因为我有另一个想法,即使用通用ToString方法,不幸的是使用反射&您可能会强制正确解析字典名称/值对,查看此项目:@JeremyThompson不确定您为什么在这里谈论查询字符串,因为它们不是路由的一部分?我想帮助您,这个问题在我脑海中,现在是凌晨1点。有什么额外的信息吗?