【问题标题】:ASP.NET MVC 5 - RedirectToAction with custom type passes empty object [duplicate]ASP.NET MVC 5 - 具有自定义类型的 RedirectToAction 传递空对象 [重复]
【发布时间】:2017-07-27 15:26:25
【问题描述】:

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

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

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

public ActionResult Play(UserInputViewModel playParameters)
{  
    PoolTableConfig config = CreatePoolTableConfig(playParameters);
    PoolTable poolTable = new PoolTable(config);
    PocketName resultPocketName = poolTable.Play();
    IEnumerable<Point> crossPoints = poolTable.CrossPoints;

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

    return View();
}

private PoolTableConfig CreateConfig(UserInputViewModel input)
{
    return new PoolTableConfig()
    {
       Width = input.Width,
       Height = input.Height,
       BallPointX = input.BallPointX,
       BallPointY = input.BallPointY,
       VectorX = input.VectorX,
       VectorY = input.VectorY
    };
}

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; }
}

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

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

我的问题是:为什么在这种情况下 ASP 不能从 http 标头生成正确的对象?

【问题讨论】:

  • 是的,我做到了。结果是一样的。
  • 我不认为你可以传递这样的对象
  • @helvy91 抱歉,我没有看到它正在采取行动。您不能将对象传递给另一个动作。所以解决方案要么保留在 session/tempdata/db 中,然后将其检索到另一个部分。

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


【解决方案1】:

也许可以试试这样的

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);
}

【讨论】:

    【解决方案2】:

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

    [HttpPost]
    public ActionResult UserInput(UserInputViewModel inputParameters)
    {
        if (!ModelState.IsValid)
        {
            return View();
        }
    
        return RedirectToAction("Play", "Home" , new RouteValueDictionary(inputParameters));
    }
    

    【讨论】:

      【解决方案3】:

      用途:

      return Play(inputParameters);
      

      而不是

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

      -- 编辑

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

      我上面写的解决方案可以解决问题,但它很老套,不推荐:)

      【讨论】:

        【解决方案4】:

        如果您想发出重定向命令并传递数据,您将使用 TempData。这篇文章比我在没有抄袭的情况下更好地分解它Passing object in RedirectToAction

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-12-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-24
          • 1970-01-01
          相关资源
          最近更新 更多