Is it possible to change the querystring variable in ASP.NET MVC path before it hits the controller?

感情迁移 提交于 2019-11-29 22:09:59

问题


I have a controller method in ASP.NET MVC that looks like this:

public ActionResult GetAlbumPictures(int albumId)
{
    var album = AlbumRepo.GetSingle(albumId);
    var pictures = album.Pictures;
    return View(pictures);
}

The routing for this method looks like this:

routes.MapRoute(null,
                "pictures"
                new { controller = "Album", action = "GetAlbumPictures" });

The user will use the following URL to get the pictures, filtered by the album ID:

GET http://server/pictures?albumid=10

However, I'd like to change the querystring parameter to just album instead of albumid:

GET http://server/pictures?album=10

This would mean that the controller method needs to be modified to:

public ActionResult GetPictures(int album)
{
    ...
}

However, this is not ideal because now the method has a parameter named album, which can be confused as an Album object instead of the ID of the Album.

My question is, is there any way of configuring ASP.NET MVC so that in the routing, it will receive a querystring parameter called album, but then pass it off to the controller as the albumId parameter?

P.S. I know that I can do this in the routing table:

routes.MapRoute(null,
                "album/{albumId}/pictures",
                new { controller = "Album", action = "GetAlbumPictures" });

But due to legacy issues, I have to make it work for the querystring method as well.


回答1:


You can create a custom action filter attribute to handle this scenario. I haven't tested this specific implementation, but the general idea is to do something like this:

public class AlbumAttribute : ActionFilterAttribute
    {
         public override void OnActionExecuting(ActionExecutingContext filterContext)
         {
             var albumId = filterContext.HttpContext.Request.QueryString["album"] as string;
             filterContext.ActionParameters["albumId"] = albumId;

             base.OnActionExecuting(filterContext);
         }
    }

Then, decorate your action method with the [Album] attribute:

[Album]
public ActionResult GetAlbumPictures(int albumId)
{
    var album = AlbumRepo.GetSingle(albumId);
    var pictures = album.Pictures;
    return View(pictures);
}



回答2:


You can use a Custom Model Binder and it will work with both album and albumId. It can be implemented as follows:

Custom Model Binder:

public class AlbumModelBinder : IModelBinder
{
    public object BindModel
    (ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        int albumId;
        var albumVar = bindingContext.ValueProvider.GetValue( "album" );
        if (albumVar != null)
        {
            albumId = int.Parse( albumVar.AttemptedValue );
        }
        else
        {
            albumId = int.Parse( bindingContext.ValueProvider.GetValue( "albumId" ).AttemptedValue );
        }
        return albumId;
    }
}

Action implementation:

public ActionResult GetAlbumPictures
([ModelBinder( typeof( AlbumModelBinder ) )] int albumId)
{
    var album = AlbumRepo.GetSingle(albumId);
    var pictures = album.Pictures;
    return View(pictures);
} 

Global.asax.cs implementation:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    ModelBinders.Binders.Add( typeof( int ), new AlbumModelBinder() );
    RegisterRoutes( RouteTable.Routes );
}



回答3:


Consider intercepting your request and use HttpContext.RewritePath to alter the query string before its picked up by the Routing engine. There is a nice diagram here showing how Url Rewriting is executed ages before the routing :)

http://learn.iis.net/page.aspx/496/iis-url-rewriting-and-aspnet-routing/




回答4:


You can intercept the request before it hits the controller in Application_BeginRequest in your global.asax. You won't have access to the MVC contexts though, but could use

Server.Transfer(...);

or

Response.Redirect(...); 
Response.End();


来源:https://stackoverflow.com/questions/4558982/is-it-possible-to-change-the-querystring-variable-in-asp-net-mvc-path-before-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!