我的asp.net MVC 4应用程序的路由问题

时间:2016-07-12 09:06:56

标签: asp.net-mvc-4 asp.net-mvc-routing

由于这个问题,我过去几天忙碌了。我试图将路线数据作为导航问题传递给视图。但是,routeInfo不包含路由信息。 ie routeInfo.RouteData.Values.Count = 0.我有另一个使用相同代码的应用程序正常工作。

我不确定我在这里失踪了什么。

任何帮助都会非常感激!!

    public ActionResult Index(int type)
    {
        UrlHelper u = new UrlHelper(this.ControllerContext.RequestContext);
        string url = u.Action("Action", "Controller", new { type = type }, Request.Url.Scheme);
        Uri uri = new Uri(url);
        RouteInfo routeInfo = new RouteInfo(uri, HttpContext.Request.ApplicationPath);
        Session["_ReturnURL"] = routeInfo.RouteData.Values;
        ViewBag.ReturnURL = Helpers.GetSessionKey("_ReturnURL");

        return View();
    }


    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.RouteExistingFiles = true;
        routes.IgnoreRoute("elmah.axd");
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Controller",
            url: "Controller/{type}/{action}/{id}",
            defaults: new { controller = "Controller", action = "Action", id = UrlParameter.Optional }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "CBlah", action = "ABlah", id = UrlParameter.Optional, returnUrl = "~/Blah2/Blah2" }
        );

    }


public class RouteInfo
{
    public RouteData RouteData { get; private set; }

    public RouteInfo(RouteData data)
    {
        RouteData = data;
    }

    public RouteInfo(Uri uri, string applicationPath)
    {
        RouteData = RouteTable.Routes.GetRouteData(new InternalHttpContext(uri, applicationPath));
    }

    private class InternalHttpContext : HttpContextBase
    {
        private readonly HttpRequestBase _request;

        public InternalHttpContext(Uri uri, string applicationPath)
        {
            _request = new InternalRequestContext(uri, applicationPath);
        }

        public override HttpRequestBase Request { get { return _request; } }
    }

    private class InternalRequestContext : HttpRequestBase
    {
        private readonly string _appRelativePath;
        private readonly string _pathInfo;

        public InternalRequestContext(Uri uri, string applicationPath)
        {
            _pathInfo = uri.Query;

            if (String.IsNullOrEmpty(applicationPath) || !uri.AbsolutePath.StartsWith(applicationPath, StringComparison.OrdinalIgnoreCase))
                _appRelativePath = uri.AbsolutePath.Substring(applicationPath.Length);
            else
                _appRelativePath = uri.AbsolutePath;
        }

        public override string AppRelativeCurrentExecutionFilePath { get { return String.Concat("~", _appRelativePath); } }
        public override string PathInfo { get { return _pathInfo; } }
    }
}

1 个答案:

答案 0 :(得分:0)

Route.GetRouteData定义

public override RouteData GetRouteData(HttpContextBase httpContext)
{
    string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
    RouteValueDictionary values = this._parsedRoute.Match(virtualPath, this.Defaults);
    if (values == null)
    {
        return null;
    }
    RouteData data = new RouteData(this, this.RouteHandler);
    if (!this.ProcessConstraints(httpContext, values, RouteDirection.IncomingRequest))
    {
        return null;
    }
    foreach (KeyValuePair<string, object> pair in values)
    {
        data.Values.Add(pair.Key, pair.Value);
    }
    if (this.DataTokens != null)
    {
        foreach (KeyValuePair<string, object> pair2 in this.DataTokens)
        {
            data.DataTokens[pair2.Key] = pair2.Value;
        }
    }
    return data;
}

问题出在这一行:

string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;

您要将查询字符串附加为httpContext.Request.PathInfo来自:

_pathInfo = uri.Query;

我知道Route类不考虑查询字符串这一事实,因此将其附加到路径是一个错误。还有一些信息here支持PathInfo总是返回空字符串的事实。

MSDN

  

对于网址http://www.contoso.com/virdir/page.html/tail,PathInfo值为/tail

因此,添加查询字符串会使此行失败(当存在查询字符串时),因为_parsedRoute.Match不期待它。

RouteValueDictionary values = this._parsedRoute.Match(virtualPath, this.Defaults);

我的猜测是你的某个应用程序“有效”,因为它没有传递带有查询字符串的URL,因此正确匹配。但无论如何,你应该从你PathInfo类中的InternalRequestContext返回一个空字符串,使其在100%的时间内都能正常工作(除非你有疯狂的带点的URL,然后你可能需要做一些额外的工作)。