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?
LVL 19
BardobraveAsked:
Who is Participating?
 
static-voidConnect With a Mentor Commented:
ok heres a sample

public ActionResult DeleteA()
        {
            return View("Delete", new EntityDeleteModel
            {
                ReturnAction = "A"
            });
        }

        public ActionResult DeleteB()
        {
            return View("Delete", new EntityDeleteModel
            {
                ReturnAction = "B"
            });
        }

        [HttpPost]
        public ActionResult Delete(EntityDeleteModel model)
        {
            //your delete code

            return RedirectToAction(model.ReturnAction);
        }

Then all you need to do is to make sure that your delete view maintains the state of the ReturnAction Property, you could do this by putting it in a hidden property.

Make more sense?
0
 
Richard LeeSoftware EnthusiastCommented:
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
0
 
BardobraveAuthor Commented:
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.
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
static-voidCommented:
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.
0
 
BardobraveAuthor Commented:
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.
0
 
static-voidCommented:
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
0
 
static-voidCommented:
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
0
 
BardobraveAuthor Commented:
> "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?
0
 
BardobraveAuthor Commented:
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.
0
 
static-voidCommented:
In general i think its best to not use ViewData, view models are a whole heap tidier, its kinda like strongly typing your objects.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.