0

In my MVC4 web application I have both a GlobalController which all controllers will inherit from so I have a single place that has all the common code that must run on each and every page. I also have a _MasterLayout.cshtml page that all my views use as there layout page. So far I have been able to put code in my GlobalController to fill ViewBag data with stuff to propagate dynamic data to the _MasterLayout.cshtml file.

I now need to figure out how to place buttons and/or links that people can click on to do things like register, login, logout, etc. As you could imagine these functions could be used on any page in my site so I would like the code for those to live in my GlobalController. I have already created public classes inside the GlobalController to do the actions I want but what I can not figure out is how to wire up a click on either a link or button placed on the _MasterLayout.cshtml file to the GlobalController public class?

I DO NOT WANT TO RENDER NEW VIEWS!

  • Please post some code. – mayabelle Oct 18 '13 at 20:19
  • 1
    Register, Login, Logout actions should be in their own `AccountController`. Then in your header, or where ever, you have a link to the logout action. /Account/Logout or Account/Login – Stephen Gilboy Oct 18 '13 at 20:19
  • Also, I would recommend storing dynamic data on a view model rather than in ViewBag when possible. See here: http://stackoverflow.com/questions/13779294/viewmodels-or-viewbag – mayabelle Oct 18 '13 at 20:19
  • Yeah, you wouldn't have calls to the base controller. Your calls should be to the real controllers that inherit the base one. – A Khudairy Oct 18 '13 at 20:22
  • @mayabelle What code in particular are you looking for? The `GlobalController` just has `public static void Name() { code to do action here }` in it. I understand about having things in the view model rather then ViewBag and I do have a view model used for the language settings. @Stephen I don't want to load a hole new page for them when the do most of these actions. If the user logs out I don't want to send him to a special logout page, I just want to log him out and leave him on the same page. –  Oct 18 '13 at 20:44
  • @AKhudairy If I move the code from the base controller to the "real" controllers then that defeats the whole point of OOP. Why would I want to re-type the code to log someone out in ever single controller where I have the potential for hundreds of controllers. Not only does that greatly increases the chance of a type-o but if I ever have to make a change to that code it will have to be done in hundreds of places. Having the code in the Base controller makes it one place to write, one place to manage. –  Oct 18 '13 at 20:46
  • You got me in the wrong way. For example if you want to call the logout would you type this in the browser address (/Global/Logout), I would guess not, you would be typing (/Account/Logout). Now I don't care where the code is, am talking about how would you access the action. – A Khudairy Oct 18 '13 at 20:52
  • @AKhudairy I don't want them to have to go to a special page just to log out. Take google.com for example, if your loged in and at google.com and you hit logout your not taken to another page your simply loged out and your still on google.com. same for maps.google.com. Now yes some google.com pages like gmail will log you out and redirect you somewhere so you still not in your email box but I don't want to redirect to load special pages. –  Oct 18 '13 at 20:55
  • The relation between the client side (view) and the server side happens by the view calling an action on a controller. Now if you have helper methods on your base controllers, those can't be called right away, the access point need to be an action method. – A Khudairy Oct 18 '13 at 20:56
  • @AKhudairy So what your saying is it is impossible to just perform an action on a click without having to recode the action in ever single controller inside MVC? I either have to code a logout function in every single controller, breaking the whole point of OOP, or load a special view just to log a user out? –  Oct 18 '13 at 20:59
  • You can define an action in the base controller, and this way it will be available in all controllers that inherit from it. But it should be an action, not a static void function. – A Khudairy Oct 18 '13 at 21:02
  • But this still presents the problem that a whole new view must be rendered out to the client. I will state it one more time I DO NOT WANT TO REND A NEW PAGE –  Oct 18 '13 at 22:11
  • @MatthewVerstraete well if you are not using ajax then there will be a round trip to the server of course. Regarding rendering a different page, well you can render the same view(page) again that the user was on. .... and you don't need to use CAPS :) – A Khudairy Oct 19 '13 at 23:02
  • @AKhudairy I understand with out AJAX there would be a full round trip and I am fine with that for now. I plan on adding in AJAX a bit down the road. How would I render the same view back to the user with the same URL displayed? –  Oct 21 '13 at 01:32
  • Oh. Well if you have multiple places that the user can access the logout from ... then you can check Request.UrlReferrer to get the originating link, and redirect the user back to it. You may need to write some custom code to get the controller and action name and do a redirect then, am not sure if a simple response.redirect would work for you, but try it out also, – A Khudairy Oct 21 '13 at 11:18

1 Answers1

1

Your BaseController should only contain methods that controllers need to know how to do, like finding Views hence the View() method. Then every other controller should take care of their own jobs. So for Login, Logout, Register those all deal with account management. So you would create an account controller and put those actions inside

public class AccountController: BaseController {
    public ActionResult Logout() {
        /* logout user */
     }
    .....
 }

And then in your views you would just create an action link to to what you need.

<div id="header">
    @Html.ActionLink("Log me out", "Logout", "Account");
</div>

or you can call it directly

<div id="header">
    <a href="/Account/Logout">Log me out</a>
</div>

Hope this helps get you on the right track. I would also suggest going through the Music Store Tutorial for a better idea of working with MVC.

Stephen Gilboy
  • 5,572
  • 2
  • 30
  • 36
  • My understanding is an ActionResult must return a view, which is not want I want to do. I do not want to change pages when, say, the user logs out. I just want to run the logout command and let the user stay on the same page. –  Oct 18 '13 at 20:51
  • you can make it an ajax call. But am not sure if that would work with logout in particular, because my understanding is the authentication cookie needs to be deleted. Am not sure, you try it out. – A Khudairy Oct 18 '13 at 21:05
  • My understanding is, too, that AJAX can not work to log people out and I rather not start messing with AJAX at this point. –  Oct 18 '13 at 22:15