Url.Action(action,controller,routeValues) doubling

2019-07-07 18:58发布

问题:

I am using the following code (taken from a Stackoverflow post: Action Image MVC3 Razor ) in an HTML extension helper to build an action link. My Url.Action() method is returning a url that has the routeValues both in the route as well as appended onto the url like so:

/Proposals/List/Tabled?id=Tabled

when what I want is just

/Proposals/List?id=Tabled

Any suggestions about why it wants to do this?

Update:

A route rule from my Global.asax file. That must be why it's doing it, but why it's getting doubled up is still a mystery to me.

routes.MapRoute( _
    "ProposalsList", _
    "Proposals/List/{status}", _
    New With {.controller = "Proposals", .action = "List", .status = "Pending"} _
    )

Update:

Here is my call to the method, and I added the method definition to the code below.

@Html.ActionImage("Proposals", "List", New With {.id = Model.StatusFilter}, "~/images/" + Model.ImageFile, "Count", 32, 32, Model.ProposalsCount.ToString + " " + Model.StatusFilter + " Proposal(s)")

Here is my code:

    <Extension()> _
    Public Function ActionImage(ByVal html As HtmlHelper, ByVal controller As String, ByVal action As String, ByVal routeValues As Object, ByVal imagePath As String, ByVal alt As String, ByVal width As Integer, ByVal height As Integer, ByVal text As String) As MvcHtmlString                
            Dim url = New UrlHelper(html.ViewContext.RequestContext)
            Dim imgHtml As String
            Dim anchorHtml As String
            Dim imgbuilder = New TagBuilder("img")

            imgbuilder.MergeAttribute("src", url.Content(imagePath))
            imgbuilder.MergeAttribute("alt", alt)
            imgbuilder.MergeAttribute("width", width)
            imgbuilder.MergeAttribute("height", height)
            imgHtml = imgbuilder.ToString(TagRenderMode.SelfClosing)

            Dim anchorBuilder = New TagBuilder("a")
            anchorBuilder.MergeAttribute("href", url.Action(action, controller, routeValues))
            anchorBuilder.InnerHtml = imgHtml + "<br/>" + text
            anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal)

            Return MvcHtmlString.Create(anchorHtml)
    End Function

回答1:

When you pass routeValues to the url.action method it will use the values to override the currently defined ones (in the request context for the current page).

So when the current status is Tabled and you do not reset that in the new routeValues you pass, then it will still use it..

But since you pass an id as well it adds that too..

You need to pass New With {.id = Model.StatusFilter, .status = nothing}

the hierarchy is (from http://forums.asp.net/t/1328683.aspx)

  1. Values specified in the Url.Action call, then
  2. Values specified in the request context for the current page, then
  3. Default values for the route.