It just occured to me that I effectively implemented Server.Execute for MVC (and in case if you are wondering, the regular Server.Execute is tied to the webform model it appears).
I would like to hear some opinions from the dev team on whether "render_component" has any place in the mvc framework. Seems to me that this is really no different from ajax calls as far as the amount of work the server has to do.
t just occured to me that I effectively implemented Server.Execute for MVC (and in case if you are wondering, the regular Server.Execute is tied to the webform model it appears).
I believe Execute() will work well. however I am wondering if Execute() is not that lightweight enough? ( I mean it may have too many overhead from inside of Execute, and it would be better to have a light weight one)
shinakuma
I would like to hear some opinions from the dev team on whether "render_component" has any place in the mvc framework. Seems to me that this is really no different from ajax calls as far as the amount of work the server has to do.
Me too.
I believe the problem we discuss here is quite common in a "real" web application.
I was able to finally hack up a conversion of the core of my old content management system into the new MVC framework. All the issues you guys discussed here were real problems for me. The biggest issues I'd like to see some framework help from was the
execution of Controller methods and Rendering of partial views.
I like your solution shinakuma, in that you call ProcessRequest. That seems a bit heavy though, to just call a controller method and output a snippet of html. I managed to use IController's Execute method, but I think that's too heavy as well, plus it
was very hackish to get it to work.
In my cms, you can either navigate to a particular page, or render a module directly. The former is old school portal stuff where the engine determines all the views to throw on the page and renders them in the right places. The latter is just like a normal
MVC route, with the exception that the rendered html then goes in the main content area of the site template. The cms engine then figures out the home page for that module (basically all the views in a controller share a home page), then draws all the modules/portlets/webparts/partialviews
in all the areas outside the main content area. Any POSTs will be handled via AJAX or will be interactions solely with the module represented in the main content area, so all the Route stuff should work just fine. Here's the basic workflow relevant to the
discussion you guys have been having:
<div mce_keep="true">Created custom Controller class that overrides RenderView</div>
<div mce_keep="true">RenderView checks a context variable "isPageBuildingInProgress"</div>
<div mce_keep="true">If not, take the view being rendered (remember, a controller action has already been executed) and capture it in a string - to be placed in the main content area</div>
<div mce_keep="true">If page building is in progress, just render to a string and store it in the right place (number 6 below)</div>
<div mce_keep="true">Interact with the model to get all the partial views that belong in all the other areas of the page (a controller and an action will come back for each)</div>
<div mce_keep="true">Execute the appropriate actions on each of the controllers, capturing the rendered html and placing it in StringBuilders on a PageData object (ViewData for the page)</div>
<div mce_keep="true">Render "THE" aspx view (there is only one in the whole app, everything else is a ViewUserControl) - it binds to the PageData object which just contains html for each of the content areas within the MasterPage</div>
The benefit of this implementation is that all my controllers just call RenderView and know nothing about the cms view manipulation that is going on. The exact same code is executed whether the partial view is the main attraction (directly accessed in the
url to show up in the main content area) or if it's just been selected to show up in a particular location by the user for that particular page (rendered due to configuration of the portal). All of the logic is in the base Controller class's Render method,
leaving all the controllers and their views for all the modules very clean and nicely encapsulated.
The drawback is the hackish nature of the code I had to mangle to get this to work. Messing with the ControllerContext and RouteData made me feel particularly dirty. Here are some code snippets (Disclaimer - I'm certain there are better ways to do this,
but this is as far as I got):
When executing the final Render for the page (all partial views rendered with their html strings securely fastened to my PageData object), I had to do the following:
// Now, render the containing page, passing in the pageData object, which contains all the html for each of the SiteTemplate locations
RouteData routeData = this.RouteData;
routeData.Values.Clear();
routeData.Values.Add("controller", "Nav");
routeData.Values.Add("action", "Show");
routeData.Values.Add("id", null);
ControllerContext controllerContext = new ControllerContext(new RequestContext(this.HttpContext, routeData), (IController)this);
this.ControllerContext = controllerContext;
base.RenderView("~/Views/Nav/Show.aspx", masterName, pageData);
Oh, and I used home grown reflection code to create all my partial view controllers to call Execute on. I think I've got some more work ahead of me to handle all the data that can be passed into the url route in my Execute method, but calling ProcessRequest
seems like a bit much to accomplish a partial view render.
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 ?
Sounds reasonable while we have M-V-V-C, but if we get to M-V-C-V-C then it all was in vain... [:)]
In other words, while we keep SoC and keep these "components" to be in fact "subviews" (and not what the term "component" may suggest...) all is fine.
Writing software would be a lot easier if it weren't for customers
I like your solution shinakuma, in that you call ProcessRequest. That seems a bit heavy though, to just call a controller method and output a snippet of html. I managed to use IController's Execute method, but I think that's too heavy as well, plus it was
very hackish to get it to work.
The goal wasn't to just call a controller method, but to invoke a full MVC cycle, going through a typical execution pipeline like any other request, thus preserving all custom hooks along the way. That is not to say this is a efficient way of doing things
however.
I'm now thinking that MVC by itself is not going to address this need sufficiently. You would need another architecture layer on top of the basic MVC that will give you a flexible and configurable plugin framework usually demanded by CMS. Think of it as
the difference between WebForms, PHP and DotNetNuke, Joomla.
RenderView calls a process request anyway to kick off the asp.net pipeline which is needed to render the view. It would be nice to somehow inject the secondary calls to renderview into the current executing pipeline, not sure how easy that would be.
RenderView calls a process request anyway to kick off the asp.net pipeline which is needed to render the view.
No, RenderView will call the ProcessRequest on the aspx page handler to render the view page. That only goes through the page life cycle on the apsx. It's very different from the ProcessRequest on the MvcHandler.
I did a simple benchmark test which is related to this post. Detail test result is here: http://dotnet.robertmao.com/2008/01/13/some-aspnet-benchmark-data/
This is just a very simple and rough benchmark test, I use my own desktop computer running Windows XP professional and many process (including the heavy weight Visual Studio 2008) and ASP.NET's development server which comes with Visual Studio. I believe
after deploy it on IIS under Windows Server box will archive much better performance.
I use Apache bench to test, the parameter I used is "-n 1000 -c 100", means send 1000 requests and concurrent number is 100.
Quick view of results:
Test
Request per second [#/sec] (mean)
1
Simple aspx view (same as below MVC's view aspx file)
285.71
2
Simple asp.net MVC
232.73
3
ASP.net MVC with another MVC request from inside
174.39
4
ASP.net MVC with a simple user control rendered by RenderUserControl()
218.43
5
ASP.net MVC with a simple user control rendered by user control tag
235.29
Of course a simple .aspx page archive the best performance, MVC add very minimal overhead to it.
Use tag to render user control have almost no overhead ( I believe it has been complied inside, like source level include), RenderUserControl() have a small overhead.
shinakuma's
RenderComponent() have some overhead in performance since he use "ProcessRequest()" which actually initialize a whole server side MVC cycle. (Java's jsp:include have same heavy weight behavior as I tested before.) If we can find out a better solution to
archive a much lighter weight performance it would be great.
convit
Member
10 Points
5 Posts
Re: How about a very complex page which need many "MVC modules/parts" ?
Dec 21, 2007 03:11 AM|LINK
shinakuma: Thank you very much. I've tried to implement my self but not success. Thanks again :)
DTK
I've just tested, it runs smoothly :)). Now I could use MVC modules in my project :)
shinakuma
Member
378 Points
92 Posts
Re: How about a very complex page which need many "MVC modules/parts" ?
Dec 21, 2007 05:49 PM|LINK
It just occured to me that I effectively implemented Server.Execute for MVC (and in case if you are wondering, the regular Server.Execute is tied to the webform model it appears).
I would like to hear some opinions from the dev team on whether "render_component" has any place in the mvc framework. Seems to me that this is really no different from ajax calls as far as the amount of work the server has to do.
mave99a
Member
2 Points
8 Posts
Re: How about a very complex page which need many "MVC modules/parts" ?
Dec 21, 2007 09:03 PM|LINK
I believe Execute() will work well. however I am wondering if Execute() is not that lightweight enough? ( I mean it may have too many overhead from inside of Execute, and it would be better to have a light weight one)
Me too.
I believe the problem we discuss here is quite common in a "real" web application.
Kepler
Member
76 Points
42 Posts
Re: How about a very complex page which need many "MVC modules/parts" ?
Jan 02, 2008 08:35 PM|LINK
I was able to finally hack up a conversion of the core of my old content management system into the new MVC framework. All the issues you guys discussed here were real problems for me. The biggest issues I'd like to see some framework help from was the execution of Controller methods and Rendering of partial views.
I like your solution shinakuma, in that you call ProcessRequest. That seems a bit heavy though, to just call a controller method and output a snippet of html. I managed to use IController's Execute method, but I think that's too heavy as well, plus it was very hackish to get it to work.
In my cms, you can either navigate to a particular page, or render a module directly. The former is old school portal stuff where the engine determines all the views to throw on the page and renders them in the right places. The latter is just like a normal MVC route, with the exception that the rendered html then goes in the main content area of the site template. The cms engine then figures out the home page for that module (basically all the views in a controller share a home page), then draws all the modules/portlets/webparts/partialviews in all the areas outside the main content area. Any POSTs will be handled via AJAX or will be interactions solely with the module represented in the main content area, so all the Route stuff should work just fine. Here's the basic workflow relevant to the discussion you guys have been having:
The benefit of this implementation is that all my controllers just call RenderView and know nothing about the cms view manipulation that is going on. The exact same code is executed whether the partial view is the main attraction (directly accessed in the url to show up in the main content area) or if it's just been selected to show up in a particular location by the user for that particular page (rendered due to configuration of the portal). All of the logic is in the base Controller class's Render method, leaving all the controllers and their views for all the modules very clean and nicely encapsulated.
The drawback is the hackish nature of the code I had to mangle to get this to work. Messing with the ControllerContext and RouteData made me feel particularly dirty. Here are some code snippets (Disclaimer - I'm certain there are better ways to do this, but this is as far as I got):
protected void Execute(System.Web.IHttpContext httpContextInterface, RouteData routeData, string controllerName, string action) { routeData.Values.Clear(); routeData.Values.Add("controller", controllerName); routeData.Values.Add("action", action); routeData.Values.Add("id", null); ControllerContext controllerContext = new ControllerContext(new RequestContext(httpContextInterface, routeData), (IController)this); base.Execute(controllerContext); }When executing the final Render for the page (all partial views rendered with their html strings securely fastened to my PageData object), I had to do the following:
Oh, and I used home grown reflection code to create all my partial view controllers to call Execute on. I think I've got some more work ahead of me to handle all the data that can be passed into the url route in my Execute method, but calling ProcessRequest seems like a bit much to accomplish a partial view render.
CMS partial view portal
Momcilo
Participant
1477 Points
251 Posts
Re: How about a very complex page which need many "MVC modules/parts" ?
Jan 02, 2008 10:20 PM|LINK
Sounds reasonable while we have M-V-V-C, but if we get to M-V-C-V-C then it all was in vain... [:)]
In other words, while we keep SoC and keep these "components" to be in fact "subviews" (and not what the term "component" may suggest...) all is fine.
shinakuma
Member
378 Points
92 Posts
Re: How about a very complex page which need many "MVC modules/parts" ?
Jan 03, 2008 07:20 PM|LINK
The goal wasn't to just call a controller method, but to invoke a full MVC cycle, going through a typical execution pipeline like any other request, thus preserving all custom hooks along the way. That is not to say this is a efficient way of doing things however.
I'm now thinking that MVC by itself is not going to address this need sufficiently. You would need another architecture layer on top of the basic MVC that will give you a flexible and configurable plugin framework usually demanded by CMS. Think of it as the difference between WebForms, PHP and DotNetNuke, Joomla.
abombss
Member
575 Points
164 Posts
Re: How about a very complex page which need many "MVC modules/parts" ?
Jan 04, 2008 02:54 PM|LINK
RenderView calls a process request anyway to kick off the asp.net pipeline which is needed to render the view. It would be nice to somehow inject the secondary calls to renderview into the current executing pipeline, not sure how easy that would be.
shinakuma
Member
378 Points
92 Posts
Re: How about a very complex page which need many "MVC modules/parts" ?
Jan 04, 2008 03:25 PM|LINK
No, RenderView will call the ProcessRequest on the aspx page handler to render the view page. That only goes through the page life cycle on the apsx. It's very different from the ProcessRequest on the MvcHandler.
abombss
Member
575 Points
164 Posts
Re: How about a very complex page which need many "MVC modules/parts" ?
Jan 04, 2008 03:31 PM|LINK
True, I misread some of the post.
mave99a
Member
2 Points
8 Posts
Re: How about a very complex page which need many "MVC modules/parts" ?
Jan 13, 2008 10:38 PM|LINK
I did a simple benchmark test which is related to this post. Detail test result is here: http://dotnet.robertmao.com/2008/01/13/some-aspnet-benchmark-data/
This is just a very simple and rough benchmark test, I use my own desktop computer running Windows XP professional and many process (including the heavy weight Visual Studio 2008) and ASP.NET's development server which comes with Visual Studio. I believe after deploy it on IIS under Windows Server box will archive much better performance.
I use Apache bench to test, the parameter I used is "-n 1000 -c 100", means send 1000 requests and concurrent number is 100.
Quick view of results:
Of course a simple .aspx page archive the best performance, MVC add very minimal overhead to it.
Use tag to render user control have almost no overhead ( I believe it has been complied inside, like source level include), RenderUserControl() have a small overhead.
shinakuma's RenderComponent() have some overhead in performance since he use "ProcessRequest()" which actually initialize a whole server side MVC cycle. (Java's jsp:include have same heavy weight behavior as I tested before.) If we can find out a better solution to archive a much lighter weight performance it would be great.