Passing Object in Redirecttoaction

Passing object in RedirectToAction

You can not pass classes to the redirected actions like that. Redirection is done by means of URL. Url is a string, so it can not contain classes (serializing objects to url is really out of logic here)

Instead, you could use TempData

TempData["searchJob"] = searchJob;
return RedirectToAction ...;

and in Action redirected

Entity.SearchJob = (Entity.SearchJob)TempData["searchJob"] ;

After executing of the code above, TempData will not contain searchJob anymore. TempData is generally used for single time reading.

But I do not like the way above. If I were in your place and wanted to search jobs by name, I would add route parameters like

RouteValueDictionary dict = new RouteValueDictionary();
dict.Add("searchJobName", searchJob.JobName);

and receive it to action via parameter

public ActionResult SearchJob(string searchJobName)
{
... do something with the name
}

This way, you get better user and HTTP friendly URL and from the Action point of view, it would get all the parameters it needs from outside. This is better for testing, maintenance, etc.

Passing an object in RedirectToAction

Yes you can get values using TempData on redirect.
Your method should looks like:

public ActionResult YourRedirectMethod()

{
TempData["myObject"]=r;
return RedirectToAction() ("Index", "Location");

}

and

public ActionResult Index()
{
LocationByAddressReply location=null;
if(TempData["myObject"]!=null)
{
location=(LocationByAddressReply)TempData["myObject"];
}
}

In this way you get values of your model that was previousely set on redirect method.

How can I use RedirectToAction to pass an object to a new Action in MVC 5

It is possible to pass a simple object to a GET method using

return RedirectToAction("ForexPaymentConfirmation", model);

However, internally this creates an ugly query string including all the names and values of your properties

../ForexPaymentConfirmation?somePropertyName=someValue&anotherPropertyName=AnotherValue.....

It will only work if your model contains properties which are value types (int, bool DateTime etc) or string. If any properties are complex objects or collections, binding will fail. In addition you could easily exceed the query string limit and throw and exception.

