TearGas
TearGas

Reputation: 3

ASP.NET MVC 5 custom route goes to wrong action

I'm having trouble with a custom route which isn't being routed correctly. Both @Html.ActionLink and @Html.RouteLink create the correct url fantasy/1/fantasyleague1/matchups which when clicked never touches the Matchups Action and incorrectly routes to fantasy/1/fantasyleague1/settings?round=3

RouteDebugger shows:

Matched Route: Fantasy/{leagueID}/{leagueSlug}/Settings

Generated URL: /fantasy/11/fantasyleague1/matchups/3 using the route "Fantasy/{leagueID}/{leagueSlug}/Matchups/{round}"

RouteConfig.cs

    routes.MapRoute(
        name: "Fantasy League Matchups",
        url: "Fantasy/{leagueID}/{leagueSlug}/Matchups/{round}",
        defaults: new { controller = "Fantasy", action = "Matchups", leagueSlug = UrlParameter.Optional, round = UrlParameter.Optional },
        constraints: new { leagueID = @"\d+" }
    );

    routes.MapRoute(
        name: "Fantasy League Settings",
        url: "Fantasy/{leagueID}/{leagueSlug}/Settings",
        defaults: new { controller = "Fantasy", action = "Settings", leagueSlug = UrlParameter.Optional },
        constraints: new { leagueID = @"\d+" }
    );

FantasyController.cs

    // GET: /Fantasy/{leagueID}/{leagueSlug}/Matchups/{round}
    public ActionResult Matchups(int leagueID, string leagueSlug = null, int round = -1) {
        var fantasyLeague = DataContext.FantasyLeagues.Where(l => l.ID == leagueID).FirstOrDefault();
        if (fantasyLeague != null) {
            if (string.IsNullOrEmpty(leagueSlug) || round == -1) {
                return RedirectToActionPermanent("Matchups", "Fantasy", new { leagueID = leagueID, leagueSlug = fantasyLeague.Slug, round = fantasyLeague.CurrentRound });
            }

            var userInLeague = User != null && User.Identity != null && fantasyLeague.FantasyTeams.Any(t => t.Owner.UserName == User.Identity.Name);
            var fantasyMatches = fantasyLeague.FantasyMatches.Where(fm => fm.Round == round).ToList();

            return View("Matchups", new FantasyMatchupsViewModel {
                FantasyLeague = fantasyLeague,
                FantasyMatches = fantasyMatches,
                Round = round,
                UserInLeague = userInLeague
            });
        }
        return RedirectToAction("Index");
    }

    // GET: /Fantasy/{leagueID}/{leagueSlug}/Settings
    public ActionResult Settings(int leagueID, string leagueSlug = null) {
        var fantasyLeague = DataContext.FantasyLeagues.Where(l => l.ID == leagueID).FirstOrDefault();
        if (fantasyLeague != null) {
            if (string.IsNullOrEmpty(leagueSlug)) {
                return RedirectToActionPermanent("Settings", "Fantasy", new { leagueID = leagueID, leagueSlug = fantasyLeague.Slug });
            }

            var userOwnsLeague = User != null && User.Identity != null && fantasyLeague.Commissioner.UserName == User.Identity.Name;

            return View("Settings", new FantasySettingsViewModel {
                FantasyLeague = fantasyLeague,
                UserOwnsLeague = userOwnsLeague,
                Name = fantasyLeague.Name,
                MaxPlayers = fantasyLeague.MaxPlayers,
                LockoutPeriod = fantasyLeague.LockoutPeriod,
                PasswordProtected = fantasyLeague.PasswordProtected,
                Password = fantasyLeague.Password
            });
        }
        return RedirectToAction("Index");
    }

Upvotes: 0

Views: 301

Answers (1)

NightOwl888
NightOwl888

Reputation: 56849

Most likely, this is not a routing problem at all. You are using RedirectToActionPermanent, which produces a 301 redirect. Most browsers cache 301 redirects, so the behavior you are seeing is likely from the first hit your browser cached.

Instead of using RedirectToActionPermanent, you should use RedirectToAction, which will generate a "normal" 302 redirect.

301 redirects are for ensuring URLs that have already been put into the wild (that is, users have potentially bookmarked and/or search engines have potentially indexed) are updated to the new location. They should generally not be used just to get a user from URL A to URL B within your application.

Upvotes: 1

Related Questions