使用 ASP.NET MVC 路由之类的路由解析为对象
Parse to object with a route like ASP.NET MVC routing
在 ASP.NET MVC 中可以这样定义路由:
routes.MapRoute("myroute",
"myroute/{country}/{name}-{type}",
new { controller = "MyController", action = "Get" });
然后将其直接解析为一个对象:
public class MyController : Controller
{
public HttpResponseMessage Get([FromRoute] MyViewModel model)
{
//TODO do stuff with model.
}
}
这是我的视图模型:
public class MyViewModel
{
public string Name { get; set; }
public string Type{ get; set; }
}
我的问题是,我可以在一个简单的控制台应用程序中进行相同的解析吗?
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; }
}
一定有某种方法可以做到这一点,因为 ASP.NET MVC 路由是可能的。
使用 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);
}
}
country: Denmark
type: MyType
name: MyName
但是,将其绑定到一个实体将意味着您将拥有整个 model binding 堆栈,这恰好“有点”更复杂,无法单独启动。因此,我只建议您使用一点反射手动进行此操作:
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;
}
并像这样使用:
var obj = BindValues<MyViewModel>(values);
虽然这显然不如模型绑定强大,但它应该足以满足您的用例。
在 ASP.NET MVC 中可以这样定义路由:
routes.MapRoute("myroute",
"myroute/{country}/{name}-{type}",
new { controller = "MyController", action = "Get" });
然后将其直接解析为一个对象:
public class MyController : Controller
{
public HttpResponseMessage Get([FromRoute] MyViewModel model)
{
//TODO do stuff with model.
}
}
这是我的视图模型:
public class MyViewModel
{
public string Name { get; set; }
public string Type{ get; set; }
}
我的问题是,我可以在一个简单的控制台应用程序中进行相同的解析吗?
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; }
}
一定有某种方法可以做到这一点,因为 ASP.NET MVC 路由是可能的。
使用 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);
}
}
country: Denmark
type: MyType
name: MyName
但是,将其绑定到一个实体将意味着您将拥有整个 model binding 堆栈,这恰好“有点”更复杂,无法单独启动。因此,我只建议您使用一点反射手动进行此操作:
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;
}
并像这样使用:
var obj = BindValues<MyViewModel>(values);
虽然这显然不如模型绑定强大,但它应该足以满足您的用例。