MVC Theory - Action Responsibilities? (really long)

Last post 12-28-2007 11:12 AM by shinakuma. 16 replies.

Sort Posts:

  • MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 2:11 AM
    • Loading...
    • ChadThiele
    • Joined on 04-27-2003, 2:43 AM
    • Japan
    • Posts 266

    I'm porting my site, www.spelldamage.com, to the MVC framework. I've successfully gotten the master pages setup and ripped out all the runat="server" junk. At the basic level the site renders the same way it did before. I want to port it to the MVC framework for the RESTful architecture and the elegant URLs (and just thinking about routing has me drumming up knew ideas for the site).

    Anyway, the MVC architecture is all about separating responsibilities in your apps. So let me throw this scenario out there (hopefully someone here is familiar with World of Warcraft a bit).

    Let's say you play World of Warcraft, and you play a Mage class. My SpellDamage calculator is able to perform a lookup in the WoWArmory (an XML pull from the Blizzard website) to pull your character's information. I then store it in a database and perform spell damage calculations using the values pulled. The way it occurs now is obviously with post backs. You enter your character's name/realm into two text fields, and click the Get Data button (which fires the ArmoryPull_Click event). Inside the ArmoryPull_Click event I pull the data from the WoWArmory, store it in a DB, populate some text fields, and then fire the Calculate event. Inside the calculate event the values are pulled from the text fields and used in the calculations, then the results are displayed to the user. Here's a basic flowchart:

    Visitor Enters Name/Realm => WoWArmory Pull => Store in DB & Fill in Text Fields => Fire Calculate Event => Display Results

    Now, the results are essentially in two parts. The page showing the results also shows the Mage's information such as level, guild, battlegroup, etc... along with the actual spell damage results. Using the post back method, it's as simple as databinding some gridviews to show the spell damage results (and setting the text attribute on some literals). Using MVC, I'm a bit confused about which actions to write. I was read that MVC controllers generally should have 8 actions, and more than that should be very well thought out (the 8 are: Index, List, Show, Edit, New, Create, Update, and Delete; the last three don't have view associated with them).

    Index was easy, it simple shows the default UI with no calculations or lookups occurring. I'm stuck on the Show action (I know, I'm not limited to those 8 actions, but want to try to stick with conventions). I was pleasantly surprised at how easy the lookup part flowed while coding the Show action. A simple url like www.spelldamage.com/Mage/Name/Realm/US will first check if the character is in the DB. If it is, pull the data from there. If not, pull from the WoWArmory.That part works flawlessly. Earlier I asked how to pass more than one object to the View, and your advice to combine them into a viewController class worked great.

    However, as I'm working on this I'm wondering if I'm breaking the true meaning of an MVC framework. Do I perform all this work inside the Show action? Or should I be passing responsibility off to another action at some point? And, if I should be, what method would I use to move to the new action cleanly, RedirectToAction?

    Sorry for the long post, hopefully it made enough sense... :)

    Thanks in advance!


     

    Did I answer your question(s)? Phweew...
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 7:32 AM
    • Loading...
    • gunteman
    • Joined on 07-11-2007, 12:57 PM
    • Norrköping, Sweden
    • Posts 2,326

    It's nice to see that these kind of questions become more and more common in the ASP.NET community. The possibility to create good, separated architectures has always been there, even with web forms, but the MVC framework has made it popular.
     

    ChadThiele:

    Do I perform all this work inside the Show action?

    Yes! And no! Remember that the controller is essentially the glue the connects the model with the view, but you should strive not to perform any real work inside the controller. Many MVC samples can give the impression that the Model is only the data itself, but it's actually the data and everything about the data, such as calculations etc.

    In pseudoish code:

     Controller->Show
    {
      CharacterInfo info=Model.GetCharacterInfo();
      ViewData["CharacterInfo"]=info;
      RenderView("Show");
    }

    Model->GetCharacterInfo
    {
       CharacterInfo info=GetCharacterInfoFromDb();
       if (info==null)
       {
        info=GetCharacterInfoFromWoWArmory();
        if (info!=null)
        {
           StoreCharacterInfoInDb(info);
        }
       }
       return info;
    }


    -- "Mark As Answer" if my reply helped you --
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 7:48 AM
    • Loading...
    • ChadThiele
    • Joined on 04-27-2003, 2:43 AM
    • Japan
    • Posts 266

    Hmm... I wrote a class to model the spell damage results, that's in the models directory. I've got a model for the Mage class, it's in the models directory (actually, it's a LINQ to SQL file since I've got a DB table with the fields I want). I've got spells modeled (again, a LINQ to SQL file).

    I guess I wasn't clear in what I meant about "Do I perform all this work inside the Show action?". I have a DBHelper class (again, in the models folder) that handles the work of pulling a character from the DB, and a WoWArmory class that handles pulling the data from the WoWArmory. The controller isn't actually doing that work, it's making the calls to the appropriate models for help. I think I'm doing that right.

    What I was more concerned with, is should one action be showing the character info and be responsible for calling the calculations (since I've got a Calculator class, except I put that one in a Helpers folder)? Or should I be passing the call over to another action? I think I'm confusing myself!

    Thank you for the response!
     

    Did I answer your question(s)? Phweew...
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 8:47 AM
    Answer
    • Loading...
    • hhariri
    • Joined on 12-10-2007, 10:07 AM
    • Posts 42

    "What I was more concerned with, is should one action be showing the character info and be responsible for calling the calculations (since I've got a Calculator class, except I put that one in a Helpers folder)? Or should I be passing the call over to another action? I think I'm confusing myself!"

    Remember that actions  are "public" procedures. They are like RPC calls. Should someone be able to directly call "Calculations" in your app? And if so, what do they get as a result? Or should they call Show? And then calculations is part of what Show does (and should be part of the model)?

    Think of your actions as what glues the model to the view. So, if you have an action called Show, that's to display the information of your model. It should call whatever is required on your model to obtain the information so that the view can use it. Think always simplicity and separation of concerns. You don't want one action doing redirects to other actions (in general), because that's calling back into the controller. If you're doing that, then you're not encapsulating each action correctly.  THe same way your controller focuses on  a certain aspect of your model (for example CustomerController, InvoiceController), the actions should focus on the operations that can be performed with these. IF you're doing complicated things in the action and performing redirects, etc. then it might be that your model is slipping into your controller.

     

  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 8:55 AM
    • Loading...
    • ChadThiele
    • Joined on 04-27-2003, 2:43 AM
    • Japan
    • Posts 266

    Thank you, that's what I was thinking... just let the controller do the calls to the models, even if it's more than one call to multiple models (if that's what is needed to do get the data to hand over to the view). I appreciate the quick responses! 

    Did I answer your question(s)? Phweew...
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 2:10 PM
    • Loading...
    • shinakuma
    • Joined on 03-01-2003, 11:09 AM
    • Posts 92

    To nitpick a little, as far as I know, there are only 7 RESTful actions. Index and List are the same thing. From my experience, REST only works if you can map everything to CRUD. It's CRUD for the entities in your model. In my current app for example, we have a lot of workflow driven actions like approve, submit, reject etc that one action affects the state of multiple entities. I use REST as a guideline to map urls in a consistent fashion, but it doesn't work for everyting.

    On how much a controller action should do. For simple apps, it usually does quite a bit. But as the app gets more complex, I start moving towards a rich domain model, where 95% or more of the work are handled by the factories, repositories, service components etc. Controller actions become nothing more than a pass through layer that simply orchestrate.

  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 2:16 PM

    shinakuma:
    we have a lot of workflow driven actions like approve, submit, reject etc that one action affects the state of multiple entities.
     

    Couldn't you have an ActionController and create() workflow actions named "approve", "reject", etc? Even if there no concrete WorkflowAction model, the controller could do the translation from this "virtual" entity to whatever you need in the back end.

    Sometimes the necessity of creating a non-RESTful action can be a sign of a new entity struggling to be born (even if only virtually). This may not be your case but it's worth considering IMHO. 

    __________________________________________
    Sergio Pereira
    http://devlicio.us/blogs/sergio_pereira/
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 2:39 PM
    • Loading...
    • abombss
    • Joined on 06-27-2006, 4:13 PM
    • Chicago, IL
    • Posts 164

    sergiopereira:
    Sometimes the necessity of creating a non-RESTful action can be a sign of a new entity struggling to be born (even if only virtually). This may not be your case but it's worth considering IMHO. 
     

    Yes

    shinakuma:
    To nitpick a little, as far as I know, there are only 7 RESTful actions. Index and List are the same thing.

    Delete may be the 8th.  Rest did not include a delete, I talked about it in my SimplyRestfulRouting piece.  Basically its optional action before destroy to confirm or do some optional prompting if its needed.

    Adam Tybor -- abombss.com
    Filed under: ,
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 5:01 PM
    • Loading...
    • shinakuma
    • Joined on 03-01-2003, 11:09 AM
    • Posts 92

    sergiopereira:
    Sometimes the necessity of creating a non-RESTful action can be a sign of a new entity struggling to be born (even if only virtually).

    You are absolutely right, I could have say ApproveEntityController.Create() etc. But what does that really gain me other than successfully pigeonhole the world into a REST model? I'm not sure if I am completely sold on the if you go beyond the 7, it's a sign for new entity argument. There are times when RPC is just more natural and suitable. Especially if you buy into the whole domain driven approach. I often have methods on entities that go beyond CRUD. Why create extra entities just to say you are following REST.

  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 5:45 PM
    • Loading...
    • ChadThiele
    • Joined on 04-27-2003, 2:43 AM
    • Japan
    • Posts 266

    Excellent discussion, thank you. I'll sit back and watch as a lot of this is a bit of over my head.

    Did I answer your question(s)? Phweew...
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 6:11 PM

    shinakuma:
    I'm not sure if I am completely sold on the if you go beyond the 7, it's a sign for new entity argument
     

    It's not always a sign. But sometimes it is.

    shinakuma:
    But what does that really gain me other than successfully pigeonhole the world into a REST model?
    (snip)
    Why create extra entities just to say you are following REST.
     

     There's something to be said for adhering to a standard set of operations. For one, it simplifies a lot the code written to interact with your RESTful api, and notice that I'm no longer restricting your controller to a web-page application, I'm looking at a more general approach where your views now become XML or JSON (or something else) representations of your entities. And the standard set of urls become a standard way of retrieving and posting information regarding those entities.

    Also, remember that those extra entities will not make to your repository, they are IMHO lightweight helpers that keep your code organized (this is subjective) and consistent. Again, it totally possible that in some scenarios creating such entities do achieve exactly the opposite result. 

    This may be irrelevant for many applications and I would agree that introducing extra actions may be the easiest and the most adequate solution in some domains. 

    __________________________________________
    Sergio Pereira
    http://devlicio.us/blogs/sergio_pereira/
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 6:16 PM
    • Loading...
    • abombss
    • Joined on 06-27-2006, 4:13 PM
    • Chicago, IL
    • Posts 164

    shinakuma:
    I often have methods on entities that go beyond CRUD. Why create extra entities just to say you are following REST.
     

    So do I, but that doesn't mean they are exposed to the user through an interface.

    shinakuma:
    But what does that really gain me other than successfully pigeonhole the world into a REST model?

    I don't know if I would call it pigeonholing, it gives your application a REST api which is different from RPC.  I think mixing and matching only leads to confusion for consumers of the api, both people and machines.

     

    Adam Tybor -- abombss.com
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 7:37 PM
    • Loading...
    • ChadThiele
    • Joined on 04-27-2003, 2:43 AM
    • Japan
    • Posts 266

     I like the concept and can't wait to finally finish porting my site over to the MVC framework (and get my mind fully wrapped around the concept). Once that's done, I want to start building in some "discoverable" urls... I remember the first time I ran across a well-written MVC website, and I just played with the urls to see what I could get. Some ideas for my site would be:

    • www.spelldamage.com/Mage/Name/Realm/Continent/xml - For an xml based output instead of html
    • www.spelldamage.com/Top/Mage/ - shows the top mages for many categories; filterable (you can see the postback version online now at www.spelldamage.com/Mage/Stats.aspx)
      • /Top/Mage/Realm/[realmName] - filtered by realm with realmName set
      • /Top/Mage/Guild/[guildName] - filtered by guild with guildName set
      • of course */xml for an xml output as well

    These are some ideas I'd come up with simply by thinking of clean urls that MVC apps enable. I do have one question about this though. In the second bullet, I described the Top/Mage/Realm/[realmName], etc... those are basically filters for the statistics. How would you create urls that can support more than one filter at once? An ugly url would look something like: www.spelldamage.com/Top/Mage/Stats.aspx?filter1=this&filter2=that&filter3=those. Those filters can be applied in any order... I'm assuming this is more difficult in a MVC app?

    Thanks! 

    Did I answer your question(s)? Phweew...
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 7:48 PM

    ChadThiele:
    How would you create urls that can support more than one filter at once? An ugly url would look something like: www.spelldamage.com/Top/Mage/Stats.aspx?filter1=this&filter2=that&filter3=those. Those filters can be applied in any order... I'm assuming this is more difficult in a MVC app?
     

    If you have a Stats() action, you can declare it as:

    public void Stats(string filter1, int? filter2, DateTime? filter3, ... etc... ){  ... }

    Whatever parameters are given in the query string will be mapped to the method parameters with the same names. I thinks that's the way to go for optional parameters.  

    __________________________________________
    Sergio Pereira
    http://devlicio.us/blogs/sergio_pereira/
  • Re: MVC Theory - Action Responsibilities? (really long)

    12-26-2007, 8:17 PM