I've made a function which takes a MethodBase object and a dictionary of named parameters and matches the named parameters to the method and converts the data so that the method can be called with the correct parameters.
In order to convert the data I've been using
parameters[paramIndex] = Convert.ChangeType(item.Value, paramType);
However this will not work for MVC bound types as simply invoking a MethodBase object doesn't perform the data conversion via MVC bindings.
I can check whether the type to be converted has a binder by doing
if(ModelBinders.Binders.TryGetValue(paramType, out var binder)){...}
However I'm not sure then how to use the binder to convert the data. I've tried using this answer but there's no explanation of what the ModelBindingContext
parameters actually are and how to use them for these purposes.
Context
Thought it might be wise to provide some context: I'm trying to do this as we perform server-side rendering of SVG and HTML DOMs (using Puppeteer/batik) but some of the DOMs have embedded images with links in them.
So before performing the render:
- Find image URLs from DOM
- Parsing the parameters and route out
- Find the method to call in assembly via it's MVC route attribute
- Call the method with the converted parameters to render the image
- Convert the result to base64
- Change the embedded image in DOM to use the base64 representation rather than a URL
Thanks in advance for your help.
The entire method definition is:
private static object[] MapParameters(MethodBase method, IDictionary<string, object> namedParameters)
{
var parms = method.GetParameters();
var paramNames = parms.Select(p => p.Name).ToArray();
var parameters = new object[paramNames.Length];
for (var i = 0; i < parameters.Length; ++i)
parameters[i] = Type.Missing;
foreach (var item in namedParameters)
{
var param = parms.First(parm => parm.Name == item.Key);
var paramType = Nullable.GetUnderlyingType(param.ParameterType) ?? param.ParameterType;
var paramName = item.Key;
var paramIndex = Array.IndexOf(paramNames, paramName);
if (ModelBinders.Binders.TryGetValue(paramType, out var binder))
{
// Use the binder to convert data
continue;
}
parameters[paramIndex] = Convert.ChangeType(item.Value, paramType);
}
return parameters;
}