In ASP.NET MVC it's possible to define a route like this:
routes.MapRoute("myroute",
"myroute/{country}/{name}-{type}",
new { controller = "MyController", action = "Get" });
And that would parse it directly to an object:
public class MyController : Controller
{
public HttpResponseMessage Get([FromRoute] MyViewModel model)
{
//TODO do stuff with model.
}
}
This is my view model:
public class MyViewModel
{
public string Name { get; set; }
public string Type{ get; set; }
}
My question is, can I do the same parsing in a simple console app?
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; }
}
There must be some way of doing this, since it's possible for ASP.NET MVC routing.
Parsing and applying the route template is actually pretty simple using 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
However, binding that to an entity would mean that you will have the whole model binding stack which happens to be a “bit” more complex to spin up separately. So instead, I would just recommend you to make this manually using a little bit of reflection:
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;
}
And used like this:
var obj = BindValues<MyViewModel>(values);
While this is obviously a lot less powerful than model binding, it should work fine enough for your use case.