Avatar of Bardobrave
BardobraveFlag for Spain

asked on 

Passing values from controller to view and back

Hi experts.

I'm developing a web app through ASP.NET MVC.

I have several listings that calls controller methods over business elements to edit or erase them. Usually, when an element is erased, controller returns execution to the list (so
users can see their erased element is out of the list).

And here comes the question. I have several different listings that can show the same business elements (I mean, there are lists that filter in different ways or show different data of
same business elements) and I want to make controller know where to return when an element is erased (so if I call it from a determinated list I want the eraser controller to come back
to it when finished).

So I'm thinking in the best approach for this. I'd like to use some sort of "session variable" to store at any moment the last listing executed, this way any controller could determine when it has to call a listing wich one must be called.

However I'm not very used yet to work in ASP.NET MVC and the only way I'm seeing is to adding a new parameter to controller methods with this "last listing" value, passing it to views through ViewData and back to controllers into the forms or links that
calls them.

However I'm sure it should be an easier way.
Any suggestions?
.NET ProgrammingC#Web FrameworksASP.NET

Avatar of undefined
Last Comment
static-void
Avatar of Avodah
Avodah
Flag of United Kingdom of Great Britain and Northern Ireland image

Well I agree that passing a "last listing" value to the controller action is the way to go. If you take this approach I see no reason to use the ViewData dictionary to transfer information. Also within the controller action you will want to RedirectToRoute.

DaTribe
Avatar of Bardobrave
Bardobrave
Flag of Spain image

ASKER

I'm not sure of understand you.

I'll try to explain this more with an example:

There are a many to many relationship on the app between persons and courses, so one person can go to a course and one course can have many persons attending to it.

I have a model business class to manage this relationship, so I can edit or delete the attendance of one person to a course, and I can do it from within a list of the courses that one single person attends and whithin a list of the persons that attends to a single course.

So here I have two different listings (views called from different controller's methods) that can call to same methods to edit or erase the attendance of any person to any course.

Well... what I'm doing from each list controller's method is to load a ViewData with its method name, this value is get on the views, getting passed to detelete method when is called, this delete method calls to another view where confirmation is asked for, and once more the lastList info travels through ViewData to view and by form posting back to executing deletion method. This method erases the data from database and, on success, returns execution to the listing stated in the data he received from confirmation form.

Now this is working ok, but I'm sure that must be a simpler way to have "lastList" data accesible through layers without having to send it from controllers to views and back.
Avatar of static-void
static-void

I think actually what you want to do is set a return url on your action, does this sound correct?

So whats happening is that you have a couple of different places that link to say a delete function on your item. When you click delete you are redirected to some kind of confirmation page and when the action is confirmed you would like the page to return to the caller. Sound about right?

How i do this normally is to attach an argument to your call to the delete function for example site/controller/Delete?ReturnUrl=http://site/controller/<yourSourceAction> then inside your delete action return Redirect(ReturnUrl);

Make sense? The benefit of using a URL not a RedirectToAction is that you can preserve the arguments passed to your source page.
Avatar of Bardobrave
Bardobrave
Flag of Spain image

ASKER

Yeah... I considered that option by the way. However current project has as a condition that urls must be as clean as it's possible.

So I neglected params attached to the url through posting in favor of a parameter passed directly to the controller.

I even coded a unique method that creates forms to replace my current link creation. But when send those forms through GET I was redirected to mistaken controller (as I differ between show and post form controller through HttpPost directive), and when sent through POST the ?urlParam attached didn't liked me.

I'm still convinced that .NET MVC should have one global point to store determinate values between layers.
Avatar of static-void
static-void

One of the core principles of the MVC design pattern is that transactions should be stateless, Having said that i believe there are ways (not recommended) to maintain session as MVC is built on top of webforms essentially (its really just a design pattern with some helper methods).

However if your requirement is simply to keep the urls clean there is another way to do this behavior. Basically what you can do is create a seperate controller method for each entry point then use that to inject a value which specifies the return action into a hidden field on your view, when the view posts back you can examine the hidden field to redirect to the appropriate source action. Does this make sense?

Basically many HttpGet actions for the delete
A single View
A single post method
Avatar of static-void
static-void

oh another sneeky option would be to have the delete button perform a post to the delete form and post back the url of the source page when it does then reinject it to a hidden field do when the delete actually posts it can maintain that url. Its a bit of a hack tho
Avatar of Bardobrave
Bardobrave
Flag of Spain image

ASKER

> "However if your requirement is simply to keep the urls clean there is another way to do this behavior. Basically what you can do is create a seperate controller method for each entry point then use that to inject a value which specifies the return action into a hidden field on your view, when the view posts back you can examine the hidden field to redirect to the appropriate source action. Does this make sense?"

I'm not sure of seeing the difference between what I've done and this proposal, can you explain it further?
ASKER CERTIFIED SOLUTION
Avatar of static-void
static-void

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of Bardobrave
Bardobrave
Flag of Spain image

ASKER

Yeah... seems more elegant than my ViewData mode, not sure if really better, but at least more elegant.

I'll give it a try and see wich one performs better.

Thanks for your time.
Avatar of static-void
static-void

In general i think its best to not use ViewData, view models are a whole heap tidier, its kinda like strongly typing your objects.
.NET Programming
.NET Programming

The .NET Framework is not specific to any one programming language; rather, it includes a library of functions that allows developers to rapidly build applications. Several supported languages include C#, VB.NET, C++ or ASP.NET.

137K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo