I have a question about reuseable controls in ASP.NET MVC 3.
In our application we have a lot of tales on different pages. The tables have all the same logic, so we put a table in its own controller and view.
The data source and certain individual properties are submitted to the tablecontroller as parameter. The controller store the parameters in the tempdata to save them for self request by the tableview.
The table raises an AJAX request when sorting or paging, so that only parts of the table are updated. The request goes directly to the tablecontroller. The tablecontroller requires the parameters that we stored in the tempdata. So the table can call itself, without losing the data source and the properties.
My question is whether there is a better solution?
The current approach is not so nice, because the TempData are occupied with data to the end of the session. The pages and tables are linked and the user can switch between there. So its difficult to determine when certain parameters are no longer needed.
What is the best solution to build your own parameterized controls in MVC?
The right build your own parameterized controls in MVC in using Declarative Helpers.
However, this solution may be not flexible enough for asynchronous client-server interaction. For such interactive controls may be the best implementation is javascript template engine.
Related
Is there a way to keep information between post backs in MVC2 without utilizing Session variables or the query string?
You mean like the view state from .NET Web Forms? Technically there is, although it isn't recommended - you're much better off utilizing models and posting the model data to the server and pushing the model back into the view.
This will work well but if you're needing something as stateful as the WebForms ViewState, I would recommend doing your project in WebForms or use the session to save your models.
Edit: Build your form that posts (or gets) data back to the same page. Then in your controller, have a method like this.
[HttpPost]
public ActionResult LoginUser(LoginViewModel model)
{
//work on the model here
return View(model);
}
This will push the form data that the user just submitted back into your view. Then have an Html helper like this in your view.
<%: Html.TextboxFor(m => Model.Username) %>
There are a slew of excellent resources on the web about using html helpers with models. Google around and you'll come across them.
You could use Hidden Form fields to POST the values back to the server with each form submission.
Other alternatives include a cookie or Http Cache - what is stopping you using session?
As a high level concept, you should rely as little as possible not only on Session to store your state, but on statefulness in general in a web application. The idea is that the web itself is stateless by design, and when designing software on that paradigm the software should be designed to embrace a stateless nature.
More specifically, using a ViewModel gives you a strongly typed representation of the data needed for your view to pass down to the client. Pieces of that data which hold information about the state of a given request which can be made from that view can be added to the view in probably a number of ways, but the two most immediate ones are:
As hidden form field elements
As parts of URLs for requests
Check out the NerdDinner tutorial for a standard approach to using either ViewData or a strongly-typed ViewModel. Some Google searches will, as always, yield more information and tutorials. But note specifically where the tutorial uses the ViewModel properties in the view. These can be used anywhere in the rendering of the HTML, either in the HTML helpers or in manually constructing the tags.
Additional interesting reading regarding the statelessness of the web (and this whole not-as-new-as-many-people-seem-to-think REST thing) is the article: How I Explained REST to My Wife.
If your main issue with the Session variables is of a practical nature (want something that works for a single request, not needing to worry about cleaning it up etc) rather than a requirement to not use Session then use the TempData dictionary. It deals with putting information in the Session for a single request only and the framework will automatically remove it for you afterwards.
I've recently decided to try out MVC 2 and coming from a webforms background, I'm having a little trouble trying to figure out the best practice solution to caching data provided to a partial view (user control).
In my webforms application, I have an AccountSummary.aspx page, which has a Booking.ascx control. Booking.ascx had output caching of 300 seconds and in the Page_Load of AccountSummary.aspx, I used to check if the control was null, and if not, pass it a UserId. Then in the code-behind of the Booking.ascx, I used to make a data access call to fetch all the bookings, thus a call to fetch the bookings was made at most once every 300 seconds.
I would like to achieve the same in MVC2, but I can't seem to find the best way of achieving this because all the examples on the web seem to pass the data to the user control in the RenderPartial HTML helper method (which I don't want because on every page load I would have to pass the booking info which is going to kill my database!)
Please advise :-)
Cheers, A.
There is no simple mechanism for view-level caching in ASP.NET MVC 2.
There are some clever tricks to exploit the output caching in ASP.NET, like Donut Caching and Donut Hole Caching, but they both violate the MVC pattern (by making the DAL spill over into the views, for example), are very tricky to get right, and exhibit virtually undocumented behavior. (See the comments in the blog posts and other posts here on SO for more information.)
The short answer is that view-level caching (i.e. caching a partial view or a view, as opposed to an action method) is a trip you do not want to embark on if you are new to ASP.NET MVC. Hence, you should cache in your DAL instead, or on your action methods.
In your example, you could have a OutputCacheAttribute on an action method that returns a partial view with the booking list, or you could use the System.Web.Cache to cache the booking list when retrieving it in your DAL.
ViewModel is a term that is used in both MVVM (Model-View-ViewModel) and the recommended implementation for ASP.NET MVC. Researching "ViewModel" can be confusing given that each pattern uses the same term.
What are the main differences between the MVC ViewModel and MVVM ViewModel? For example, I believe the MVVM ViewModel is more rich, given the lack of a Controller. Is this true?
A rather challenging question to answer succinctly, but I'll attempt it. (Bear in mind that the answers to these kinds of questions are still the subject of debate amongst developers.)
In MVC, the ViewModel provides all the information necessary for a View to be rendered. The data it contains is created using data defined in the Model. The View reads the ViewModel and renders the output. Input from the View is passed to the Controller, which manipulates the Model, constructs an appropriate ViewModel, and passes this to the View for rendering.
In MVVM, the ViewModel serves the same function as it does in MVC, but it also replaces part of the MVC Controller by providing commands which allow the View to manipulate the Model. WPF databinding manages the updating of the View according to changes in the ViewModel (and this effectively replaces the remaining function of the MVC Controller).
It's been a while since I played UI Design Patterns Bingo.. however let me take a stab at this..
MVVM is just something that MS has come up with... because it helps you to get the most out of WPF. You combine the state and behavior of the view into a class (a presentation model) that is easily testable + then you use data-binding to get the data into any view.
This link has a brief of the evolution of MVVM. Combine this with Fowler's "GUI Architectures" series, and you should be on your way.
Update: Didn't know there was something called MVC-VM. Apparently a brainchild of the ASP.NET MVC crowd. Looks and sounds similar to MVVM (except tuned for ASP.NET MVC); the only difference is that it places a restriction that there is 1:1 mapping between VM and View. I'd have guessed 1:N, but everything else matches.
I know this is a (way) old question, but I've been pointed to it as an example of using "View Model" in the context of MVC. I argue that this is incorrect and can lead to confusion by people who are new to either/or/both patterns. Whoever is doing it--stahp. Here's why (and it's even an answer to the original question in a roundabout way).
An example of when this happens can be seen in this question. The user is trying to use a View Model that implements INotifyPropertyChanged in an ASP.NET MVC application, thus mashing together desktop and stateless web application design in an architectural fail and heartbreak.
To put it simply, there is no "View Model" in the MVC pattern. There is, however, a functional equivalent, and that's the Controller. Just to be clear about the parts and their purpouses,
MVVM (desktop applications):
Model - Strongly typed object that holds data to be passed between the View and View Model
View - The UI viewed by the user and through which the user interacts with the system
View Model - Interprets user actions (e.g., via ICommand), performs them, updates application state
MVC (web applications):
Model - Strongly typed* object that holds data to be passed between the View and View Model
View - A UI generator that combines the Model, code and HTML to render a webpage
Controller - Accepts user requests, interprets them, updates application state and uses a View to convert this state into an HTML webpage
The Model is practically the same in both patterns. Desktop models may implement update event notifications, web Models may be dynamic (i.e., not strongly typed), and both may or may not include validation methods or metadata.
The View in the desktop is what the user sees. In the web, it is a generator that outputs HTML for browsers to display on the client side. It must interpret user interaction on the desktop, but on the web that is handled by client side javascript, the browser, and the requests that are sent back to the server.
The View Model/Controller are roughly functionally equivalent, but differ greatly in how they are implemented and how they operate. In the View Model, user interaction with the application is transferred to View Models via ICommands, routed events, and other methods (many MVVM frameworks provide different ways to hook View Models to the UI and other parts of the application). In a Controller, a request comes in with all information needed for the Controller to return a result to the user (assuming it's a 200 OK request). The Controller must perform whatever work is necessary to create the state (aka Model) needed for the HTML generator (the View) to create the response. Design-wise, the Controller sits above the View and Model knowing and controlling both, whereas the ViewModel sits next to the View, passing the Model (and other information) between them.
What really seems to confuse some people is that there are client side MVVM frameworks that you can mix into your MVC application. These exist solely in javascript in the user's browser, and have nothing to do with whatever particular pattern you're following on the server side. You can run a classic ASP website that uses MVVM on the client side. Hell, you can run static HTML pages that use MVVM on the client side. They are that separate.
These javascript MVVM frameworks typically follow a similar pattern to the desktop MVVM pattern described above, but adjusted to work more in tune with the nature of the HTML DOM and javascript. For example, there is no extensive binding system woven into the DOM, and javascript has a very limited type system, so matching up templates to models is much different than in WPF. They also typically work disconnected from the server, and when they need to interact, prefer AJAX calls rather than POSTing the page back to the Controller (AJAX calls typically are handled by WebAPI Controllers in ASP.NET MVC).
So, to summarize, there really isn't a View Model in MVC. The Controller is the rough equivalent, but is very different in how it receives user input, interprets it, and returns a result to the user. Using the term "View Model" to refer to anything in MVC can only lead to confusion, and therefore should be avoided. Use the proper terms for the proper parts of the pattern. It may seem pedantic, but it should help keep things clear and be less confusing to people who are new to both patterns.
In our old system we had pages rendered from XSLT. In order to change the page into "edit" mode we would have a button of some sort, once clicked would have an EditYN flag which would be passed to the stored procedure. The stored procedure would simply give this variable back to indicate that the page was in edit mode. This meant that query strings, viewstate or session data were not required to indicate that the page is in edit mode.
I've been dealing with ASP.NET MVC only for the last week for RND purposes at work. I'm wondering what's the best way to have a page which displays data, to then turn into a page where you can edit all of that data? Should you move to a separate page? Should you stay on the same page and have rendering logic in the view to show the edit mode of the page?
Whilst on the same topic, I thought I'd also ask about GridViews and their place in the MVC architecture. Beforehand we'd simply use data sources and set them up with the GridView. Then the GridView could enter edit mode quite easily by itself with the UPDATE query set in the data source. How should this process be done using MVC?
Make a submit button for your edit mode. The controller action will respond to POST, set the "InEdit" flag in your model, then return the same view again. The view can then render based on the flag. But I would rather create two different views, for view and edit modes, then based on the flag analysis done in the controller action just return the one or the other view.
Whilst on the same topic, I thought
I'd also ask about GridViews and their
place in the MVC architecture.
How should this process be
done using MVC?
You can use javascript, something like jqGrid or Yahoo´s datatable. For simpler datatables, you can use jQuery´s tablesorter.
On the backend, your controller returns json objects that can be modified by the client, ie. the javascript grid which then sends the data back to the controller to be saved.
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.