开发者

mvc2.net how to remove ambient route values

in my mvc2 application i have an action link like

<%=Html.ActionLink("dash.board", "Index", pck.Controller,  new{docid ="",id = pck.PkgID }, new { @class = "here" })%>

docid is set to empty string because i want to clear ambient value of docid that is present in request context. i have gone through a lot of material on internet and even tried docid=String.Empty but it does not solve the problem and gives me url like /controller/action/id?docid=x. i also write a routeconstraint as suggested here but it did not solve the problem either. 开发者_运维知识库plz suggest me a way to clear those route values comming from request context with html.actionLink. i don't want to use html.routeLink


Solution at the root of the problem

It seems that the optimal solution (that doesn't smell too much as a workaround) is the one that solves the problem where it has roots and that's in routing.

I've written a custom Route class called RouteWithExclusions that is able to define route value names that should be excluded/removed when generating URLs.

The whole problem is detailed and explained in my blog post and all the code is provided there as well. Check it out, it may help you solve this routing problem. I've also written two additional MapRoute extension methods that take an additional parameter.


This is such a frustrating problem and I would venture to say that it is even a bug in ASP.Net MVC. Luckily it's an easy fix using ActionFilters. If you are using MVC3 then I would just put this as a global attribute to clear out ambient values. I made this attribute discriminatory, but you can change it to clear all attributes.

The assumption here is that by the time the Result is executing (your view most likely), you have already explicitly specified all your ActionLinks and Form Actions. Thus this will execute before they (the links) are evaluated, giving you a new foundation to generate them.

public class ClearAmbientRouteValuesAttribute : ActionFilterAttribute 
{
    private readonly string[] _keys;

    public ClearAmbientRouteValuesAttribute(params string [] keys)
    {
        if (keys == null)
            _keys = new string[0];

        _keys = keys;
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        foreach (var key in _keys) {
            // Why are you sticking around!!!
            filterContext.RequestContext.RouteData.Values.Remove(key);        
        }
    }
}

// Inside your Global.asax
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new ClearAmbientRouteValuesAttribute("format"));
}

Hope this helps someone, cause it sure helped me. Thanks for asking this question.


I know this is really old, but I'm dealing with this issue in MVC5. For what it's worth, this seems to work for me, and I leave it here for others to try...

On the site I'm working on, I have a controller action that takes a date as a parameter like this:

http://localhost:9999/DailyActivity/2014-01-01

But in the page, I need links that resolve to

http://localhost:9999/DailyActivity

or

http://localhost:9999/DailyActivity/Index

Using this

@Html.ActionLink("Test Link", "Index", "DailyActivity")

Frustratingly creates links like this:

http://localhost:9999/DailyActivity/2014-01-01

This does not help:

@Html.ActionLink("Test Link", "Index", "DailyActivity", new { date = String.Empty }, null)

As it creates a link like this:

http://localhost:9999/DailyActivity?date=2014-01-01

After banging my head, the solution I found seems to work. Put a slash in the action name (before or after). The ambient date value is then discarded:

@Html.ActionLink("Test Link", "/Index", "DailyActivity")

That generates:

http://localhost:9999/DailyActivity/Index

And

@Html.ActionLink("Test Link", "/Index/..", "DailyActivity")

Gives

http://localhost:9999/DailyActivity

I don't yet know what kind of ramifications this has in the routing system, but it seems to work...

EDIT:

It might be a better idea to do this (for the default action):

@Html.ActionLink("Test Link", String.Empty, "DailyActivity")

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