我们可以将模型作为参数传递给RedirectToAction吗?

79

我想知道,有没有一种方法可以将Model作为参数传递给RedirectToAction

例如:

public class Student{
    public int Id{get;set;}
    public string Name{get;set;}
}

控制器

public class StudentController : Controller
{
    public ActionResult FillStudent()
    {
        return View();
    }
    [HttpPost]
    public ActionResult FillStudent(Student student1)
    {
        return RedirectToAction("GetStudent","Student",new{student=student1});
    }
    public ActionResult GetStudent(Student student)
    {
        return View();
    }
}

我的问题 - 我能在RedirectToAction中传递学生模型吗?


1
当然,这是一个有效的调用。它没有被路由吗? - Andrei V
1
我已经尝试过了,但是没有找到模型值。 - Amit
由于路由字典处理对象,尝试将“GetStudent”操作更改为接受一个“object”,并在内部将其转换为“Student”。另一个选项是在从“FillStudent”传递时使用JSON进行序列化。 - Andrei V
@AndreiV 我正在FillStudent函数中获取模型值。 - Amit
看起来这是一个基本操作,应该由 ASP.NET MVC 支持,但仍然不可能。我不得不从模型中提取值创建路由值对象,通过从多个参数进行提取,在 GET 处理程序中重新插入它们到我的模型中。 - AaronHolland
请查看:http://www.codingfusion.com/Post/Passing-Data-with-RedirectToAction--in-NET-MVC - undefined
6个回答

88

使用 TempData

表示一组仅在当前请求和下一个请求之间保持的数据

[HttpPost]
public ActionResult FillStudent(Student student1)
{
    TempData["student"]= new Student();
    return RedirectToAction("GetStudent","Student");
}

[HttpGet]
public ActionResult GetStudent(Student passedStd)
{
    Student std=(Student)TempData["student"];
    return View();
}

另一种方式 使用查询字符串传递数据

return RedirectToAction("GetStudent","Student", new {Name="John", Class="clsz"});

这将生成一个GET请求,如Student/GetStudent?Name=John & Class=clsz

确保您想要重定向的方法已经装饰了[HttpGet],因为上述RedirectToAction将发出带有HTTP状态代码302 Found的GET请求(执行URL重定向的常见方式)


12
我不想使用 TempData。我知道我们可以用 TempData 实现该功能。但我的问题与此不同。 - Amit
2
我也知道方法2,但我的问题不同。我能实现我的问题吗?是/否 - Amit
3
@AmitAgrawal,简单的“不行”。请查看在ASP.NET MVC应用程序中传递数据 - Murali Murugesan
4
这是一个旧的帖子,但我想指出1)使用TempData时,GetStudent操作不需要有参数;2)必须注意,如果这是为了实现PRG模式,它仅部分解决了问题。在第二次刷新视图时,TempData会为空(按设计!)。 - Sudhanshu Mishra
2
不要使用TempData。假设您有一个在Azure中运行的应用程序,您将最终拥有许多应用程序实例。如果禁用ARR亲和性,则第一个方法由一个实例调用以保存TempData中的数据,第二个实例将接收第二个请求。您将为弄清楚发生了什么而苦恼。因此,请远离状态解决方案,例如TempData或会话。 - akd
显示剩余2条评论

45

只需调用该操作,无需使用redirect to actionnew关键字来创建模型。

 [HttpPost]
    public ActionResult FillStudent(Student student1)
    {
        return GetStudent(student1); //this will also work
    }
    public ActionResult GetStudent(Student student)
    {
        return View(student);
    }

@AmitAgrawal,它将调用您的GetStudent()操作。 - Vinay Pratap Singh Bhadauria
9
GetStudent这个操作需要返回一个名为"GetStudent"的视图,其中包含名为student的数据模型 - 对我而言起作用的是 - return View("GetStudent", student) - hotfusion
2
这个答案对我没用(页面从未改变),但是hotfusions的评论有效。 - Ravendarksky
17
请注意,尽管这个方法可以使用(需要按照 @hotfusion 提出的更改),但这仍然不符合 PRG 模式。如果用户按下 F5 键,将会再次重复原始请求! - Sudhanshu Mishra
3
这将显示原始请求的URL。这可能不是所需的。 - John Lord
显示剩余2条评论

