2017-07-27 3 views
1

Ich habe eine Situation, die ich nicht verstehe. Ich entwickle eine kleine Webanwendung, die Poolbillard-Spielprozesse simuliert. Ich zwei Aktionen haben, erste ist eine Aktion, verantwortlich für die Eingabe von Benutzer zu sammeln, berechnet zweiten notwendigen Daten:ASP.NET MVC 5 - RedirectToAction mit benutzerdefinierten Typ übergibt leeres Objekt

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

Und UserInputViewModel sieht wie folgt aus:

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

Wie Sie sehen, ich bin vorbei benutzerdefinierter Typ (Viewmodel) von UserInput() Aktion zu Play() Aktion. Die inputParameter Variable in der UserInput() Aktion hat die richtigen Werte, aber wenn das Programm zur Play() Aktion geht, ist es null oder leer (mit Standardwerten der im Objekt enthaltenen Typen).

Wie ich verstehe Standard ASP.NET-Modellbindung überprüft, welche Eigenschaften benutzerdefinierte Objekt benötigt und sucht sie in HTTP-Header vom Client gesendet. Ich halte mich an das Standard-ASP.NET-Validierungsschema, weshalb ich nicht verstehe, warum meine App ein Problem mit der Übersetzung von HTTP-Headerparametern in ein .NET-Objekt hat. Wenn ich benutzerdefinierten Typ durch vordefinierten Typ (d. H. Zeichenfolge) ersetzen, sollte alles sein.

Meine Frage ist: Warum ASP kann nicht richtige Objekt von HTTP-Header in dieser Situation generieren?

+0

konnte Ja, tat ich. Das Ergebnis war das gleiche. – helvy91

+1

Ich glaube nicht, dass Sie solche Objekte passieren können –

+0

@ helvy91 Entschuldigung, ich habe nicht gesehen, es ist Aktion. Sie können das Objekt nicht an eine andere Aktion übergeben. Die Lösung wird entweder in session/tempdata/db gespeichert und in einem anderen Abschnitt abgerufen. – Parwej

Antwort

0

Vielleicht etwas versuchen, wie diese

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

Auch Sie können nicht nur die Berechnungen, die in Play innerhalb der UserInput ActionResult fertig sind und dann wieder genau das, was jemals Ansicht, die Sie in den Play ActionResult zurückkehren würden?

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

Verwendung:

return Play(inputParameters); 

statt

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

- Bearbeiten

Gut zu wissen, dass Sie nicht Objekt passieren kann Methode zu bekommen, und es ist nicht möglich um POST zu verwenden, entweder weil RedirectToAction 302 an den Browser zurückgibt, was bedeutet, dass der Browser eine GET-Anfrage macht!

Die Lösung, die ich oben ‚geschrieben würde es tun, aber es ist Hacky und nicht zu empfehlen :)

0

Danke Jungs für Ihre Hilfe, aber ich habe gerade die am meisten befriedigende Antwort ich :). Ich habe RouteValueDictionary() verwendet. Userinput() -Aktion sollte wie folgt aussehen:

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

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

Wenn Sie den Umleitungsbefehl ausgegeben werden soll und die Daten übergeben Sie TempData verwenden. Dieser Beitrag bricht es besser als ich ohne Plagiat Passing object in RedirectToAction

Verwandte Themen