我在ASP.NET MVC中有一个控制器方法,如下所示:
public ActionResult GetAlbumPictures(int albumId)
{
var album = AlbumRepo.GetSingle(albumId);
var pictures = album.Pictures;
return View(pictures);
}
此方法的路由如下所示:
routes.MapRoute(null,
"pictures"
new { controller = "Album", action = "GetAlbumPictures" });
用户将使用以下网址获取图片,按照相册ID进行过滤:
GET http://server/pictures?albumid=10
但是,我想将querystring参数更改为album
而不是albumid
:
GET http://server/pictures?album=10
这意味着需要将控制器方法修改为:
public ActionResult GetPictures(int album)
{
...
}
但是,这并不理想,因为现在该方法有一个名为album
的参数,可以将其混淆为Album
对象而不是ID
Album
。
我的问题是,有没有办法配置ASP.NET MVC,以便在路由中,它将收到一个名为album
的查询字符串参数,但随后将其作为{{1}传递给控制器参数?
P.S。我知道我可以在路由表中执行此操作:
albumId
但由于遗留问题,我必须使其适用于查询字符串方法。
答案 0 :(得分:9)
您可以创建自定义操作过滤器属性来处理此方案。我没有测试过这个具体的实现,但总的想法是做这样的事情:
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);
}
}
然后,使用[Album]属性修饰您的动作方法:
[Album]
public ActionResult GetAlbumPictures(int albumId)
{
var album = AlbumRepo.GetSingle(albumId);
var pictures = album.Pictures;
return View(pictures);
}
答案 1 :(得分:0)
您可以使用自定义模型Binder,它可以同时使用album和albumId。 它可以实现如下:
自定义模型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;
}
}
行动实施:
public ActionResult GetAlbumPictures
([ModelBinder( typeof( AlbumModelBinder ) )] int albumId)
{
var album = AlbumRepo.GetSingle(albumId);
var pictures = album.Pictures;
return View(pictures);
}
Global.asax.cs实施:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.Add( typeof( int ), new AlbumModelBinder() );
RegisterRoutes( RouteTable.Routes );
}
答案 2 :(得分:0)
考虑拦截您的请求并使用HttpContext.RewritePath在路由引擎选择之前更改查询字符串。这里有一个很好的图表,显示了如何在路由之前执行Url重写:)
http://learn.iis.net/page.aspx/496/iis-url-rewriting-and-aspnet-routing/
答案 3 :(得分:-1)
您可以在global.asax中的Application_BeginRequest中访问控制器之前拦截请求。您将无法访问MVC上下文,但可以使用
Server.Transfer(...);
或
Response.Redirect(...);
Response.End();