We have a fairly complex application that was previously using WebForms. We are in the process of rewriting bits of it from scratch using MVC. Our application is comprised of a number of widgets, that together make up the functionality of the application.
In WebForms, we used UserControls. Each UserControl would register its CSS and JavaScript by means of a collection that was stored in HttpContext.Current.Items. That collection would then be merged to output as one single request. Typically this would occur in the Page_Load event, and the containing page would then render out a script tag that would comprise all the JavaScript and CSS needed for that page.
We've been struggling with doing the same in MVC. We are using a number of views within a masterpage to mimic the widgets. Each widget has its own controller, so the functionality can be sufficiently segregated. The masterpage builds up the widgets on the page using RenderAction from MVC futures. Originally we were using the same registration method for the CSS/JS files. Each controller would register its required files in an Action. The files would then be contained in the HttpContext.Current.Items collection, and would be rendered out to the page. To facilitate this, I wrote an HtmlHelper extension to render the links/scripts out to the page. It looks like this:
<%= Html.GetRegisteredCssFiles() %>
The problem is that MVC uses a more top down approach. This call is made in the tag of the page, but our subsequent calls to RenderAction happen below. By the time RenderAction is called and the required files are registered in HttpContext.Current.Items, the code above has already executed. So, the collection is not modified at the right time.
Does anyone have any ideas on how we should be constructing this? I'm looking for answers that incorporate best practices for MVC.
This question was asked a lot of time ago, so probably you've dealt with this already. But for future visitors, maybe this solution will be helpful:
http://marcinbudny.blogspot.com/2010/01/handling-stylesheet-references-in.html
The Free Telerik MVC tools have a script and a style register that might do what you want ...
Not sure if this is a feasible solution for you, but try moving that call to the bottom of each page.
I've always included my javascript and css files in the html HEAD, so I don't know if it would work lower down. My assumption is that it'll work in most browsers, but you might have random problems in a few.
The alternative is to have GetRegisteredFiles() output some javascript that loads the CSS files in the proper place (via DOM manipulation).
The problem with either of these solutions is that the files aren't included until the end, which could cause the page to look "plain" until the CSS is downloaded.
Alternatively, the controller could predict which "widgets" will get loaded and pass that data to the master page.
Related
I have Umbraco 7.5 and I need to know how to create normal MVC pages for adding new data to my site.
Lets say I have a Doctype "Node" in back-office. I want to let some people be able to add/edit some nodes without going through back-office. How can I do it?
I've tried to create add my view and controller (the MVC way), but apparently Umbraco hijacks all routing and my controller won't hit at all.
I've googled the matter (which is hard since I am not looking for Umbraco forms :| )and I've found this. But I prefer not to add my form as a part of other page. I mean, does it make sense to create a page in back office from type "something" and then on its template I do my add/edit form of another type? Seems strange, right?
I appreciate any ideas/ solution to this matter
You have a couple of options here. You can create a physical page for the editor to sit on, and add the editor as a SurfaceController action (basically an MVC Partial with Postback, that is still part of the Umbraco pipeline). Your form can then use the Content Service API to update the details. The advantage of this method is your code will have access to all of the Umbraco methods and templating out of the box. You could also use WebAPI controllers for the form if you want to do it all client side with JS requests.
You could also use route hijacking: https://our.umbraco.org/documentation/reference/routing/custom-controllers this allows you to have your own custom controllers for Umbraco routes, rather than using the default Umbraco ones. This is a bit more work to set up.
Finally, you can also tell Umbraco to ignore certain paths entirely, and you could run your controllers on those paths. The disadvantage here is that as the routes are being ignored by Umbraco, you don't automatically have access to all the useful Umbraco templating etc.
I've used the first method recently, and it works fine. The only caveat is that allowing users to edit nodes will fill up the version table quite quickly if a lot of users are editing a lot of nodes (every time a node is saved, a version is created). If you're going down this route, you may want to investigate something like Unversion: https://our.umbraco.org/projects/website-utilities/unversion/ which helps to keep old versions more manageable in situations like this.
With the asp.net MVC, we see a lot different view engines, like Razor, spark, webform etc.
I thought the idea of MVC is separating of data and view, I assume view part should be something that allows a designer to do some work, even after it is created by a developer. But I see now most if not all view engines introduce new syntax, not stick with html. The old web form, you can use "view designer" to see how a page looks like even with some code blocks, designer could at least move blocks and html elements around, but now with engine like Razor, you cannot even view a page in designer mode. So I don't quite get what is the point?
This came to me when I tried to search for a server side templating that allows end user do some changes on the page. I perfer something stick to pure HTML, maybe Spark is the one, but I am not sure. Please someone can give me some idea.
Thanks
Views are meant for that. It will not static design. Markup will be generated on fly.
If you take razor as an example, you will have the combination of c# and html as code in view page. So, as you may be able to understand now, you cannot see the actual design until the c# and html execution goes hand-in-hand.
Hope it clarifies a little!
I want to use a different model for site.master. Instead of of the old "<"asp :Content PlaceHolder ID="SideContent" runat="server" "/ >" tags I want to use ajax to dynamically display my aspx pages(within Site.master). so no complete reload unless explicitly asked for.
I also want to do this with very little change to the way my project is organized.
Joe,
if you're using mvc, it'll be no problem (jQuery partialview updates etc, etc). however, as you haven't tagged as such i'm presuming webforms (oh, i see the asp.net mvc tag is there now - however, i'll leave the reply as i wrote it at the time as it may be of interest). the good news is, all is not lost and there are in fact page methods that can be used in webforms to stunning effect. i did a quick google and this article seems to nail what i was thinking about:
http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/
i can't comment on the technique too much as i'm definately more in the mvc camp these days, but this is how i'd have done it had i been still heavily using webforms.
jim
[edit] - as the mvc tag is now present, that changes my answer above (or at least means that i should add a little re mvc). what you could do on the masterpage is to ensure that your content pages were ALL partialviews and that your menus invoked a partial refresh. the masterpage would have a 'content' div that you'd update via each jquery menu request. in effect only the inner section of the page would ever change. i know you'd said 'little' change, but depending on the width of your pages, this suggestion could be fairly simple or complex depending on your viewmodels etc. i'll be interested to see further comments.
also, take a look at this (oldish) jeff palermo article re partials and different masterpages: http://jeffreypalermo.com/blog/asp-net-mvc-and-the-templated-partial-view-death-to-ascx/
i have been reading this interesting article which is increasing my every growing confusion about best practices in MVC
link text
and there is a very hot debate about wither to inject JavaScript and HTML Tags using an HTMLHelper or putting it in User control.
what do you advise ?
in case you advise putting it in user Control, how can you make it generic and use it in different views and keep testability ?
Concerning javascript I would say that none of the methods seems suitable for me. I am a big fan of unobtrusive javascript, so I always prefer just adding a script tag in the beginning of my page and not writing a single line of js in helpers or user controls.
"Injecting Javascript into markup" is bad idea for me. I prefere to separate scripts and markup as much as it possible in every concrete situation. I'm using HtmlHelpers for creating custom HTML tags or set of logically combined HTML tags. As for UserControls I'm using it primarily for creating Views, which can be returned for AJAX request and at the same time could be included into "normal page" (non-AJAX requests).
What is the 'page lifecycle' of an ASP.NET MVC page, compared to ASP.NET WebForms?
I'm tryin to better understand this 'simple' question in order to determine whether or not existing pages I have in a (very) simple site can be easily converted from ASP.NET WebForms.
Either a 'conversion' of the process below, or an alternative lifecycle would be what I'm looking for.
What I'm currently doing:
(yes i know that anyone capable of answering my question already knows all this -- i'm just tryin to get a comparison of the 'lifecycle' so i thought i'd start by filling in what we already all know)
Rendering the page:
I have a master page which contains my basic template
I have content pages that give me named regions from the master page into which I put content.
In an event handler for each content page I load data from the database (mostly read-only).
I bind this data to ASP.NET controls representing grids, dropdowns or repeaters. This data all 'lives' inside the HTML generated. Some of it gets into ViewState (but I wont go into that too much!)
I set properties or bind data to certain items like Image or TextBox controls on the page.
The page gets sent to the client rendered as non-reusable HTML.
I try to avoid using ViewState other than what the page needs as a minimum.
Client side (not using ASP.NET AJAX):
I may use JQuery and some nasty tricks to find controls on the page and perform operations on them.
If the user selects from a dropdown -- a postback is generated which triggers a C# event in my codebehind. This event may go to the database, but whatever it does a completely newly generated HTML page ends up getting sent back to the client.
I may use Page.Session to store key value pairs I need to reuse later
So with MVC how does this 'lifecycle' change?
I'll attempt to comment on each of the bullet points you mentioned:
Your master pages still exist in MVC and are used to provide a consistent layout to the site. not much new there.
Your content pages will become views in the MVC world. They still provide the same content areas to your master pages.
The eventhandling of webforms should not be used in MVC, instead your Controller classes and their action methods will handle loading your data into a "model" that gets passed to the view.
Although webform style databinding is possible in MVC, I find that it is not the optimal solution. Better to place your data in a model class and strongly type your view so that you have direct access to that model. Then its simply a matter of using the <%= ViewData.Model.SomeProperty %> syntax to access your data and display it in the desired locations. As for viewstate, my recommendation is to forget that it even exists.
Remember that one of the advantages of using MVC is that you have control over the HTML you send to the client. Embrace that power and try to find solutions that allow you to maintain that control. Webform controls attempt to hide the the html from you and as such make it more difficult to customize the html when you need to.
I would highly recommend JQuery or one of the other similarly powerful javascript libraries. But learn to use them to access the HTML DOM directly and avoid the id mangling issues of webform controls.
You can use jquery to hook into the dropdown selection on the client side and submit standard or ajax style requests. Those request can return new pages, redirects, html fragments or even JSON data that can be used to update the existing page.
The asp.net Session can be used as needed.