Asp.net mvc 为什么Mvc SiteMapProvider参数区分大小写?

Asp.net mvc 为什么Mvc SiteMapProvider参数区分大小写?,asp.net-mvc,breadcrumbs,mvcsitemapprovider,Asp.net Mvc,Breadcrumbs,Mvcsitemapprovider,目前,我尝试使用mvcsitemprovider.MVC5 4.6.17生成面包屑。当我在路由配置中定义preservedouteparameters=id是的,它是{id}部分时,它工作得很好,但是当我将其更改为preservedouteparameters=id时,url与该节点不匹配 是否有任何原因使其区分大小写?有什么简单的方法可以绕过它吗 背景:在id的情况下,这并不重要,因为用户不能在url中输入文字“id”。但我推出了一种使用querystring参数的方法,但问题是queryst

目前,我尝试使用mvcsitemprovider.MVC5 4.6.17生成面包屑。当我在路由配置中定义preservedouteparameters=id是的,它是{id}部分时,它工作得很好,但是当我将其更改为preservedouteparameters=id时,url与该节点不匹配

是否有任何原因使其区分大小写?有什么简单的方法可以绕过它吗


背景:在id的情况下,这并不重要,因为用户不能在url中输入文字“id”。但我推出了一种使用querystring参数的方法,但问题是querystring值名称必须遵循xml配置中定义的确切大小写,否则它与节点不匹配。

以防有人想知道我是如何解决此问题的

第一件事是通过执行以下操作扩展默认SiteMapNode 2个更改添加到Lower:

public class CustomSiteMapNode : RequestCacheableSiteMapNode
{
    public CustomSiteMapNode(ISiteMap siteMap, string key, bool isDynamic, ISiteMapNodePluginProvider pluginProvider, IMvcContextFactory mvcContextFactory, ISiteMapNodeChildStateFactory siteMapNodeChildStateFactory, ILocalizationService localizationService, IUrlPath urlPath) :
        base(siteMap, key, isDynamic, pluginProvider, mvcContextFactory, siteMapNodeChildStateFactory, localizationService, urlPath)
    {
    }

    protected override void PreserveRouteParameters()
    {
        if (this.PreservedRouteParameters.Count > 0)
        {
            var requestContext = this.mvcContextFactory.CreateRequestContext();
            var routeDataValues = requestContext.RouteData.Values;
            var queryStringValues = requestContext.HttpContext.Request.QueryString;

            foreach (var item in this.PreservedRouteParameters)
            {
                var preservedParameterName = item.Trim().ToLower();
                if (!string.IsNullOrEmpty(preservedParameterName))
                {
                    if (routeDataValues.ContainsKey(preservedParameterName))
                    {
                        this.routeValues[preservedParameterName] =
                            routeDataValues[preservedParameterName];
                    }
                    else if (queryStringValues[preservedParameterName] != null)
                    {
                        this.routeValues[preservedParameterName] =
                            queryStringValues[preservedParameterName];
                    }
                }
            }
        }
    }

    protected override IDictionary<string, object> MergeRouteValuesAndNamedQueryStringValues(IDictionary<string, object> routeValues, ICollection<string> queryStringKeys, HttpContextBase httpContext)
    {
        // Make a copy of the routeValues. We only want to limit this to the scope of the current node.
        var result = new Dictionary<string, object>(routeValues);

        // Add any query string values from the current context
        var queryStringValues = httpContext.Request.QueryString;

        // QueryString collection might contain nullable keys
        foreach (var key in queryStringValues.AllKeys.Select(x => x.ToLower()).ToList())
        {
            // Copy the query string value as a route value if it doesn't already exist
            // and the name is provided as a match. Note that route values will take
            // precedence over query string parameters in cases of duplicates
            // (unless the route value contains an empty value, then overwrite).
            if (key != null && queryStringKeys.Contains(key) && (!result.ContainsKey(key) || string.IsNullOrEmpty(result[key].ToString())))
            {
                result[key] = queryStringValues[key];
            }
        }

        return result;
    }
}
最后是我用来从模型中提取属性值并将它们传递给父站点地图节点的属性

public class SiteMapRouteValueAttribute : ActionFilterAttribute
{
    private readonly string _key;
    private readonly string[] _propertyParts;

    public SiteMapRouteValueAttribute(string key, string modelProperty = "")
    {
        _key = key.ToLower();
        _propertyParts = modelProperty.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries);
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var viewResult = filterContext.Result as ViewResult;
        if (viewResult == null)
        {
            base.OnResultExecuting(filterContext);
            return;
        }
        var value = viewResult.Model;
        foreach (var property in _propertyParts)
        {
            var propertyInfo = value.GetType().GetProperty(property);
            value = propertyInfo.GetValue(value);
        }
        var currentNode = SiteMaps.Current.CurrentNode;
        while (currentNode != null)
        {
            currentNode.RouteValues[_key] = value;
            currentNode = currentNode.ParentNode;
        }
    }
}

所以现在它可以工作了,为什么任何查询字符串值名称的情况下,但网站地图生成的url将包含小写的查询字符串值名称。

谢谢,我添加了这个作为。但是,我将使用的解决方案是添加一个属性,该属性基于PreservedLoteParameters更正requestContext.HttpContext.Request.QueryString NameValueCollection中值的大小写。然后,PreserveRouteParameters和“MergeRouteValuesAndNamedQueryStringValues”将使用此属性将大小写从原始URL更改为配置的大小写。那么就不需要任何操作筛选器属性。仅供参考-此问题现在已在中修复,可在NuGet上获得。谢谢,它可以正常工作。url是用mvc.sitemap文件的大小写生成的。
public class SiteMapRouteValueAttribute : ActionFilterAttribute
{
    private readonly string _key;
    private readonly string[] _propertyParts;

    public SiteMapRouteValueAttribute(string key, string modelProperty = "")
    {
        _key = key.ToLower();
        _propertyParts = modelProperty.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries);
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var viewResult = filterContext.Result as ViewResult;
        if (viewResult == null)
        {
            base.OnResultExecuting(filterContext);
            return;
        }
        var value = viewResult.Model;
        foreach (var property in _propertyParts)
        {
            var propertyInfo = value.GetType().GetProperty(property);
            value = propertyInfo.GetValue(value);
        }
        var currentNode = SiteMaps.Current.CurrentNode;
        while (currentNode != null)
        {
            currentNode.RouteValues[_key] = value;
            currentNode = currentNode.ParentNode;
        }
    }
}