-1

I have an ASP.Net Core application which needs passing of a model from one action to another.

These are models :

public class ClassA
{
    public string Id{get;set;}
    public string Name {get;set;}
    public StudentMarks Marks {get;set;}
}

public class StudentMarks
{
    public int Marks {get;set;}
    public string Grade {get;set;}
}

And the post Controller:

[HttpPost]
public ActionResult TestAction1(ClassA model)
{   
    return RedirectToAction("TestAction2", model);
}

public ActionResult TestAction2(ClassA model)
{


}

In TestAction 1 while debugging, i see that Id, Name and marks have value.

I am getting the value for Id in TestAction2 same as that in TestAction1. However the value of complex object Marks is not obtained in the TestAction2 action method.

What are my other options?

TheFallenOne
  • 1,598
  • 2
  • 23
  • 57

4 Answers4

2

You cannot redirect with a model. A redirect is simply an empty response with a 301, 302, or 307 status code, and a Location response header. That Location header contains the the URL you'd like to redirect the client to.

The client then must make a new request to that URL in the header, if it so chooses. Browsers will do this automatically, but not all HTTP clients will. Importantly, this new request is made via a GET, and GET requests do not have bodies. (Technically, the HTTP spec allows for it, but no browser or HTTP client out there actually supports that.)

It's unclear what your ultimate goal is here, but if you need to persist data temporarily between requests (such as a redirect), then you should serialize that data into a TempData key.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
2

You can use TempData to pass model data to a redirect request in Asp.Net Core In Asp.Net core, you cannot pass complex types in TempData. You can pass simple types like string, int, Guid etc. If you want to pass a complex type object via TempData, you have can serialize your object to a string and pass that. I have made a simple test application that will suffice to your needs:

Controller:

public ActionResult TestAction1(ClassA model)
{
    model.Id = "1";
    model.Name = "test";
    model.Marks.Grade = "A";
    model.Marks.Marks = 100;
    var complexObj = JsonConvert.SerializeObject(model);
    TempData["newuser"] = complexObj;
    return RedirectToAction("TestAction2");
}

public ActionResult TestAction2()
{
    if (TempData["newuser"] is string complexObj )
    {
        var getModel= JsonConvert.DeserializeObject<ClassA>(complexObj);
    }
    return View();
}

Model:

public class ClassA
{
    public ClassA()
    {
        Marks = new StudentMarks();
    }

    public string Id { get; set; }
    public string Name { get; set; }
    public StudentMarks Marks { get; set; }
}

public class StudentMarks
{
    public int Marks { get; set; }
    public string Grade { get; set; }
}

If you want to persist your TempData values for more requests you can use Peek and Keep functions. This answer can give more insight on these functions.

Rahul Sharma
  • 7,768
  • 2
  • 28
  • 54
0

I think you're getting model and routeValues mixed up. The overload of RedirectToAction that you're calling (takes a string and an object) expects a routeValues argument, not a model argument. https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.redirecttoaction?view=aspnetcore-2.2

TestAction1 is called via Post, but TestAction2 is called via Get. You need to work out a URL that will let you call TestAction2 the way you want (independently of the RedirectToAction in TestAction1). I'm guessing this will involve setting up a custom route. Once you have a URL that will let you call TestAction2 the way you want, you can specify the route values to form that URL in the RedirectToAction in TestAction1.

jefftrotman
  • 1,059
  • 7
  • 16
-1

I think the problem is that you shuold use:

return RedirectToAction("TestAction2", model);

(you did this without return)

Efraim Newman
  • 927
  • 6
  • 21