How about a very complex page which need many "MVC modules/parts" ?

Rate It (4)

Last post 01-13-2008 6:38 PM by mave99a. 29 replies.

Sort Posts:

  • How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 6:36 AM
    • Loading...
    • mave99a
    • Joined on 12-19-2007, 6:28 AM
    • Posts 8

    How about a very complex page which is composited by many different modules? e.g. a MSN home page alike web page, it need to display latest news, latest weather forecast, latest blog, forum updates, ...

    For each module, it's pretty clean to make it a full "MVC" cycle, but if we mix multiple M together, mix multiple V  together and make it one MVC cycle, it not that neat.  Any good idea on design web sites like this?

     
    --

    Some similar idea is, a master page could contain multiple place holders for different piece of contents, it's clean if we handle each part of them in a MVC cycle, but how to do it in current ASP.NET MVC?

     

     


     

  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 9:42 AM
    • Loading...
    • rjcox
    • Joined on 12-19-2007, 2:14 PM
    • Basingstoke, UK
    • Posts 1,328

    Sounds like you want "MVC for Web Parts" where the rendering of the overall page, and separately the parts goes through Controller + Model → View. 

    However web parts are closer to user controls than pages in their own right, and there is a lot of provider support associated with their use, so I'm not sure that MVC CTP #1 is a viaiable starting point for this.

    However MVC view user controls could be a starting point (seem to be ASP.NET User Controls + Html, Url etc. helpers plus access to ViewData).

    Richard
  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 1:29 PM
    • Loading...
    • abombss
    • Joined on 06-27-2006, 4:13 PM
    • Chicago, IL
    • Posts 164

     This has always been a small paint point for me and MVC web frameworks in general.

    Coming from the Monorail world I have solved this in the past by using ViewComponents very similar ot UserControls.

    Lets call my controller/view Dashboard/Index.  My Index view page would mostly delegate to usercontrols passing ViewData that I set in my controller.  Monorail has the concept of a dynamic action, meaning I can decorate my controllers with actions from other places without actually writing methods on my controller. So my options now become.

    1. Have UserControls provide actions on the controller.  This gets a little crazy with naming collisions in large apps.
    2. Create full blown controllers for the logic of your user controls and you would have the framework partially render them.  Anything they had to do would callback to their dedicated controller.
    3. Add actions to your controller to handle everything with AJAX.  The UserController would call actions on your controller that would have to be there.

    Option 1 is confusing, it would require a little plumbing, and I am not totally sold on it.

    Option 2 I have personally always liked option 2 the best, the problem is now my UserControllers need to be aware of my application to do anything involving persistence, security, etc.  Check this thread, I have a late response on how I would handle user controls without code behind.

    Option 3 Don't know why, but I just don't like option 3.  Seems like too much client side setup with script.  

    Following Option 2, if I wanted some really reusable controls, I think I would just make my usercontrol's controller virtual and use a template method approach for creating protected methods that the end users can override to do what they need.  Now I just drop in my user control, I tell it where its controller is and I am done.

    I am interested to see what MS recommends for third party components.  I hope to God it does not involve code behind. 

    Adam Tybor -- abombss.com
    Filed under: , ,
  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 2:01 PM
    • Loading...
    • robconery
    • Joined on 02-23-2005, 10:16 PM
    • Posts 174
    • AspNetTeam

    You'd want to use UserControls (similar to Rails partials) that you can Render using RenderUserControl(); In terms of where the logic resides - I always tell people to create Services that do this (similar, in a way, to Rail's plugins).

    In Rails if you want to have a certain bit of functionality - like GoogleMaps or something - you download a Plugin and then "strap it" to the ApplicationController (or whichever controller you're using it in). In a sense what you're doing is extendin the controller by doing this.

    You can use this same concept in C#/MVC by using a "Service" - an encapsulated bit of logic that does something specific, and is "horizontal" to your application (meaning it can be used everywhere). So if you wanted to get NYSE quotes, you could by 1) creating a NYSEService class (or call it what makes sense to you) that handles the logic and 2)Create a UserControl that exposes it.

    I did this with the new SubSonic forums (not release yet) because I needed Akismet (for spam) and CSharpFormat for posting. You can put this stuff in your project, or keep it in a DLL externally.

  • Re: How about a very complex page which need many "MVC modules/parts" ?

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

    robconery:
    I always tell people to create Services that do this
     Yes

    robconery:
    then "strap it" to the ApplicationController

    When did C# get mixins?

    I think the problem comes when you have portal like pages where you want to drop in functionality in some type of portlet.  You can't add methods on your controller for every scenario.  What happens when my usercontrol has some ajax capabilities, what controller/action is it calling to?  What happens when my usercontrol wants to persist perferences or options?

     

     

     

    Adam Tybor -- abombss.com
  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 5:25 PM
    • Loading...
    • mave99a
    • Joined on 12-19-2007, 6:28 AM
    • Posts 8

     Thanks Abombss, Rob.

     Yes, this is a general problem...so I am wondering if ASP.NET will have some neat solution.

      As my understanding partials in RoR is just a piece of presentation code (should belongs to View), so actually I had same problem when I played on RoR before. (though it's possible to put some M&C code inside partial, it's ugly)  As you mentioned we can archive the same goal with RenderUserControl() in ASP.NET.

      I think the key problem is not in the view part, it's inside M & C.  A dashboard web page could pull all kind of data in the database, if we mix all those inside the M&C, it will be a mess.  Yes, we can put those modulized logic into "services", we can even encapsulate them into different classes / assemblies / ..., however we need a place to put them together...then we may get a messed up "action". Image a real complex application, many actions may contain similar codes though those are just simple calls to some encapsulated services.

      e.g.

        public class BigWebController : Controller {

          [ControllerAction]

         public void Index()

         {

              LatestNewsService latestNews = new LatestNewsService();

              StockQuotoService stock = new StockQutoService();

              ...  

             // we at least need to create and call those services somewhere, right?


             RenderView(...);

         }

         public void MyCustomizedDashboard()

         {

             ...

             // we may have similar code here, right?
      

             RenderView("...")
     

         }
     

        }

    For the views, we can use user control, or simple "include" some aspx files which render partial content (is the include a good idea? I am very new to asp.net, but I did quite a lot such include in Java web develop)  Since we have prepared all required data in M, C,  we will get whatever we want in the V.

    What if we need to add some "component" to a web page?  Oh, besides change the view aspx files, we have to change the controller code, even those component are remain exactly same in another page!  

    This is not a neat enough idea sounds to me, because we not treat it as "component", we separated something which could done perfectly in a full M-V-C cycle into  "service" and "partial" .

    If we need to consider the cache, the logic could be much complex: we may have a bunch of condition code somewhere to get "Model" from cache, but how about the view? if Model can be get from cache, why we render view again? would it better to directly pull the result from cache?

     
    -----

    What I did before is: (I didn't use asp.net before, so write some Java related stuff, but I believe it similar)

    (1) Keep MVC stuff simple and only do one task in each MVC cycle. (It's not conflict to implement stuff as service)

    (2) Use another container page to "include" each part of the "components", this could be a simple jsp page or another "MVC" cycle.

    I think my solution have those advatange:

    *  it's like real "component", they are self-contained.

    * change the finally page is simple, just change the external contain page, you get different result. (the project I worked before, the web design changes from time to time, maybe we just have poor design and decision but that's real in many teams I believe... )  

    * it's easy to switch from "service side include" to "ajax include", just change the container page, all component remain unchanged!  In one of my project, we even switch between the 2, if user agent support javascript, we use ajax, if not we use server side include,  and it's very SEO friendly.

    * The huge benefit I think is CACHE. We can have many level cache to archive best performance, in the container page level, we can use cached result if nothing changed from any inside component, for  "component" they have cache for themselves, and the cache mechanism is same for the whole page and the "component", it's simple and very efficient.

     I think the solution I have is like a "reversed" master page: the "container" page dispatch to each "component" and composite into a final web page.  ASP.NET's master page is a great idea, however I am wonder if how to archive the above dash board alike application easily and keep the design neat and clean.

    ---

    Of course, maybe I am wrong or maybe there are much better solution for this, that's what I am looking for and why I asked the question here.   

  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 9:39 PM
    • Loading...
    • convit
    • Joined on 09-10-2002, 8:46 AM
    • Posts 5

     I've got the same problem with master page which include M-V-C modules. I search on the net, ROR or PHP MVC have method: render_component which will render a view to solve this problem

    <html>

    <body

    <div id="leftCol">

       render_component(Controller="Category", Action = "List", {param1=value1, param2=value2}) 

    </div> 

    <div id="mainCol">

       render_component(Controller="Product", Action = "List", {param1=value1, param2=value2, param3=value3})

    </div> 

    </body> 

    </html> 

    Can we have any same solutions for asp.net mvc ?

     

     

     

     

  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 10:20 PM
    • Loading...
    • shinakuma
    • Joined on 03-01-2003, 4:09 PM
    • Posts 92

    convit:
    ROR or PHP MVC have method: render_component which will render a view to solve this problem

    I like this, conceptually, they are all seperate actions, so it's very natural, this gives you a good way of composing complex views without breaking the mvc. Got my vote too.

  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 10:44 PM
    • Loading...
    • abombss
    • Joined on 06-27-2006, 4:13 PM
    • Chicago, IL
    • Posts 164

    How is that any different than <uc:MyUserControl />?

    How does your CategoryController/List action know what view to render, and know that it only needs to render a partial?

     

    Adam Tybor -- abombss.com
  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 11:00 PM
    • Loading...
    • convit
    • Joined on 09-10-2002, 8:46 AM
    • Posts 5

    If we use <uc:MyUserControl> : we will breaking the MVC pattern because of view is direct accessed not throught its controller,  

    CategoryController/List, List Action already know what view to render, I dont know how to implement this idea :(

    I have another question:

    How to pass data cross modules ? With classic asp.net mode, I use query string to pass data.

    But with MVC URL is very important to determine Controller, Action, with one URL, we only determine one controller, one action deal with that URL.

    But in complex View scene, we have to instance many controller, each controller mush have data to process itself.

     

     

     

  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 11:16 PM
    • Loading...
    • shinakuma
    • Joined on 03-01-2003, 4:09 PM
    • Posts 92

    convit:
    But in complex View scene, khi have to instance many controller, each controller mush have data to process it selt.

    The flow will look something like this. Take a portal type page with multiple components, most likely you hit the home controler/action first, inside the action you read the db and load up some profile settings for each individual component on your portal page, pass that to the view, inside the view, appropriate component is rendered with the setting you read from the db. preserves mvc. Basically, you either pass it through the original url when appropriate, or count on the first action to figure it out. Think of it as a parent action with a bunch of child actions, parent will tell the children what to do.

  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-19-2007, 11:58 PM
    • Loading...
    • abombss
    • Joined on 06-27-2006, 4:13 PM
    • Chicago, IL
    • Posts 164

     

    convit:
    If we use <uc:MyUserControl> : we will breaking the MVC pattern because of view is direct accessed not throught its controller,  

    Where does it say a view cannot call another view in MVC?  We get our MVC separation because the model does not depend on the view.

    convit:
    How to pass data cross modules ? With classic asp.net mode, I use query string to pass data.
     

    Through parameters, everything has access to the RequestContext and if using UserControls you can use parameters.

    convit:
    But in complex View scene, khi have to instance many controller, each controller mush have data to process itself.
     

    This is why this is a weird idea.  Why would you call an action on a 2nd controller just to render output?  You call a controller to take action.  Outputing a component will have no side effects.  Only if the component needs to modify or presist state in some way does it need a controller to call into an action.  I only want one action happening per request, otherwise it will turn into a bloody nightmare. 

    Adam Tybor -- abombss.com
  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-20-2007, 12:04 AM
    • Loading...
    • shinakuma
    • Joined on 03-01-2003, 4:09 PM
    • Posts 92

    abombss:
    How is that any different than <uc:MyUserControl />?

    Unlike user controls that will break the mvc pattern, render component will not.

    Take implementing this forum for example, there's a top 10 poster list on the right panel. The obvious solution is we will make a master page that contains a Top10UserControl. now let's say we hit

    http://asp.net/forums/index

    how do we load the data into this Top10UserControl, one option is have the user control do it, but that is not mvc. option 2 is have ForumsController.Index load up the data and pass it on, but there's a problem, what if we hit other pages

    http://asp.net/forums/1
    http://asp.net/forums/1/posts/index
    http://asp.net/forums/1/posts/1000/comments/new
    ...

    all these actions ForumsController.Show(forumId), PostsController.Index(forumId), CommentsController.New(postId) etc all have to know to load up the Top10 data for the master page. What if we decided to add something else to the master page? Code has to be changed in lots of places. We can refactor and make an utility function called GetMasterPageData(), but every action still have to remember to invoke that, not very clean. Maybe we use the template pattern so you will never forget to call GetMasterPageData(), but that's an extra class on the inheritance hierarchy.

    With the render component approach, you don't have to worry about any of that, the master page will call render component with { controller = "top10", action = "index", forumId = forumId }. Just like you could alternatively have an ajax call on the master page that invokes http://asp.net/top10/index/1 and retreve a html fragment, except render component is done in the same request.

    When you think about it, it's a pretty simple and neat solution.

  • Re: How about a very complex page which need many "MVC modules/parts" ?

    12-20-2007, 4:33 AM
    • Loading...
    • convit
    • Joined on 09-10-2002, 8:46 AM
    • Posts 5

    Thanks shinakuma for the reply.
    Could you please help me to implement a helper function with prototype like this:

              ControllerHelper.ExecuteAction(string url, object defaults, bool isAjaxRender) ;

    url: we will build a url string to simulate a call to action,
    defaults: we will provide some other information for action
    isAjaxRender: true if we want content will be render on client side, false if we want to execute action and render html in server side

    Example:

    <div>
             <% ControllerHelper.ExecuteAction("Post/Top10", {Controller=Post}, false);%>
    </div> 

    or a control like this

    <div id="leftCol">
           <mvc:ExecuteAction runat="server" Url="..." Defaults="..." id="mvcCategory" />
    </div>
    <div id="mainCol">
           <mvc:ExecuteAction runat="server" Url="..." Defaults="..." id="mvcListProduct" />
    </div>

     
    DTK 

  • Re: How about a very complex page which need many "MVC modules/parts" ?