【问题标题】:Parse to object with a route like ASP.NET MVC routing使用 ASP.NET MVC 路由之类的路由解析到对象
【发布时间】:2019-03-15 03:10:05
【问题描述】:

在 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 路由。

【问题讨论】:

  • 肯定有办法做到这一点,写一些代码来解析你的值并用PropertyInfo设置它们,试一试,有很多东西,从正则表达式开始或拆分
  • 不知道有没有内置方式。我很想将路由转换为正则表达式(您可以自动执行此操作),然后您可以针对生成的正则表达式测试“url”。如果您使用{ } 中的名称来命名您的正则表达式组,您还可以轻松提取数据。
  • 不打算使用拆分,这样就无法将路由更改为其他内容。
  • 一些正则表达式可能会起作用,只是不确定如何解析为一个对象。并且当它可以用于 asp.net mvc rounting 时,它必须可以用一个简单的字符串来做同样的事情。
  • 让我们看看是否有人可以做出更好的解决方案,但这是一个开始:)

标签: c# asp.net-mvc asp.net-core .net-core asp.net-mvc-routing


【解决方案1】:

使用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);

虽然这显然不如模型绑定强大,但它应该足以满足您的用例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-14
    • 1970-01-01
    • 2020-04-04
    • 2014-09-11
    • 1970-01-01
    • 2010-10-07
    • 2023-04-03
    • 2015-04-06
    相关资源
    最近更新 更多