Reputation: 369
In .NET 4.5 if I added anything to the RouteValueDictionary in RouteData.Values I could resolve this in the controller by adding it as an in-parameter for the controller but this doesn't seem to work in .NET Core.
This is my IRouter's RouteAsync method:
public async Task RouteAsync(RouteContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
var model = GetMyModel();
if (model == null)
{
await _target.RouteAsync(context);
return;
}
context.RouteData.Values["mymodel"] = model;
var routeValues = new RouteValueDictionary
{
{"controller", pageController.Name.Replace("Controller", string.Empty)},
{"action", "Index"},
{"mymodel", model }
};
var tokenValues = new RouteValueDictionary
{
{"mymodel", model }
};
// Set our values to the route data.
// Don't do it when creating the snapshot as we'd like them to be there after the restore as well.
foreach (var tokenValueKey in tokenValues.Keys)
{
context.RouteData.DataTokens[tokenValueKey] = tokenValues[tokenValueKey];
}
foreach (var routeValueKey in routeValues.Keys)
{
context.RouteData.Values[routeValueKey] = routeValues[routeValueKey];
}
// This takes a snapshot of the route data before it is routed again
var routeDataSnapshot = context.RouteData.PushState(_target, routeValues, tokenValues);
try
{
await _target.RouteAsync(context);
}
finally
{
// Restore snapshot
routeDataSnapshot.Restore();
}
}
After this, my controller is in fact called but the parameter mymodel is just a default value, not the value I set in the router. If I look at the RouteData.Values the key "mymodel" is there and has a value. Why isn't the in-parameter also set to this? Do I need to add some middleware for model binding?
public IActionResult Index(MyModelClass mymodel)
{
return View();
}
Upvotes: 3
Views: 2620
Reputation: 629
RouteData
is accessible through the controller instance as a property.
public class SomeControllerController : Controller {
public IActionResult Index() {
if (base.RouteData.Values.ContainsKey("mymodel") == false) {
return NotFound();
}
MyModel model = (MyModel) base.RouteData.Values["mymodel"];
//LOGIC...
return Index(model);
}
}
For a cleaner imlementation you could create an abstract controller to do this.
ref: https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.routedata(v=vs.118).aspx
Upvotes: 4