tags:

views:

572

answers:

3

I've got an issue with MVC routing(or at least I think it's w/routing :) )...

Just upgraded to MVC RC1, but I'm not sure that it's related as this is my first attempt at setting a MapRoute and corresponding RouteLink.

here's the route:

routes.MapRoute("Test1",
                "Forecast/CurrentLineItems/{propertyID}/{forecastYear}/{forecastMonth}",
                 new { controller = "Forecast", action =   "CurrentLineItems", propertyID = "", forecastYear = "", forecastMonth = "" }
);

here's the RouteLink...in the view it's wrapped in a table cell:

Html.RouteLink(Html.Encode(myProperty.Description),"Test1", new { controller = "Forecast", action = "CurrentLineItems", propertyID = myProperty.PropertyID.ToString(), forecastYear = "2008", forecastMonth = "10" })

here's a snippet from the controller:

namespace AnApplication.Controllers  
{
[HandleError]
[Authorize]
public class ForecastController : Controller
{        
    [AcceptVerbs(HttpVerbs.Get)]        
    public ActionResult CurrentLineItems(string propertyID, string forecastYear, string forecastMonth)
    {
       //Some code
    }

Now for the strange behavior, when I click the link specified by the RouteLink, the app enters the CurrentLineItems method and all the method arguments are correct... then it enters the CurrentLineItems method again!
with, for instance, these arguments:

propertyID = "scripts"    
forecastYear = "jquery-1.2.6.js"  
forecastMonth = ""

It then repeats this several times as it seems to run through all the scripts on this view and the Site.Master and then the last one is the .css file for this page!
What is going on!
The Call Stack is of no help as it lists the above-mentioned CurrentLineItems method and then below that is the dreaded [External Code]

When I profile the page/view in FireFox/FireBug all I see are the jQuery calls

Here's the html from the Site.Master re the scripts

<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title><%= Html.Encode(ViewData["Title"]) %></title>
    <script type="text/javascript" src="../../scripts/jquery-1.2.6.js"></script>  
    <script type="text/javascript" src="../../scripts/calculations.js"></script>  
    <script type="text/javascript" src="../../scripts/common.js"></script>    
    <style media="all" type="text/css">@import "../../Content/all.css";</style>
    <!--[if IE]><link rel="stylesheet" type="text/css" href="../../Content/ie.css"media="screen"/><![endif]-->    
    <!--<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />-->
</head>

here's a snippet from the view re the scripts

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"AutoEventWireup="true" CodeBehind="CurrentLineItems.aspx.cs" Inherits="AnApplication.Views.Forecast.CurrentLineItems" %>

<asp:Content ID="lineItemsContent" ContentPlaceHolderID="MainContent" runat="server">
<!--<script type="text/javascript" src="../../scripts/MicrosoftAjax.debug.js"></script>-->
<script type="text/javascript" src="../../scripts/lineItems.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.formatCurrency.js"></script>
<!--<script type="text/javascript" src="../../scripts/jquery-1.2.6.min.js"></script>-->

Note that this ActionLink works fine(It's basically just a menu item used for testing and the three arguments are set in the code inside the controller...):

<%= Html.ActionLink("Line Items", "CurrentLineItems", "Forecast")%>

Any help in solving this issue is greatly appreciated.

Thanks,
Greg

+1  A: 

RouteLink versus ActionLink is a red herring here. The only thing that matters is the rendered a href="[something]". You would get exactly the same results if you wrote the a href manually instead of generating it via RouteLink.

So, yes, now we're down to routing. Inside your controller action, inspect RouteData in the debugger, and see which route name was matched. Chances are very likely it's the wrong one, and that is causing other things to misbehave. Either change the order of your reps, or add constraints to prevent the wrong one from being matched.

RouteLink works very well to prevent finding the wrong route when you're generating a URL. But when your application is consuming a URL, you still need to have your routes in order in global.asax.

Craig Stuntz
The RouteData is the same...first time with the correct arguments...subsequent times with the 'scripts' etc arguments. I get the same behavior if I type in the URL Like so http://AnApp/Forecast/CurrentLineItems/010/2008/10, but if I type in http://AnApp/Forecast/CurrentLineItems/ it works fine...
w4ik
>>>or add constraints to prevent the wrong one from being matched.I'm considering doing this just move past this issue...
w4ik
w4ik
When I view source of the loaded view I see... <script type="text/javascript" src="../../scripts/jquery-1.2.6.js"></script> <script type="text/javascript" src="../../scripts/calculations.js"></script> <script type="text/javascript" src="../../scripts/common.js"></script>
w4ik
rest of the view's relevant source... <style media="all" type="text/css">@import "../../Content/all.css";</style>
w4ik
+2  A: 

It could be caused by the usage of relative paths to include the scripts.

When you click on the link the URL of the new page will be something like http://[server]/Forecast/CurrentLineItems/xxx/2009/1

Now check the html code in the browser: If the URLs are in the form of '../../scripts/jquery-1.2.6.js', this will cause the browser to load it from http://[server]/Forecast/CurrentLineItems/scripts/jquery-1.2.6.js - and so your controller gets called again.

If that is the case you could either use absolute paths ('/scripts/jquery-1.2.6.js') or use a path relative to the application root ('~/scripts/jquery-1.2.6.js') and resolve it on the server side with Page.ResolveClientUrl().

Maybe there has been a change from Beta to RC1, so that the URLs in the head, even with runat="server", don't get remapped.

David Tischler
David, Thanks a million!...that was it...excellent explanation too, thanks for taking the time to answer...Greg
w4ik
+6  A: 

Hi everyone, There were in fact two subtle, yet annoying bugs in the recently release ASP.NET MVC Release Candidate. These were the two bugs:

  1. We changed all our URL-rendering methods to render relative URLs instead of absolute URLs. While we feel this might be the right decision in general, we found that it breaks an awful lot of scenarios. AJAX scenarios were especially affected since the URLs for retrieving data asynchronously are often different from the original URL as seen in the browser's address bar.

  2. Html.RouteLink specifically (and not Html.ActionLink) had a bug in it (so it is not in fact a red herring - at least not necessarily). Html.RouteLink would erroneously take the "current" controller and action and pass those values into the routing system. Only Html.ActionLink is supposed to do that. Html.RouteLink is not supposed to do any processing at all. It's supposed to just take the values you give it and pass it along to the ASP.NET Routing system.

Since these two bugs were both pretty bad, we decided to roll back the change that caused #1 and to fix the issue that caused #2 and release an updated ASP.NET MVC Release Candidate Refresh.

You'll see some posts on ScottGu's blog, Phil Haack's blog, and the ASP.NET MVC Forums detailing the refresh.

Thanks, Eilon

Eilon
Eilon, Thanks for taking the time to post here...looking forward to the Refresh release...Thanks again, Greg
w4ik