使用ASP.NET MVC路由等路由解析对象

And*_*bæk 1 c# asp.net-mvc asp.net-mvc-routing .net-core asp.net-core

在ASP.NET MVC中,可以定义这样的路由:

routes.MapRoute("myroute",
    "myroute/{country}/{name}-{type}",
    new { controller = "MyController", action = "Get" });
Run Code Online (Sandbox Code Playgroud)

这会将它直接解析为一个对象:

public class MyController : Controller
{
   public HttpResponseMessage Get([FromRoute] MyViewModel model)
   {
      //TODO do stuff with model.
   }
}
Run Code Online (Sandbox Code Playgroud)

这是我的视图模型:

public class MyViewModel
{
    public string Name { get; set; }
    public string Type{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,我可以在一个简单的控制台应用程序中进行相同的解析吗?

class Program
{
    static void Main(string[] args)
    {
        string route = "myroute/{country}/{name}-{type}";

        string input = "myroute/Denmark/MyName-MyType";

        //TODO Parse input to MyViewModel with route
        MyViewModel result;
    }
}

public class MyViewModel
{
    public string Name { get; set; }
    public string Type { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

必须有一些方法可以做到这一点,因为它可以用于ASP.NET MVC路由.

pok*_*oke 9

使用以下方法解析和应用路径模板实际上非常简单Microsoft.AspNetCore.Routing:

string route = "/myroute/{country}/{name}-{type}";
string input = "/myroute/Denmark/MyName-MyType";

var routeTemplate = TemplateParser.Parse(route);
var matcher = new TemplateMatcher(routeTemplate, null);
var values = new RouteValueDictionary();

if (matcher.TryMatch(input, values))
{
    foreach (var item in values)
    {
        Console.WriteLine("{0}: {1}", item.Key, item.Value);
    }
}
Run Code Online (Sandbox Code Playgroud)
country: Denmark
type: MyType
name: MyName
Run Code Online (Sandbox Code Playgroud)

但是,将它绑定到实体意味着您将拥有整个模型绑定堆栈,这对于单独启动而言更加复杂.所以相反,我建议你手动使用一点点反射:

public static T BindValues<T>(RouteValueDictionary values)
    where T : new()
{
    var obj = new T();
    foreach (var prop in typeof(T).GetProperties())
    {
        if (values.ContainsKey(prop.Name))
        {
            prop.SetValue(obj, values[prop.Name]);
        }
    }
    return obj;
}
Run Code Online (Sandbox Code Playgroud)

像这样使用:

var obj = BindValues<MyViewModel>(values);
Run Code Online (Sandbox Code Playgroud)

虽然这显然没有模型绑定那么强大,但它应该可以很好地适用于您的用例.