does it make sense to use KnockoutJS Viewmodels in combination with ASP.NET MVC3 or 4? Because it is not very DRY, isn't it? I have to write models for EF, Viewmodels for the MVC Views and Viewmodels for Knockout... and i lose a lot of magic. Automatic client-side validations for example.
Does it make sense to use MVC at all if one sticks with the MVVM Pattern?
With Knockout Mapping, you can automatically generate a KO view model from your MVC view model.
This is a proper pattern: your models are raw entities, your data. Your views are the UI. And your view models are your models adapted to that specific view.
This may be an unpopular answer, but I don't use ko.mapping to translate my C# POCOs into JS viewmodels. Two reasons, really.
The first is a lack of control. ko.mapping will turn everything into an observable if you let it. This can result in a lot of overhead for fields that just don't need to be observable.
Second reason is about extensibility. Sure, ko.mapping may translate my C# POCOS into JS objects with observable properties. That's fine until the point you want a JS method, which at some point, you invariably will.
In a previous project, I was actually adding extra methods to ko.mapped objects programmatically. At that point, I questioned whether ko.mapping was really creating more problems than it solves.
I take on board your DRY concerns, but then, I have different domain-focused versions of my POCOs anyway. For example a MyProject.Users.User object served up by a UserController might be very different from a MyProject.Articles.User. The user in the Users namespace might contain a lot of stuff that is related to user administration. The User object in the Articles namespace might just be a simple lookup to indicate the author of an article. I don't see this approach as a violation of the DRY principle; rather a means of looking at the same concept in two different ways.
It's more upfront work, but it means I have problem-specific representations of User that do not pollute each others' implementations.
And so it is with Javascript view models. They are not C# POCOs. They're a specific take on a concept suited to a specific purpose; holding and operating on client side data. While ko.mapping will initially give you what seems to be a productivity boost, I think it is better to hand-craft specific view-models designed for the client.
btw, I use exactly the same MVC3/KnockoutJS strategy as yourself.
We use knockout Mapping to generate the KO view models well.
We have a business layer in a separate project that does CRUD, reporting, caching, and some extra "business logic". We aren't going to be using EF, or something similar. Currently we've defined c# classes as MVC models, and our controllers call the business layer to construct the Models that are defined in the usual place in our MVC app. These C# models get serialized as JSON for use in our pages.
Since everything we do in the browser is c#/JSON based using knockout, we aren't using MVC models in the traditional MVC way - everything gets posted as JSON and serialized to c#, so we don't use MVC model binding, validation, etc. We're considering moving these models to our business layer so they can be tested independently of the web app.
Se we'll be left with an MVC app that has controllers and views, but no models - controllers will get models that are defined in the business layer. We're nervous about departing from the normal MVC structure, but a KO/javascript based client is fundamentally different from a DOM based client that MVC was originally built around.
Does this sound like a viable way to go?
I work now on project which mixes MVC3 and knockouts and I have to tell you - it's a mess...
IMO it's nonsense to force some patterns just to be up to date with trend.
This is an old topic, but now in 2014 (unfortunately) I still feel this question has a huge relevance.
I'm currently working on a project which mixes MVC4 with knockoutjs. I had some difficoulties to find whichs part should be handled on which side. Also, we needed a "SPA-ish" kind of architecture, where each module has its own page, but then inside that module there is only AJAX interaction. Also faced some heavy validation scenarios, and needed to provide user (and SEO) friendly URLs inside each module. I ended up with the following concept, which seems to be working well:
Basic MVC and .NET side roles:
Handling authentication and other security stuff.
Implementing the Web API interface for the client-side calls (setting up viewmodels, retrieving and mapping data from the domain, etc.)
Generating knockout viewmodels from my (pre-existing) C# viewmodels with T4 templates, also including knockout validation plugin extensions from .NET validation attributes. (This was inspired by this aticle). The generated viewmodels are easily extensible, and the generation can be finetuned with several "data annotation"-like custom or built-in attributes (such as DefaultValue, Browsable, DataType, DisplayFormat, etc.). This way the DRY doesn't get violated (too much).
Providing strongly typed, but data-independent partial view templates for each submodule (each knockout viewmodel). Because property names on C# viewmodels are same as in KO models, I can benefit from the strongly typed helpers specifically written for KO bindings, etc.
Providing the main view for each module similarly to previous point.
Bundling and minification of all scripts and stylesheets.
Basic client-side roles:
Loading the initial state of all viewmodels encapsulated into one module page, taking the whole URL into account with a simple route parser implementation.
Handling history with history.js
Data-binding, user interaction handling.
Posting relevant parts of viewmodels to the server, and processing the returned data (usually updating some viewmodel with it).
I hope this could help anyone else who feels lost in the world of trendy technologies. Please, if anyone has any thought on this, feel free to post any question or suggestion in the comments.
Related
Just to prefix this question, I've decided to take a look at moving our works old legacy systems (40+ programs from vb6, vba, vb.net to c#.net) into two separate systems using the same DAL (barcoding terminals and one web based system) as I spend most my day fixing crummy or non existant business logic in 15 year old vba programs. I've recently built an entity framework model complete with fluent validation and couldn't be happier with it after using it for a bit.
The small team is familiar with webforms (but not very) but the last few days I've explored MVC Razor. I was loving MVC Framework until I tried to start trying to add more functions onto the same page and then it seemed arbitrarily hard to replicate our a recent system I put in a webform. Before, I would eager load a customer and all it's child entities and then bind that to single page for the customer so they could access everything (which is what they wanted), it works okay and isn't slow. From this single page I could edit all their account details/contacts/emails/phones/jobs.
All the examples I've done and seen in MVC handle a single update, a single edit etc but surely you can't separate out every single action into a new view/page? I can pass a rich model through to the view in MVC, but then its a pain trying to update all the different child entities.
This is probably the exact design that MVC wasn't designed for maybe, which is okay, I'm willing to adapt it if MVC will be a better platform going forward, but how are you meant to handle adding this complexity in? Some methods I've seen:
Lots of partial views? passing child info to them (or the id and lazy loading it)?
I've seen methods that wrap multiple <forms> around everything and handle actions that way.
Separate pretty much every task out
If the solution is more lightweight and easier to maintain I'll go research whatever I need to I just wanted at an earlier stage to see if I'm wasting my time. Any pointers to the correct questions I should be asking would be greatly appreciated.
ASP.NET MVC is neither more or less better equipped to deal with complex pages than any other technology out there.
Certainly, MVC requires more low-level work than a Web Forms app, with no direct binding support, but in most cases this is a good thing and provides much more flexibility in how your page is rendered.
One of the whole ideas of MVC is to give you more control over things, but that control leads to requiring more knowledge and more effort on your part in most non-trivial cases. MVC provides a number of tooling functions to speed up trivial work (like creating standard table based CRUD) but when you have complex models, you will have to do much of the work yourself.
This is not that MVC is "ill suited" for it, but just that control and flexibility has a trade off with more responsibility on your part.
In your case, you simply create a view model with all the fields you want. Then, you create your form to edit those fields. In your controller, you will need to unflatten that view model and create or update the necessary records in the database. It's not difficult, but it's more work than WebForms databinding.
You could look into more advanced tools (commercial) for MVC, such as Telerik's tools, which have developed more of a databinding like interface, but MVC is not a drag-n-drop technology, and requires you to hook things up and write the various logic for what is done.
If you need drag-n-drop, databound functionality, then no.. MVC is not the correct technology. But then WebForms requires you to accept many compromises as well, and ties your hands in many ways.
You could use partial views, however I seldom use them. I prefer to instead use Editor/DisplayTemplates as these take care of naming your form fields correctly, even for collections and complex objects. PartialViews tend to have lots of gotchas if you aren't careful. I pretty much only use them as fancy includes, or when using Ajax.
I'm not sure what you meay by "wrap multiple <forms> around everything`. You cannot nest forms in HTML, it's not legal. If you mean place a form around each row of a table, that isn't valid html either in most cases (it's not legal to put a form in a between the table and the tr).
It would help if you had a specific problem that you could ask about, vague objections don't help us solve your issue.
You can accomplish anything in MVC that you can in WebForms. The difference is MVC will usually require you to write more code as it doesn't really offer you any "controls" to drop on your page.
In WebForms, it's easy to create a master/detail view with a GridView, FormView and then wrap everything in an UpdatePanel for automagical AJAX support.
In MVC, while you do have helpers like the WebGrid and AjaxHelpers extension methods, creating views and/or pages requires more understanding of how things work to get the desired functionality. When I start a new MVC project, here's what I include:
Backbone.js - client-side "ORM" that performs CRUD operations
against RESTful* APIs
Knockout.js - client-side view models and
real-time data-binding for your views
Knockback.js - wraps
Backbone models in Knockout view models
Using these three frameworks, you can quickly create powerful single-page apps using MVC and WebAPI.
The more I read into Asp.Net MVC the more layers and components I find out are required in order to make my application follow all of the standards and best programming practices.
It's starting to get a bit confusing because some of the new layers don't seem to fit in as easily as the others I learnt. So I just wanted someone to go over all of the required/recommended layers for an Asp.Net MVC application- what purpose they serve and how they interact with the other layers.
Here's a few of the layers I've found and how they link up:
(Some of them may be wrong)
View/UI --> Model Binder --> Controller --> Service Layer --> Repository --> Entity Framework/LINQ to SQL --> DB
Could someone go over ones I may be missing, how they all link up, and what each of their purposes are?
Thanks,
Matt
Good question, I think you covered all the layers I have seen: Modal binder and service layer are optional.
Maybe, you can add another Error Handling layer such as elmah.
View/UI --> You put your html markup / Javascript code.
Model Binder --> You perform the magic to bind your input to the action parameters, normally, you will use the default binder, so you don't need worry about it. However, you can override this with your own binder, and do validation in this layer. Here is a good example on this.
Controller --> Enough documentation online.
Service Layer --> A lot of people do validation and other business logic processing here before sending it to repository. Asp.net mvc contact manger example has a good example here. This is also the layer to actually work with your modal.
Repository --> Simple read/write operation.
Entity Framework/LINQ to SQL --> DB - Actually writing to database. Nhibernate is another good candidate here.
First of all, I think software and patterns have a tendency to overcomplicate things. As the ASP name implies the main idea of the framework is Model-View-Controller (MVC). You could be able to put a lot of things between these components, including DBs, Services, APIs, etc. However, the main concept of the Model-View-Controller pattern is pretty simple: Separate those functionalities into modules so the project could be easier to mantain.
MVC could be applied to ANY programming or scripting you do. Even for a shell script MVC could be helpfull. Here are some examples of each one:
View - Here is how the user interacts. It could be a web page, and Windows Form, or a command line interface.
Controller - The brains of the program, it should be aware of everything, but should be pretty simple. It basically gets messages or events from the view and/or model and decides on what to do. Good controllers are basically a dispatcher of events. Depending on events, it call view or model methods. In ASP MVC, the controller is the one providing the ActionResults for the View and interacts with the Model.
Model - This is basically where the data is. This could be a DB, file system, a Web Session, or memory.
Now the good part. The Controller does not care how the View is managing the interaction with the user. It could be a command line interface or a web form. The Controller does not know how the data is stored, it does not matters if it is a DB or a file. It just request data and pass it to the View. It not of its business to know how the view is getting the inputs, or the model the data.
Then the question, Why the hell do we want to overcomplicate things with this pattern? Well, Imagine that you have an MVC application using a MySQL DB and know you want to use SQL Server. What module you should change? Obviously the Model is the one affected. The Controller and the View should not have any major impacts. Now, imagine that you have another MVC application using Windows Forms, and now you want to change it to Web Forms? Well basically the View is the one that will be affected (and some parts of the controller), but your Model should be the same.
In summary, MVC is a great pattern, and it should be used more. However, I think there are some projects which are not suitable for MVC due its simplicity. It will be like building a laser to kill flies. Of course you will kill them, but the effort is not worthy on all cases.
Is it considered a bad practice to use code-behind with ASP.NET MVC Views? Got into a bit of a debate about this with my colleagues today and I was wondering the community's thoughts.
Obviously, this isn't an option when using another MVC like Rails, which makes me think it's relied on more as a crutch for those accustom to working with traditional ASP.NET Web Forms applications.
I would say that it's a bad practice to use code-behinds with ASP.NET MVC. MVC allows separation of concern where presentation logic (in Views) are separated from application logic (in Controllers). Using code-behinds will mix presentation logic and application logic inside the code-behinds, whereby defeating some of the benefits of MVC.
Certainly the authors of ASP.NET MVC In Action advise against it, and I agree. It isn't necessary, so why do it? In the early betas a code-behind file was included, but this was removed at RTM (or shortly before).
Typically, it simply encourages you to do more non-view work than you should in the view, as it is out of sight / out of mind.
I used code-behind extensively on my first ASP.NET MVC (Preview 3!) project - primarily for doing stuff like casting ViewData["foo"] into strongly-typed data objects, gathering view data into IEnumerables so I could loop across it, that kind of thing.
With the introduction of strongly-typed views, and pragmatic use of the (horrifically-named) Model-View-ViewModel pattern, I haven't missed code-behind at all since it was removed from the project framework just before the final release.
I now strongly feel that whatever processing you're doing in your view's code-behind, you are far better off modelling the result of that processing in your ViewModel, allowing the controller to perform the actual processing, and keep the view as simple and lightweight as you can. That'll let you test the processing logic, it makes the views easier to modify, and creates - I think - a much more elegant separation between transforming your data for display, and actually displaying it.
Yes the codebehind has long been the secret hiding place of business logic which as we all know should not be at the View level.
Code behind has been removed to stop naughty developers from being tempted.
I would recommend avoiding the codebehind in an MVC app at all costs. Using the code behind negates some of the values you get by using the MVC Framework such as separation of concerns, etc. You want to have your data access, business rules, type conversion and that sort of thing applied in the Model. If you find you need to convert your data types like Dylan mentioned, you may want to make ViewModels. The ViewModel would basically be the data from the actual Model you would like to display, in the format you wish to display it in.
Its probably best to avoid putting anything in the code behind when using MVC.
I would be interested to hear which part was being debated about, to go in the codebehind?
If you new to Asp.Net MVC, I really recommend spending some time going through the Nerd dinner example. There's a free EBook and source available here http://nerddinner.codeplex.com/.
Creating the simple demo from scratch is a great way to learn.
After doing this, it may shed some light on where the code you have in the codebehind, could alternatively go.
Note: If you do follow the EBook, grab the latest site.css file from codeplex, otherwise the virtual earth maps won't be aligned properly.
HTH
Ralph
It should be noted that "Code Behind" is a feature of the Web Forms view engine. It really has nothing to do with ASP.NET MVC itself.
For example, the Razor view engine in MVC3 does not even support it.
I would answer your question this way: If you cannot switch view engines without rewriting your controllers (or even your models) then you are not using the MVC pattern correctly.
Probably most of what you are doing in the .aspx.cs file should really be done before the model (or View Model) gets passed to the view. That said, in projects that I have migrated from ASP.NET Web Forms to ASP.NET MVC, I left a lot of the Code Behind in place. For example, I find it cleaner and more pleasing to use a Repeater control than to try to use a 'for' loop in Web Forms. I am still just iterating over View Model data after all. So why not? Separation of concerns is preserved (perhaps to a greater degree in fact).
I mean, why should "best practice" for Web Forms suddenly be the wrong way to do a Web Forms View? As a simple example, consider a Repeater that assigns a different CSS class to every second row of a table. Why should my controller (or even my model) care? Trying to put this kind of logic inline in Web Forms quickly devolves into tag soup and complete spaghetti. Now imagine something more complicated.
I have left Master pages in place that build the menus in the code behind. Again, all data comes from the View Model. I do not see why using GridView or other controls in this way should be a problem either.
I usually disabled ViewState in Web Forms anyway and did the data binding in "Init". Still, there would often be a small ViewState that I could not get rid of. I put some code in "Render" that moves this to after the form (it defaults to before). When moving to MVC, I sometimes left this code in. So, I have ASP.MVC sites that do indeed use Code Behind. I am just careful that it code that is specific to the view.
On new projects, I generally have found less of a need for Code Behind on most pages. Thankfully, view engines like Razor have made mixing code and mark-up in-line a lot less painful to write, read, and maintain.
What are the basic differences between classic .cs-aspx.cs-aspx (code behind/beside) model and new MVC model?
The basic difference between MVC and classic ASP is that in classic ASP all of the code and mark-up for the application exists in the .asp file. In MVC the .aspx file contains only the code and mark-up for rendering the page. The rest of the application for handling requests, retrieving model data, and enforcing business logic exists in controller and model classes. These classes can be much more easily tested than class ASP code because it is separated from the code that is responsible for rendering the view.
This separation of concerns is the basis of the MVC pattern. According to the pattern, the code is divided into three major components -- Model, View, and Controller. Classes in the model represent the business objects for the application, the persistence framework, and business logic applied to the business objects. Classes in the controller accept incoming requests, use the inputs or query parameters to retrieve the appropriate model data, and generate the necessary data for the view to render. Views (aspx pages) take the data supplied by the controller and generate the mark up.
Webforms (codebehind) is somewhere between classic ASP and the MVC pattern. Webforms does not enforce the separation of concerns in the way that MVC does, but it does allow much more of the code to exist "behind" the actual page. For example, you can separate out the business objects, business logic, and persistence framework (the Model, if you will) from the code that is responsible for generating the view. The difficulty is that the controller actions (input handling and model retrieval) are still linked with the view rendering code. This integration makes it much more difficult to test this code and makes the view/controller code much more dependent on each other than is necessary -- the concerns are "mixed", not "separated." In general, this is evidence of bad design because it make it more difficult to make needed changes in the future.
Hope this helps.
Simply put it this way: MVC is how really web apps should be built. Code-behind (asp.net web forms) is not a good practice. If you are truly a developer you will appreciate that the MVC is the best practice since it really separates logic from data and presentation. Simply MVC is the elegant and right way.
A really simple way to perceive the difference between MVC and ASP (or ASP.NET forms for that matter) is that in MVC the Controller is the handler of the request.
Requests get routed to a controller not a 'page' or a 'form'. The controller will pass along info in the request to the model then make some simple choices as to which view that should be used to present the desired state of the model. Note this is the important point the controller has a choice of what view to use in the response.
MVC breaks the relationship between the requested URL and the UI code needed to render a particular representation of data.
Looking at MVC framework, it seems we require more of classic ASP knowledge then ASP.NET postbacks and Viewstates. Are we moving backwards to complex UI + code logic in the actual frontend HTML markup?
We're moving back to not trying to abstract away fundamental concepts like HTML and HTTP Requests. On the UI end, that translates into the Views being more tightly integrated with the output, which isn't a bad thing. the classic ASP model translated into having everything tightly integrated with the output, which is a bad thing.
One could argue that the MVC paradigm is a step backward if you consider the ASP.NET paradigm a step forward, I guess. Personally I always thought it was much easier to write clean separated code in classic ASP, rather than .NET where display output text usually got mashed into code blocks where it was impossible to access with a standard HTML editor. I always thought the ASP.NET architecture was more about pushing .NET than improving the overall structure of we application, so in that sense MVC is a step forward.
This is funny that you mention this ... I was having the same conversation with a co-worker today.
Is it a step moving backwards? I don't think so ... while in classic asp you had a some complex logic in the UI, from what I can see with MVC, the complex logic should still be in your business objects, and any complex interaction with the object should be done via the Controller.
The goal, again, from what I can see, is to keep the UI trim and fit when it comes to actual business logic. Any additional bloat would be caused by making the UI more user friendly, with the likes of AJAX and JQuery.
This is just my initial observation regarding MVC. It is a very cool technology, especially with how it sits on top of REST, makes it very easy to work with from other technologies.
I'm looking forward to trying it out in a couple of future projects!
If you are seeing complex code logic in the View relative to the Models and Controllers, than perhaps you are approaching it the wrong way.
In the pure sense, you should be able to switch out the view (XML instead of HTML let's say) with minimal work. That could only happen if the data logic is contained in the models and the business logic ins contain in the controllers.
So, if you were displaying a shopping cart, the view might only have code that writes out the product quantities and totals. The model class(es) would hold the product data and the controller would do all the processing such as adding products and checking out.
The entire point of MVC is for separation of code. Models should contain all of your business logic, the View should just handle the output to the user, and the Controller should glue those two pieces together.