Its unclear why you need this pattern (as opposed to saving the model and then in the 'details' view having a 'delete' button' in case the user changes their mind), but you need to persist the model somewhere. You can use Session (but you should not use TempData), but its always better to persist it to some form of repository, for example to a database (could be another 'temporary' table) or serialize it to an xml file so that you can retrieve it in the GET method. Another option would be to store it in the permanent table but include a bit flag (say bool IsPending) that you could set when you 'Confirm', and in the case of 'Cancel', just delete the table row.

How to pass object as hidden parameter with RedirectToAction?

In your case instead of using RouteValueDictionary and passing model from querystring try TempData(because when we use RedirectToAction it will make a new http request and object routes will be shown in url so its not a good approach to display sensitive data in url).

Use TempData as shown :-

public ActionResult GetInfo(SomeModel entity)
{
----
TempData["entity"] = entity; //put it inside TempData here
return RedirectToAction("NewAction", "NewController");
}

public ActionResult NewAction()
{
SomeModel smodel = new SomeModel();
if(TempData["entity"] != null){
smodel = (SomeModel)TempData["entity"]; //retrieve TempData values here
}
-------
-------
}

The benefit of using TempData here is that it will retain its value for one redirect and moreover model will be privately transported to another controller action and once you read data from TempData its data will be disposed automatically and if you want to retain TempData value after reading it then use TempData.keep("entity").


OR

If your Views are in a same Controller then this a simple solution for your problem :

public ActionResult GetInfo(SomeModel entity)
{
----
return NewAction(entity);
}

public ActionResult NewAction(SomeModel smodel)
{
-------
-------
return View("NewAction",smodel)
}

As Correctly Commented by @Chips_100 so i m including it here :- The first solution will do a real redirect (302) which will update the URL in the users browser. The second solution will give the desired result while keeping the original URL in the address bar.

return RedirectToAction() not passing object

Thanks all for giving time on this issue.

As @Damian S described about complex object redirecting is notable advice for me.

However I was able to find simplest solution to this problem to use DataDictionary in C#.

I managed it with using TempData[] to store details in easiest way I guess because it is most Precise and trivial technique.

Using TempData[]

Storing record in TempData[] in AutoComplete_Search() controller-

TempData["Records"]= ledge;

Usage in ProductSearchList controller

List<ledgerModel> ledge= (List<ledgerModel>)TempData["Records"];

Solved my problem and headache of playing with objects methods to methods.!

How do I include a model with a RedirectToAction?

RedirectToAction returns a 302 response to the client browser and thus the browser will make a new GET request to the url in the location header value of the response came to the browser.

If you are trying to pass a simple lean-flat view model to the second action method, you can use this overload of the RedirectToAction method.

protected internal RedirectToRouteResult RedirectToAction(
string actionName,
string controllerName,
object routeValues
)

The RedirectToAction will convert the object passed(routeValues) to a query string and append that to the url(generated from the first 2 parameters we passed) and will embed the resulting url in the location header of the response.

Let's assume your view model is like this

public class StoreVm
{
public int StoreId { get; set; }
public string Name { get; set; }
public string Code { set; get; }
}

And you in your first action method, you can pass an object of this to the RedirectToAction method like this

var m = new Store { StoreId =101, Name = "Kroger", Code = "KRO"};
return RedirectToAction("Details","Store", m);

This code will send a 302 response to the browser with location header value as

Store/Details?StoreId=101&Name=Kroger&Code=KRO

Assuming your Details action method's parameter is of type StoreVm, the querystring param values will be properly mapped to the properties of the parameter.

public ActionResult Details(StoreVm model)
{
// model.Name & model.Id will have values mapped from the request querystring
// to do : Return something.
}

The above will work for passing small flat-lean view model. But if you want to pass a complex object, you should try to follow the PRG pattern.

PRG Pattern

PRG stands for POST - REDIRECT - GET. With this approach, you will issue a redirect response with a unique id in the querystring, using which the second GET action method can query the resource again and return something to the view.

int newStoreId=101;
return RedirectToAction("Details", "Store", new { storeId=newStoreId} );

This will create the url Store/Details?storeId=101
and in your Details GET action, using the storeId passed in, you will get/build the StoreVm object from somewhere (from a service or querying the database etc)

public ActionResult Details(string storeId)
{
// from the storeId value, get the entity/object/resource
var store = yourRepo.GetStore(storeId);
if(store!=null)
{
// Map the the view model
var storeVm = new StoreVm { Id=storeId, Name=store.Name,Code=store.Code};
return View(storeVm);
}
return View("StoreNotFound"); // view to render when we get invalid store id
}

TempData

Following the PRG pattern is a better solution to handle this use case. But if you don't want to do that and really want to pass some complex data across Stateless HTTP requests, you may use some temporary storage mechanism like TempData

TempData["NewCustomer"] = model;
return RedirectToAction("Index", "Users");

And read it in your GET Action method again.

public ActionResult Index()
{
var model=TempData["NewCustomer"] as Customer
return View(model);
}

TempData uses Session object behind the scene to store the data. But once the data is read the data is terminated.

Rachel has written a nice blog post explaining when to use TempData /ViewData. Worth to read.

Using 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 absolutely want to pass a complex type object via TempData, you have 2 options.

1) Serialize your object to a string and pass that.

Here is a sample using Json.NET to serialize the object to a string

var s = Newtonsoft.Json.JsonConvert.SerializeObject(createUserVm);
TempData["newuser"] = s;
return RedirectToAction("Index", "Users");

Now in your Index action method, read this value from the TempData and deserialize it to your CreateUserViewModel class object.

public IActionResult Index()
{
if (TempData["newuser"] is string s)
{
var newUser = JsonConvert.DeserializeObject<CreateUserViewModel>(s);
// use newUser object now as needed
}
// to do : return something
}

2) Set a dictionary of simple types to TempData

var d = new Dictionary<string, string>
{
["FullName"] = rvm.FullName,
["Email"] = rvm.Email;
};
TempData["MyModelDict"] = d;
return RedirectToAction("Index", "Users");

and read it later

public IActionResult Index()
{
if (TempData["MyModelDict"] is Dictionary<string,string> dict)
{
var name = dict["Name"];
var email = dict["Email"];
}
// to do : return something
}

Can we pass model as a parameter in RedirectToAction?

Using TempData

Represents a set of data that persists only from one request to the
next

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

Alternative way
Pass the data using Query string

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

This will generate a GET Request like Student/GetStudent?Name=John & Class=clsz

Ensure the method you want to redirect to is decorated with [HttpGet] as
the above RedirectToAction will issue GET Request with http status
code 302 Found (common way of performing url redirect)

Passing a model object to a RedirectToAction without polluting the URL?

Sounds like a solution for TempData!

[HttpPost]
public ActionResult Index(ContactModel model)
{
if (ModelState.IsValid)
{
// Send email using Model information.
TempData["model"] = model;
return RedirectToAction("Gracias");
}

return View(model);
}

public ActionResult Gracias()
{
ContactModel model = (ContactModel)TempData["model"];
return View(model);
}


Related Topics



Leave a reply



Submit