I'm new to mvc, mvp or whatever you want to call them. Right now I try to implement a ReservationController where the user first selects a date and then gets a list of suitable time suggestions. As you should know, the suggestions depend on the selected date. This is where my problem / question starts. Should I:
1) Put an event in the View interface like DateChanged and then subscribe to it in the controller?
2) Call UpdateSuggestions on the controller from my asp page, when the selected date changes. (then I must make the controller method public)
Or
3) Update the suggestions in the constructor of the controller.
Regards and thx for help
eric
You need to get out of the control events mind-frame which drives ASP.NET web forms. Although it is technically possible to accomplish things this way I would suggest going down a different route.
You need to return a view to the user which lets them enter a date into a form. They then post the form back to the server and another action method handles this post. This method gets the list of time suggestions and returns a view with these times as its model.
Take a look here for some decent videos on MVC basics: http://www.asp.net/mvc
Here's some great examples of ASP.Net MVC that are great reading for anyone just getting started.
http://www.asp.net/mvc
http://www.asp.net/mvc/tutorials/getting-started-with-mvc3-part1-cs
These two samples include books that take you step by step through creating an MVC project:
http://nerddinner.codeplex.com/
http://www.asp.net/mvc/samples/mvc-music-store
This may not answer your question directly BUT going throught these samples should help make it clear how MVC works and specifically how to use it in ASP.Net. :-)
Here's also a little background on the MVC pattern.
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
http://msdn.microsoft.com/en-us/library/ff649643.aspx
You should put a link or form in your view that points to a URL that passes the date to an action in the controller.
This action should take the date as a parameter, fetch the data for that date, and pass it to a separate view that renders the data.
You should learn the basics of HTTP and web pages, as well as the underlying design of ASP.Net MVC.
Writing code in a framework or system that you don't understand is a recipe for frustration and disaster.
Sorry but your knowledge in asp.net mvc is very very poor. Better to get some knowledge better, or you cannot make it work. But anyways
1) There do not exist events in views in mvc
2) View does not call contstructor on controller
3) see first two
I think your are misunderstanding how MVC works.
If you are not clear on how MVC works it would be worth checking out something like nerd dinner and Scott Gu's blog.
You could have your dates link to an action like below to process this:
[HttpGet]
public ActionResult YourAction(DateTime date)
{
// Add action logic here
Manager suggestions = new Manager();
var suggestions =suggestions.UpdateSuggestions(date)
// create view model
MyModel model= new MyModel(suggestions);
return View(model);
}
Related
What is the point in using a viewmodel when all the relevant data is already available through the parameter in the signature of the controller? I've seen a lot of examples similar to this:
public ActionResult Index(BasicPage currentPage)
{
var model = new BasicViewModel { Heading = currentPage.Heading, Body = currentPage.MainBody, MyBlock = currentPage.MyBlock };
return View(model);
}
Why not just send in the "currentpage" in this example directly to the View? Is there something that is considered bad practise by doing like that?
The above was a general question for asp.net-mvc. I'll add a question about Episerver as well here as well and if I'm lucky someone can answer that as well.
When looking through the Alloy site done with MVC I also saw similar behavior like above where a viewmodel is created in all controllers, why not just send in the Page that is sent into the controller directly to the View? It seems like an unnecessary step to create the viewmodel? Most likely I'm missing some important point here =)
The idea behind viewmodels is that they are optimised for presentation. If you use domain objects you end up having to put logic into the view itself to control the way things are displayed. Putting logic into the view is poor design so the viewmodel gives you some flex so that you have this logic managed in a more appropriate place.
In addition, you can make your viewmodel simpler, only including the fields that are required for the specific view.
Your code example is not a good idea I agree. But having a view model is a good pattern. You might not need it right away but having a view model available and in place is a good option to have for upcoming additions. I would go with Joel's concept from his MVC templates: http://world.episerver.com/Download/Items/EPiServer-CMS/EPiServer-7---CMS/EPiServer-7-MVC-Templates/
We're evaluating asp.net MVC and are looking for some more complicated examples over and above NerdDinner.
Specifically, in a more complex web app, I might have a navigation bar (including primary nav, a search box and a log-in status display), a main content area, a sub-content area (including related content) and a footer. In MVC a controller returns a ViewModel (not a View if I'm thinking that I want to de-couple my Controller from my View) - would my ViewModel have to have properties to cover each and every aspect of the "page" I am aiming to render as output?
If this is unclear, I may be able to re-word my question.
BTW - I know this site is built using MVC. I'm after downloadable examples.
Thanks in advance.
Take a look at CodeCampServer.
Edit: With reference to your query about view models, this isn't the perfect answer to it but thought I'd draw attention to AutoMapper (used by CodeCampServer) which can assist with auto mapping data between models and view models which is a real time saver. Also worth considering the concept of Input Builders (there's some available with MVCContrib and also some in ASP.NET MVC 2) which will also reduce the amount of data you have to pass into a view by encapsulating common functionality across the board.
There's a good video on the ASP.NET MVC 2 offering here: http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-ASPNET-MVC-2-Preview-1-with-Phil-Haack-and-Virtual-Scott/.
Here ya go:
<% Html.RenderAction<LayoutController>(c => c.SearchBox()); %>
<% Html.RenderAction<LayoutController>(c => c.NavBox(Model)); %>
Put these in your masterpages, or on specific views for sidebar widgets, and abstract their logic away from your controller/viewmodel you are working on. They can even read the current RouteData (url/action) and ControllerContext (parameters/models), cause you are dealing with ambient values in these objects - and executing a full ActionMethod request!
I blogged about this little known secret here. I also blogged about where this is located, which is the ASP.NET 1.0 MVC Futures assembly that is a seperate add-on from Microsoft.
Steve Sanderson actually gives gives examples of complex logic and application building in a book I have called Pro ASP.NET MVC (shameless plug, I know, but it's what you are looking for in your question), where he actually uses the RenderAction! I made the blog post, before I even read the book so I am glad we are on the same page.
Actually, there are dozens of extensions and functionality that was developed by the ASP.NET MVC team that was left out of the ASP.NET MVC 1.0 project - most of which makes complex projects much more managable. This is why more complex examples (list above in most people's answers) have to use some type of custom ViewEngine, or some big hoop jumping with base controllers and custom controllers. I've looked at almost all of the open source versions listed above.
But what it comes down to is not looking at a complex example, but instead knowing the ways to implement the complex logic that you desire - such as your Navigation bar when all you have is a ViewModel in a single controller to deal with. It gets tiring very quickly having to bind your navbar to each and every ViewModel.
So, an example of these is the Html.RenderAction() extension (as I started off with) that allows you to move that more complex/abstracted logic off of the viewmodel/controller (where it is NOT even your concern), and place it in its own controller action where it belongs.
This littler baby has saved MVC for me, especally on large scale enterprise projects I am currently working on.
You can pass your viewmodel into the RenderAction, or just render anything like a Footer or Header area - and let the logic be contained within those actions where you can just fire and forget (write the RenderAction, and forget about any concern of what it does for a header or footer).
You are welcome to take a look at good.codeplex.com
It has much of what you seek above but there is work to be done! However, after you've looked I'd be happy to field questions on it here or over on codeplex.
This is what mygoodpoints.org is currently running on.
would my ViewModel have to have
properties to cover each and every
aspect of the "page" I am aiming to
render as output?
Yes. There is another option with RenderAction, but apart from that a ViewModel in generall is often big and you have to find a good way to fill it. I admit this sounds like a trouble spot first.
AtomSite is a blog engine written using ASP.NET MVC
As far as I know, a Controller directly returns a View and can pass data to the View using either the ViewData or the Context.
The former is just a loose bag of various bits of data, whereas the latter is a specific type.
The ViewModel would be passed to the View as the Context (and the mark-up of the View would be strongly-typed to the type of ViewModel it expects).
That's my 2c worth :) Hope that helped-- sorry I could not include any downloadable examples.
To automatically pass data to all views, you can make your own controller class and use that:
Example
public class MyController : Controller
{
private User _CurrentUser;
public User CurrentUser
{
get
{
if (_CurrentUser == null)
_CurrentUser = (User)Session["CurrentUser"];
return _CurrentUser;
}
set
{
_CurrentUser = value;
Session["CurrentUser"] = _CurrentUser;
}
}
/// <summary>
/// Use this override to pass data to all views automatically
/// </summary>
/// <param name="context"></param>
protected override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
if (context.Result is ViewResult)
{
ViewData["CurrentUser"] = CurrentUser;
}
}
}
I'm wondering how you keep a constant value of the Model in an ASP.NET MVC framework. Like when adding something to the Model through the view. You go back to an action in the controller but where do you keep the Model? Is it a private in the controller? or is it passed back and forth from the view to the controller because if it gets big then you are passing alot of data back and forth to add/delete a single item from the Model.
Also any small examples to show this?
Thanks
What are you referring to? Are you meaning a database table loaded up into an object such as Ruby on Rails's ORM -- typically the 'Model' is a series of interfaces or domain objects that load data into objects from the database .. or more simply just the database period.
Please be more specific. There are many MVC frameworks and many different kinds of 'Models'
I think you should check out a ASP.NET MVC tuturial like NerdDinner (from "Professional ASP.NET MVC 1.0"). Scott Guthrie has posted a html version of the tutorial on his site. It's a fairly simple site that they build in the tutorial, and is a great intro to ASP.NET MVC (in my opinion).
There are also some good tutorials on the ASP.NET site.
Hope these help you with .NET MVC, it's a great framework to use!
You can pass the model to the page and you can then use UpdateModel(model name) within your controller.
Each member in the model must be a property with a getter and a setter.
On the page you can hold the data in say a hidden field if you need to maintain the value outside of state.
If you have problems using UpdateModel then you can use the following in your controller;
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyAction(int? id, FormCollection collection)
{
string commentText = collection["myFieldName"];
}
This will normally get your values from the model.
Hope this is what you were asking.
Think of the model as a data transfer object. In a list, display only or edit page, you pull it out of a data layer as a single object or a list of objects. The controller passes it along to the view and it gets displayed.
In the case of an insert, a new data transfer object is instantiated upon post back and is updated with the posted values. Then sent back to the the data layer for persistence.
In the case of an edit, it comes from the data layer on the HTTP GET request and is used to pre-populate the HTML form. Then on post back, the data transfer object gets updated with the posted values and sent back to the the data layer for persistence.
Definitely checkout NerdDinner or Stephen Walther's samples.
I have an MVC application. Say for example if we have a dropdown Cars makes which when selected posts to itself and gets Car Models. Now on post, the field Car makes loses it value. I am using Form.Get("combo_box_field_name") and if it has a value I am prepopulating the car make dropdown. As lot of controls on my form do this sort of post and i have to prepopulate the fields , I was wondering if this is the right way of doing stuff. I have done loads of asp classic works and also asp.net and looks like mvc is very similar in approach tp classic asp. If someone can guide in in the right way this can be handled it would be greatly appreciated.
I am not looking to use AJAX so pls dont tell me with regard to cascading dropdowns and I have a host of other controls in the form which will need updating on the form being posted to itself before I leave the page to save the data
I don't think I've ever used Form.get in my MVC application.
I post back to the controller which looks like;
[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult MyAction(FormCollection collection)
{
MyClass myClass = new MyClass();
UpdateModel(myClass);
//do stuff with data
return View(myClass);
}
So basically you're letting MVC grab the data from the view for you.
You may need to reload your dropdown lists with this but you can get around that by using JSON to do partial postbacks.
I've been playing around with the ASP.NET MVC Framework and the one thing that's really confusing me is how I'm meant to do server side validation of posted form data. I presume I don't post back to the same URL, but if I don't, how do I redisplay the form with the entered data and error messages? Also, where should the validation logic go? In the model or the controller? This seems to be one of the few areas where web forms are much stronger (I miss the validation controls).
Here's an overview of the flow in MVC:
/new - render your "New" view containing a form for the user to fill out
User fills out form and it is posted to /create
The post is routed to the Create action on your controller
In your action method, update the model with the data that was posted.
Your Model should validate itself.
Your Controller should read if the model is valid.
If the Model is valid, save it to your db. Redirect to /show to render the show View for your object.
If the Model is invalid, save the form values and error messages in the TempData, and redirect to the New action again. Fill your form fields with the data from TempData and show the error message(s).
The validation frameworks will help you along in this process. Also, I think the ASP.NET MVC team is planning a validation framework for the next preview.
You might want to take a look at ScottGu's latest post for ASP.Net prev 5. It walks through a validation sample that is very interesting:
http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx
As far as I can tell everyone is still trying to figure out the "standard" way of doing it. That said definitely check out Phil Haack and Scott Guthrie's latest posts on MVC and you'll find some interesting info on how they did. When I was just playing around with it for myself I created a ModelBinder for the LinqToSql data class that I had generated. You can check out this post to find out how to put together a basic ModelBinder:
ASP.Net MVC Model Binder
The in your action if you had created a "Product" ModelBinder you would just declare the action like so:
public ActionResult New(Product prod)
And the model binder will take care of assigning posted data to the objects properties as long as you've built it right anyway.
After that within your GetValue() method you can implement whatever validation you want, whether using exception's, regex's, or whatever you can make a call like:
(ModelStateDictionary_name).AddModelError("form_element_id", "entered_value", "error_message");
Then you can just throw a <%= Html.ValidationSummary() %> in your view to display all your errors.
For client-side validation I just used jQuery. After you get a basic sample set up though you can start doing some interesting things combining all that with Partial Views and Ajax calls.
Have you taken a look at this?
http://www.codeplex.com/MvcValidatorToolkit
Quoted from the page
The Validator Toolkit provides a set
of validators for the new ASP.NET MVC
framework to validate HTML forms on
the client and server-side using
validation sets.
I'm afraid that someone more MVC-savvy than me would have to speak to where in the architecture you should put things.
I'm just learning the MVC framework too so I'm not sure how off this is, but from what I understand you would have a form on a View such as Edit.aspx. This form would then post to the controller to another action method such as Update() passing in the contents of the form that you set in Edit.aspx as parameters.
Update(int id, string name, string foo)
You could do the validation within that method. If all is ok,
return View("Item", yourObject)
There is Castle.Components.Validator module in Castle project. It's very agile and powerfull. It generates validation rules based on model attributes (or any other source) and even able to generate JS validation using jQuery, Prototype Validation, fValidate and other.
Of course it's wise to abstract validator away behind IValidationEngine interface.