从另一个动作返回一个动作不起作用?

时间:2012-08-10 16:15:15

标签: c# .net asp.net-mvc c#-4.0 asp.net-mvc-4

我正在尝试重载MVC Action,但由于“重载”不适用于路由操作(错误500表示模糊方法,我猜因为参数不能从浏览器强类型化),所以我想我只会返回一个由于我不能将RedirectToAction用于HttpPost,因此对另一个操作。问题是它正试图找到一个带有新动作名称的视图,而不是我试图调用的动作。这是我想要做的:

    [HttpPost]
    public ActionResult DetailForProductID(int productID)
    {
        return Detail(new[] { GetProductById(productID) });
    }

    [HttpPost]
    public ActionResult Detail(IEnumerable<Product> products)
    {
       ....
       return View(productViewModel);
    }

这是我得到的错误:

The view 'DetailForProductID' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Products/DetailForProductID.aspx
~/Views/Products/DetailForProductID.ascx
~/Views/Shared/DetailForProductID.aspx
~/Views/Shared/DetailForProductID.ascx
~/Views/Products/DetailForProductID.cshtml
~/Views/Products/DetailForProductID.vbhtml
~/Views/Shared/DetailForProductID.cshtml
~/Views/Shared/DetailForProductID.vbhtml

处理此问题最强大,最优雅的方法是什么?我不希望将事物存储在临时会话中或执行RedirectToAction因为我应该能够在服务器端执行所有操作。任何帮助或建议将不胜感激。

3 个答案:

答案 0 :(得分:3)

对于这样的重定向,我建议如下:

return RedirectToAction("Detail", data);

但我不确定你为什么需要这个。看看你的行为,为什么不这样做呢?

public ActionResult Detail(int productId)
{
   var data = GetProductById(productID);
   ....
   return View(productViewModel);
}

答案 1 :(得分:1)

您也可以在此方案中使用Tempdata,例如:

public ActionResult DetailForProductID(int productID)
{
    IEnumerable<Product> data =   GetProductById(productID);
    TempData["ProductData"]= data;
    return RedirectToAction("Detail",data);        
}


public ActionResult Detail(IEnumerable<Product> products)
{
   ....
    if(TempData["ProductData"]!=null){
       IEnumerable<Product> data =  (IEnumerable<Product>)TempData["ProductData"];
       return View(data);
    }else {
       return View(products);
    }
}

答案 2 :(得分:0)

我认为保持控制器“瘦”和“哑”非常重要。一旦你超越了一个简单的网站并且需要构建更复杂的东西,你就不希望多次重写相同的代码(由于很多原因而不是很好)。将控制器用作通用功能也是不可能的(这基本上就是你现在尝试做的)。

处理此问题的更优雅和强大的方法是抽象出您的应用程序逻辑并在其他地方执行它。然后,您可以根据操作的要求调用逻辑部分。要开始向这个方向移动,您可以在每个控制器中编写控制器特定的逻辑,然后确定它们之间共享的功能,并将其放在项目的其他位置。在更复杂的项目中,控制器中根本没有应用程序逻辑并不罕见。

您可能想尝试创建一个通用函数,该函数可能通过Id返回“Product”并将该函数放在其他位置。然后使用控制器确定特定逻辑并调用共享函数以通过Id获取产品。