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

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

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

所有这些已保存的报告都可在单个列表中显示,在应用中的特定页面上显示名称和说明,每个链接到一般网址,例如“/ Reports / Saved / 248”。 (其中248是报告ID的示例)。

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

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


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

谢谢

有帮助吗?

解决方案

我认为您需要将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方法,而PeopleDisplay方法只是使用正确的参数调用People方法。从表单发布直接调用People方法。使用两种方法可以使用CSRF预防机制。您可以在TempData中使用一个标志,以确保只有通过重定向机制才能调用GET操作,如果您想限制对它的访问。

结束编辑

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

其他提示

可以使用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
};

当然,眼前的问题,我可以用这是当你的控制器/ action方法随时间变化发生的事情看,报告中的数据是无效的。但是你可能已经想过了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top