Dimitry 的解决方案使我大部分时间都到达了我想要的位置,但是 routeName ctor 参数是一个问题,因为 StructureMap 不知道该放什么。内部 hyprlink 使用 UrlHelper 生成 URI,并且想知道要使用的路由名称
到那时,我明白为什么 URI 生成如此棘手,因为它与路由配置中的路由名称相关联,并且为了支持 POST,我们需要将方法与正确的路由名称相关联,而这在调度程序中是未知的时间。默认 hyprlinkr 假定只有一个名为“DefaultRoute”的路由配置
我将 Dimitry 的代码更改如下,并采用了基于约定的方法,其中以“Get”开头的控制器方法映射到名为“Get”的路由,而以“Add”开头的控制器方法映射到名为“Add”的路由。
我想知道是否有更好的方法将方法与正确命名的 routeConfig 相关联?
public class RemoveFromBodyParamsRouteDispatcher : IRouteDispatcher
{
private static readonly ILog _log = LogManager.GetLogger(typeof (RemoveFromBodyParamsRouteDispatcher));
public Rouple Dispatch(MethodCallExpression method,
IDictionary<string, object> routeValues)
{
var methodName = method.Method.Name;
DefaultRouteDispatcher defaultDispatcher;
if (methodName.StartsWith("Get"))
defaultDispatcher = new DefaultRouteDispatcher("Get");
else if (methodName.StartsWith("Add"))
defaultDispatcher = new DefaultRouteDispatcher("Add");
else
throw new Exception("Unable to determine correct route name for method with name " + methodName);
_log.Debug("Dispatch methodName=" + methodName);
//make a copy of routeValues as contract says we should not modify
var routeValuesWithoutFromBody = new Dictionary<string, object>(routeValues);
var routeKeysToRemove = new HashSet<string>();
foreach (var paramName in routeValuesWithoutFromBody.Keys)
{
var parameter = method.Method
.GetParameters()
.FirstOrDefault(p => p.Name == paramName);
if (parameter != null)
if (IsFromBodyParameter(parameter))
{
_log.Debug("Dispatch: Removing paramName=" + paramName);
routeKeysToRemove.Add(paramName);
}
}
foreach (var routeKeyToRemove in routeKeysToRemove)
routeValuesWithoutFromBody.Remove(routeKeyToRemove);
return defaultDispatcher.Dispatch(method, routeValuesWithoutFromBody);
}
private static bool IsFromBodyParameter(ParameterInfo parameter)
{
//Apparently the "inherit" argument is ignored: http://msdn.microsoft.com/en-us/library/cwtf69s6(v=vs.100).aspx
const bool msdnSaysThisArgumentIsIgnored = true;
var attributes = parameter.GetCustomAttributes(msdnSaysThisArgumentIsIgnored);
return attributes.Any(ct => ct is FromBodyAttribute);
}
}