2

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

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

从应用程序中的所有这些页面中,用户可以通过为其命名和描述来保存“报告”或网格。这并没有真正保存显示在网格中的数据,而是保存定义网格外观的参数,保存用于获取数据的参数,并保存定义“位置”的参数它们是应用程序(动作、控制器、路由)——基本上是一堆关于报告/网格以及如何构建它的元数据。

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

这是我需要帮助的部分:

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


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

谢谢

4

2 回答 2

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 )
 {
     ....
 }

然后,您将在您的数据库中存储过滤器参数(按名称)、操作(“人员”)和控制器。重定向结果将使用 GET 并被定向到 PeopleDisplay 方法,该方法又简单地使用正确的参数调用 People 方法。从表单发布直接调用 People 方法。使用两种方法可以让您使用 CSRF 预防机制。您也许可以在 TempData 中使用一个标志来确保只有在您希望限制对它的访问时才通过重定向机制调用 GET 操作。

结束编辑

另一种选择是简单地存储使用的视图,而不是进行重定向,只需渲染适当的视图。您需要考虑的一件事是,执行重定向最终会得到一个包含所有参数的 URL,而呈现视图将不理会 URL,只显示与创建报告时使用的 URL 相同的视图.

于 2009-05-05T16:18:24.797 回答
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
};

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

于 2009-05-05T16:16:39.013 回答