18

是的,您可以使用所示的模型传递它。

return RedirectToAction("GetStudent", "Student", student1 );

假设student1Student类的一个实例,则以下url将会生成(假设您正在使用默认路由,并且student1的值为ID=4Name="Amit"

.../Student/GetStudent/4?Name=Amit

RedirectToAction()方法在内部使用每个模型属性的.ToString()值构建一个RouteValueDictionary。但是,只有当模型中的所有属性都是简单属性时绑定才会起作用;如果任何属性是复杂对象或集合,则绑定将失败,因为该方法不使用递归。例如,如果Student包含一个名为List<string> Subjects的属性,则该属性将导致查询字符串值为:

....&Subjects=System.Collections.Generic.List'1[System.String]

并且绑定将失败,该属性将为null


谢谢您指出使用RedirectToAction时不要在Model中包含复杂对象、列表或集合。这就是解决我的问题的方法。 - Mario Levesque
我赞同这个观点。感谢您提供有关复杂对象的说明。我们试图拒绝一个巨大的模型(约200个字段),其中一个字段是List<int>()。当重定向时,我们遇到了大约20个字符串转换为整数错误,并且它甚至没有显示错误源是什么,这并没有帮助我们。 - John Lord

0
  [HttpPost]
    public async Task<ActionResult> Capture(string imageData)
    {                      
        if (imageData.Length > 0)
        {
            var imageBytes = Convert.FromBase64String(imageData);
            using (var stream = new MemoryStream(imageBytes))
            {
                var result = (JsonResult)await IdentifyFace(stream);
                var serializer = new JavaScriptSerializer();
                var faceRecon = serializer.Deserialize<FaceIdentity>(serializer.Serialize(result.Data));

                if (faceRecon.Success) return RedirectToAction("Index", "Auth", new { param = serializer.Serialize(result.Data) });

            }
        }

        return Json(new { success = false, responseText = "Der opstod en fejl - Intet billede, manglede data." }, JsonRequestBehavior.AllowGet);

    }


// GET: Auth
    [HttpGet]
    public ActionResult Index(string param)
    {
        var serializer = new JavaScriptSerializer();
        var faceRecon = serializer.Deserialize<FaceIdentity>(param);


        return View(faceRecon);
    }

请问您能展示一下在视图中如何使用faceRecon吗? - justitan

0
[NonAction]
private ActionResult CRUD(someModel entity)
{
        try
        {
            //you business logic here
     return View(entity);
       }                                
         catch (Exception exp)
         {
             ModelState.AddModelError("", exp.InnerException.Message);
             Response.StatusCode = 350;
             return someerrohandilingactionresult(entity, actionType);
         }
         //Retrun appropriate message or redirect to proper action
      return RedirectToAction("Index");   
}

因为你应该提供错误处理程序。但是我不确定它应该如何解决问题。 - John Lord

-3

我发现了类似这样的东西,有助于摆脱硬编码的TempData标记

public class AccountController : Controller
{
    [HttpGet]
    public ActionResult Index(IndexPresentationModel model)
    {
        return View(model);
    }

    [HttpPost]
    public ActionResult Save(SaveUpdateModel model)
    {
        // save the information

        var presentationModel = new IndexPresentationModel();

        presentationModel.Message = model.Message;

        return this.RedirectToAction(c => c.Index(presentationModel));
    }
}

1
这个方法从哪里来的?“this.RedirectToAction”。 - Oğuzhan Topçu
好的,一个控制器有那个方法 :) - DiSaSteR
1
我找不到一个接受lambda表达式的RedirectToAction的重载。你确定这个重载在System.Web.Mvc中而不是你正在使用的第三方库或扩展方法吗? - R. Schreurs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接