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

后端 未结 4 878
甜味超标
甜味超标 2021-01-03 06:26

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

public ActionResult GetAlbumPictures(int albumId)
{
    var album = AlbumRepo.GetSingle(album         


        
相关标签:
4条回答
  • 2021-01-03 06:35

    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);
    }
    
    0 讨论(0)
  • 2021-01-03 06:36

    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();
    
    0 讨论(0)
  • 2021-01-03 06:40

    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 );
    }
    
    0 讨论(0)
  • 2021-01-03 07:00

    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/

    0 讨论(0)
提交回复
热议问题