如何从保存的数据重建ASP.NET MVC中的URL /路由?

时间:2009-05-05 16:03:16

标签: c# asp.net-mvc asp.net-mvc-routing

我对ASP.NET MVC框架及其管道的不熟悉使我在这里,我感谢任何人阅读和考虑我的问题所需要的耐心!

好的,这是一个场景:我有一个应用程序,其中包含大量页面,其中包含基于搜索显示数据的网格,从其他数据向下钻取,基于特定于上下文的数据的报告(即它们位于Foo的详细信息页面上) ,然后单击显示与Foo相关的数据表的链接等。

通过应用程序中的任何和所有这些页面,用户可以通过为其提供名称和说明来保存“报告”或网格。这并不能真正保存网格中显示的数据,而是保存定义网格外观的参数,保存用于获取数据的参数,并保存参数在应用程序中定义“where”(动作,控制器,路径) - 基本上是一堆关于报告/网格的元数据以及如何构建它。

所有这些已保存的报告都在一个列表中提供,在应用程序的某个页面上显示名称和描述,每个链接到一个通用URL,例如“/ Reports / Saved / 248”(其中248是报告ID的一个例子。

以下是我需要帮助的部分:

当我通过URL“/ Reports / Saved / 248”进行操作并从该数据库中提取特定报告的元数据时,如何将该数据和请求重定向到相同的操作,控制器和路由用于显示报告最初保存的视图?基本上,我希望用户在同一视图中查看报告,其URL与保存的URL相同。如果可能的话,我能够基本上“调用”相同的动作,就好像我正在进行方法调用一样。


更新:不幸的是,我们的报告页面(即这些网格出现的页面)并未使用RESTful URL - 例如,我们称之为高级搜索页面,它占用了相当多的潜在参数(近30个)来自包含选择列表,文本框等的表单。当用户提交该页面时,我们对一个动作进行POST,该动作接受模型绑定器为我们构建的复杂类型 - 同样的动作是我想要调用的当用户从数据库中选择保存的高级搜索时。这个例子集中体现了我的问题。

谢谢

2 个答案:

答案 0 :(得分:2)

我认为您需要将RedirectToAction与带有RouteValueDictionary的签名一起使用。您重定向到的方法需要能够从控制器上的ValueProvider中提取值。它可能看起来像:

public ActionResult Saved( int id )
{
    var reportParams = db.Reports.SingleOrDefault( r => r.ID == id );
    if (reportParams == null)
       ...handle error...

    var routeValues = ParamsToRouteValueDictionary( reportParams );

    return RedirectToAction( reportParams.Action, reportParams.Controller, routeValues );
}

private RouteValueDictionary ParamsToRouteValueDictionary( object parameters )
{
     var values = new RouteValueDictionary();
     var properties = parameters.GetType().GetProperties()
                                .Where( p => p.Name != "Action" && p.Name != "Controller" );
     foreach (var prop in properties)
     {
         values.Add( prop.Name, prop.GetValue(parameters,null) );
     }

     return values;
}

修改

使用过滤器模型作为方法的参数实际上可以使其更容易。你只需要你的行动的GET和POST版本。

 [ActionName("People")]
 [AcceptVerbs( HttpVerbs.Get )]
 public ActionResult PeopleDisplay( SearchModel filter )
 {
     return People( filter );
 }

 [AcceptVerbs( HttpVerbs.Post)]
 [ValidateAntiForgeryToken]
 public ActionResult People( SearchModel filter )
 {
     ....
 }

然后,您将在db中为报告存储过滤器参数(按名称),Action(“People”)和Controller。重定向结果将使用GET并定向到PeopleDisplay方法,而PeopleDisplay方法只是使用正确的参数调用People方法。从表单发布直接调用People方法。使用两种方法可以使用CSRF预防机制。您可以在TempData中使用一个标志,以确保只有在您限制对它的访问时才通过重定向机制调用GET操作。

结束编辑

另一种替代方法是简单地存储使用的View,而不是进行重定向,只需渲染适当的视图。您需要考虑的一件事是,重定向最终将包含一个包含所有参数的URL,而呈现View将保留URL,并且只显示与创建报告时使用的URL相同的视图。

答案 1 :(得分:0)

您可以使用RedirectToAction方法向任何控制器上的特定操作方法发出301重定向以及路由值:

ReportMeta meta = _reportDataAccess.Get(id);
return RedirectToAction(meta.Action, meta.Controller, meta.RouteData);

这些值类似于:

meta.Action = "Bar";
meta.Controller = "Foo";
meta.RouteData = new {
    // possibly settings for the grid
    start = DateTime.Min,
    end = DateTime.Now,
    sort = "Date"
    // you get the idea
};

当然,我可以看到的直接问题是当控制器/操作方法随时间变化时会发生什么,报告数据将无效。但是你可能已经想过了。