ASP.NET MVC 5 - 具有自定义类型的RedirectToAction传递空对象

时间:2017-07-27 15:26:25

标签: c# asp.net redirecttoaction custom-type

我有一种我不明白的情况。我正在开发一个小型Web应用程序,它模拟了poolbillard游戏过程。我有两个动作,第一个是负责收集用户输入的动作,第二个是计算必要的数据:

[HttpPost]
public ActionResult UserInput(UserInputViewModel inputParameters)
{
    if (!ModelState.IsValid)
    {
        return View();
    }

    return RedirectToAction("Play", new { inputParameters });
}

public ActionResult Play(UserInputViewModel playParameters)
{
    PocketName resultPocketName;
    IEnumerable<Point> crossPoints;

    PoolTable poolTable = new PoolTable((int)playParameters.Width, (int)playParameters.Height, (int)playParameters.BallPointX, (int)playParameters.BallPointY, playParameters.VectorX, playParameters.VectorY);
    resultPocketName = poolTable.Play();
    crossPoints = poolTable.CrossPoints;

    ViewBag.ResultPocketName = resultPocketName;
    ViewBag.CrossPoints = crossPoints;

    return View();
}

UserInputViewModel如下所示:

public class UserInputViewModel
{
    [Required(ErrorMessage = "Please specify width.")]
    [ProperWidth(ErrorMessage = "Width must be an even number.")]
    [Range(300, 700)]
    public uint Width { get; set; }

    [Required(ErrorMessage = "Please specify height.")]
    [Range(150, 500)]
    public uint Height { get; set; }

    [Required(ErrorMessage = "Please specify ball position X.")]
    [Display(Name = "Ball position X")]
    [ProperBallPosition("Width", ErrorMessage = "Ball position X cannot be equal or higher than pool table width.")]
    public uint BallPointX { get; set; }

    [Required(ErrorMessage = "Please specify ball position Y.")]
    [Display(Name = "Ball position Y")]
    [ProperBallPosition("Height", ErrorMessage = "Ball position Y cannot be equal or higher than pool table width.")]
    public uint BallPointY { get; set; }

    [Required(ErrorMessage = "Please specify vector X.")]
    [Display(Name = "Vector X value")]
    [Range(-1000, 1000)]
    public int VectorX { get; set; }

    [Required(ErrorMessage = "Please specify vector Y.")]
    [Display(Name = "Vector Y value")]
    [Range(-1000, 1000)]
    public int VectorY { get; set; }
}

如您所见,我将自定义类型(viewmodel)从UserInput()操作传递到Play()操作。 inputParameter操作中的UserInput()变量具有正确的值,但是当程序进入Play()操作时,它为null或为空(对象中包含类型的默认值)。

据我所知,默认的ASP.NET模型绑定会验证自定义对象需要哪些属性,并在客户端发送的http标头中搜索它们。我坚持使用标准的ASP.NET验证模式,因此我不明白为什么我的应用程序在将http标头参数转换为.NET对象时遇到问题。当我用预定义类型(即字符串)替换自定义类型时,一切都应该是。

我的问题是:为什么ASP在这种情况下无法从http头生成适当的对象?

4 个答案:

答案 0 :(得分:0)

也许尝试这样的事情

return RedirectToAction("Play", "ControllerName", inputParameters);

你也可以不只是在Play内的UserInput ActionResult进行计算,然后只返回Play ActionResult中要返回的视图吗?

[HttpPost]
public ActionResult UserInput(UserInputViewModel inputParameters)
{
    if (!ModelState.IsValid)return View();

    PocketName resultPocketName;
    IEnumerable<Point> crossPoints;

    PoolTable poolTable = new PoolTable((int)inputParameters.Width, (int)inputParameters.Height, (int)inputParameters.BallPointX, (int)inputParameters.BallPointY, inputParameters.VectorX, inputParameters.VectorY);
    resultPocketName = poolTable.Play();
    crossPoints = poolTable.CrossPoints;

    ViewBag.ResultPocketName = resultPocketName;
    ViewBag.CrossPoints = crossPoints;

    return View("ViewName", whatEverModelYouNeed);
}

答案 1 :(得分:0)

使用:

return Play(inputParameters);

而不是

return RedirectToAction("Play", new { inputParameters });

- 编辑

很高兴知道你不能将对象传递给GET方法,并且也不可能使用POST,因为RedirectToAction向浏览器返回302,这意味着浏览器将发出GET请求!

我上面写的解决方案'我会做伎俩,但它很黑,不推荐:)

答案 2 :(得分:0)

谢谢你们的帮助,但我自己找到了最令人满意的答案:)。我使用了RouteValueDictionary()。 UserInput()动作应如下所示:

[HttpPost]
public ActionResult UserInput(UserInputViewModel inputParameters)
{
    if (!ModelState.IsValid)
    {
        return View();
    }

    return RedirectToAction("Play", "Home" , new RouteValueDictionary(inputParameters));
}

答案 3 :(得分:0)

如果要发出重定向命令并传递数据,您将使用TempData。这篇文章比没有抄袭Passing object in RedirectToAction

更好地打破了它