ASP.Net Mvc 3 Url.Action method uses parameter val

2019-02-12 10:49发布

问题:

When Urls are autogenerated using the Url.Action helper, if a page contains a line similar to

@Url.Action("Edit","Student")

is expected to generate a url like domain/student/edit and its working as expected. But if the requested url contains some parameters, like domain/student/edit/210, the above code uses these parameters from the previous request and generates something similar even though I've not provided any such parameter to the Action method.

In short, if the requested url contains any parameters, any auto generated links of the page (served for that request) will include those parameters as well no matter if I specify them or not in the Url.Action method.

What's going wrong?

回答1:

Weird, can't seem to reproduce the problem:

public class HomeController : Controller
{
    public ActionResult Index(string id)
    {
        return View();
    }

    public ActionResult About(string id)
    {
        return View();
    }
}

and inside Index.cshtml:

@Url.Action("About", "Home")

Now when I request /home/index/123 the url helper generates /home/about as expected. No ghost parameters. So how does your scenario differs?


UPDATE:

Now that you have clarified your scenario it seems that you have the following:

public class HomeController : Controller
{
    public ActionResult Index(string id)
    {
        return View();
    }
}

and inside Index.cshtml you are trying to use:

@Url.Action("Index", "Home")

If you request /home/index/123 this generates /home/index/123 instead of the expected /home/index (or simply / taken into account default values).

This behavior is by design. If you want to change it you will have to write your own helper which ignores the current route data. Here's how it might look:

@UrlHelper.GenerateUrl(
    "Default", 
    "index", 
    "home", 
    null, 
    Url.RouteCollection, 
    // That's the important part and it is where we kill the current RouteData
    new RequestContext(Html.ViewContext.HttpContext, new RouteData()), 
    false
)

This will generate the proper url you were expecting. Of course this is ugly. I would recommend you encapsulating it into a reusable helper.



回答2:

Use Darin's answer from this similar question.

@Url.Action("Edit","Student", new { ID = "" })


回答3:

Use ActionLink overload that uses parameters and supply null



回答4:

You could register custom route for this action for example:

routes.MapRoute("Domain_EditStudentDefault",
            "student/edit",
            new { 
                controller = MVC.Student.Name, 
                action = MVC.Student.ActionNames.Edit,
                ID = UrlParameter.Optional
            },
            new object(),
            new[] { "MySolution.Web.Controllers" }
        );

you then could use url.RouteUrl("Domain_EditStudentDefault") url RouteUrl helper override with only routeName parameter which generates url without parameters.