【问题标题】:How to redirect to an action with parameters from other action without passing parameters?如何在不传递参数的情况下重定向到具有其他操作参数的操作?
【发布时间】:2017-02-27 18:17:59
【问题描述】:

下面,在 CreateTest 中,一旦成功,我想从 CreateTest 重定向到测试。

我想做如下的事情:

    public ActionResult Tests(int ID, string projectName)
    {
        TestModel model = new TestModel (ID, projectName);
        return View(model);
    }

 [HttpPost]
    public ActionResult CreateTest(TestModel model)
    {
        try
        {
            return RedirectToAction("Tests");
        }
        catch (Exception e)
        {
            ModelState.AddModelError("Error", e.Message);
            return View(model);
        }
    }

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3


    【解决方案1】:

    重定向时可能需要提供参数:

    return RedirectToAction("Tests", new { 
       ID = model.ID, 
       projectName = model.ProjectName 
    });
    

    您将重定向到的网址现在看起来像这样:

    /Foo/Tests?ID=123&projectName=abc

    【讨论】:

    • 谢谢,但是如何返回错误信息呢? public ActionResult CreateTest(TestModel model) { try { return RedirectToAction("Tests"); } catch (Exception e) { ModelState.AddModelError("Error", e.Message);返回视图(测试); } }
    • @user281180,您也可以在查询字符串中传递它们:new { ID = model.ID, projectName = model.ProjectName, errorMessage = "Some error message" }。但是从我所看到的情况来看,如果出现错误,您没有重定向,您只是渲染视图,这是正确的做法,因此您可以直接访问视图内的错误消息,因为它被添加到模型状态。
    • @Darin Its not working, im 出现错误消息:传入字典的模型项的类型为 'f__AnonymousType1`2[System.Int32,System.String]',但是这个字典需要“MvcUI.Models.TestModel”类型的模型项。
    • 使用时 return RedirectToAction("Tests", new { ID = model.ID, projectName = model.ProjectName });
    • @user281180,我不知道这个匿名类型是从哪里来的。首先尝试对值进行硬编码:return RedirectToAction("Tests", new { ID = "123", projectName = "abc" });。确保 ID 参数不为空,因为在您的目标控制器操作中它不能为空。如有必要,您可以将其设为可为空的整数。
    【解决方案2】:

    我知道这有点老了,但是......

    我过去所做的是将“MessageArea”类公开为我的基本控制器上的一个属性,我的所有控制器最终都继承自该属性。该属性实际上将类实例存储在 TempData 中。 MessageArea 有一个 Add() 方法,该方法接受字符串消息和枚举类型(例如成功、错误、警告、信息)。

    然后我有一个部分,它根据消息的类型以适当的样式呈现 MessageArea 中的任何消息。

    我有一个 HTMLHelper 扩展方法 RenderMessageArea(),所以在任何视图中我都可以简单地说 @Html.RenderMessageArea(),该方法和部分处理空值,如果没有消息,则不会输出任何内容。

    因为存储在 TempData 中的数据只能在 1 个请求中存活,所以它非常适合您希望操作重定向但在目标页面上显示 1 个或多个消息的情况,例如错误,未授权页面等...或者如果您添加项目但随后返回索引列表页面。

    显然,您可以实现类似的东西来传递其他数据。最终,我会说这是对原始问题的更好解决方案,而不是接受的答案。

    编辑,示例:

    public class MessageAreaModel {
       public MessageAreaModel() {
           Messages = new List<Message>();
       }
    
       public List<Message> Messages { get; private set; }
    
       public static void AddMessage(string text, MessageIcon icon, TempDatadictionary tempData) {
           AddMessage(new Message(icon, text), tempData);
       }
    
       public static void AddMessage(Message message, TempDataDictionary tempData) {
           var msgArea = GetAreaModelOrNew(tempData);
           msgArea.Messages.Add(message);
           tempData[TempDataKey] = msgArea;
       }
    
       private static MessageAreaModel GetAreaModelOrNew(TempDataDictionary tempData) {
           return tempData[TempDataKey] as MessageAreaModel ?? new MessageAreaModel();
       }
    

    然后可以使用上面的类从控制器使用的 UI 层添加消息。

    然后像这样添加一个 HtmlHelper 扩展:

    public static void RenderMessageArea(this HtmlHelper html) {
        html.RenderPartial("MessageArea", 
            (MessageAreaModel)html.ViewContext.TempData[MessageAreaModel.TempDataKey] ?? MessageAreaModel.Empty);
        html.ViewContext.TempData.Remove(MessageAreaModel.TempDataKey);
    }
    

    上面的代码还没有完全完成,我遗漏了各种花里胡哨的东西,但你得到了印象。

    【讨论】:

    • 在我的问题回复中添加了一个小代码示例。
    【解决方案3】:

    使int 可以为空:

    public ActionResult Tests(int? ID, string projectName){
        //...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多