I need to understand the best practices of MVC architecture implementation. I'm a Java and C# programmer. I know the basic of MVC. But i'm sorta confused on how to implement it. I know how to make a simple MVC based calculator. But here's the thing.
I wanted to make a simple database editor application using MVC. Should I construct a model and controller for every rows (objects) of the table? If so, how about the view of every objects? How do i handle them being deleted, updated, and inserted. And should I make the model and controller for the editor which is also a view?
If you don't want to use the Java Persistence API, consider using a Class Literals as Runtime-Type Token in your TableModel.
At first, if you are comfortable with Java try the Spring MVC. There are a lot of tutorial regarding this. If you are much more confident in C# try ASP .NET MVC 3. I will prefer the later one as in this case you have to deal with less configuration.
Now I will answer your question one by one.
At first create a model for every table in your database. Actually these models (which are nothing but classes) when instantiated are nothing but an individual row of the respective table. Your ORM (object relational mapping) tool (For java you can use hibernate, for c#.net you can use entity framework) will provide you specific methods (save(object), add(object), delete(object)) for updating the database
Now each controller should work with a specific model (Here I am ignoring the complexities of using multiple models.). But it may generate numerous views. By clicking a link in your view page you actually invoke the related method in the controller. The controller than binds the Data (if any) with the specific view realted to that link and then the view is rendered. So for deleting a row there should be a method named delete() (you may name it anything you want, so dont be confused) in your controller. When you want to delete a row invoke that method and inside the method remove that row by using something like delete(object) (these methods will be provided by your ORM) and then return another view. The same thing is applied for adding and updating data. But each method may generate different views. Its upto you that which view you return in each of these methods.
I hope the answer helps you. Cheers !!!
Related
I'm working on a small project that is using MVC 5. I have a Projects/Details page which displays information of a given project. Each project have multiple members and there can be 3 member types. These types have different information and functions available on the page. My current temporary solution is basic, in my View I have an if statement to check the type of the logged in user and show a partial view accordingly. To me this solution feels kind of "hacky", I'm sure there's a better way. So my question is: how would you go about implementing such functionality?
Thanks.
There are three ways in which you may want to approach this.
1) Even if you think your proposed solution is "hacky", it is actually not a bad idea. I personally did it in a project. I created partial views depending on the roles a user had; however, you'd be adding extra business logic to the view. Try experimenting with it, and see how it performs when deployed. This should be your first try since it's actually your idea, and by experimenting you'll learn considerably.
2) Have you tried checking in the controller for a user's roles, and depending on that role returning a specific view? In this case, the business logic will remain in the controller, and it is considered a good practice.
3) Even if I don't know whether you are using an ORM (Entity Framework) or connecting directly to a SQL database, try retrieving a member's roles using a stored procedure and checking for its roles in a DB handler class.
As you may see, there are three options to check for a member's roles.
Finally, I recommend you reading about claims/roles-based authorization. It may help you in future projects:
https://www.c-sharpcorner.com/article/Asp-Net-mvc5-role-base-accessibility/
(Using ASP.NET MVC, C#, fairly new to the environment)
I have a controller that creates a row in a table, say a person, and then another controller that creates another row in another table that creates something that has a one to many relationship with the other table e.g. a course that contains many people.
When I create a new course in my web application, I want to be able to link to adding a person to the course, either an existing person or a new person. So I link from the course detail controller to the person controller. Then I want it to remember where it came from so I could go back to the course page and show the newly added people.
In the spirit of DRY, I wouldn't want to make a separate controller and view for creating a person within the course class. What's the proper way to get the person controller to return to the course controller when it's finished? Some kind of delegate? In iOS (which I am more used to) you might accomplish this by loading in the view modally and then assigning a delegate, and then calling the delegate if it exists and dismissing the view. Is there anything analogous here?
Thanks
In the TRUE spirit of DRY, wouldn't you want to encapsulate each of your creation methods in a respective DAL and then call them directly from your controllers as they are required? It seems as if you are embedded data access and business logic layers into your controllers. I know this is a popular approach in tutorials and simple applications, but I believe it causes long term issues (such as the issues you are running into now). My recommendation is to move your business logic back a layer and save yourself a controller redirect.
EDIT:
You can handle the CRUD data access on your entity models at a point that is deeper in your application than your controllers. In fact, many people would argue that to do so is correct separation of concerns. What I am suggesting is building a Data Access Layer that modifies your entity objects a layer removed from your controllers. That way your data access does not bloat your controller and you can call multiple types of data access methods from various controllers.
I'm trying to build a web application that let the administrator talk to the database through C# and add new tables and columns to fit his requirements (sort of a very simple database studio) but I'm not trying to just create some spaghetti application.
So I'm trying to figure out how to let those things dynamically (automatically) when he creates a table and use the table to build them :
1- The business objects or entities (the classes, it's objects and properties).
2- The Data access layer (some simple methods that connects to the database and add, update, delete retrieve items (objects)).
Is this possible ? any pointers on how to achieve it ?
EDIT
just opened your link!! .. it's talking about the data bound controls and stuff! .. my question is way more advanced than that!.
when you build an N-Layered application you start with the database schema and implementation and it's easy to do programtically then you start building the DAL classes which (add, edit, etc in other words the CRUD operations) in and form this database
what I want to do is to allow the web administrator to choose add the new table through my application and then -dynamically- the application would take the tables names and columns as parameters and create new classes and define within them the CRUD methods that will implement the SQL CRUD operations
then it would also create dynamically the classes and define within them the variables, properties and methods to call and use the DAL methods .. all this based on the table, column names
NOTE : All this happens on the run-time!
You might want to look into ASP.Net Dynamic Data. It's a RAD tool which very easily gives you CRUD functionality for your entities and more. Check it out.
Sometime back I had also asked similar question on SO. I got only one reply.
Today I was digging some information on MSDN and as I had guessed it, MS CRM entity model works based on metadata. So basically whatever a CRM developer is working against is just metadata, they are not real objects as such. Following is the MSDN link.
Extend MS CRM Metadata and here is the MS CRM 4.0 SDK.
I hope this should get you started.
Update: Recently hit upon Visual Studio LightSwitch. I think this is what we wanted to build. A UI which will pick up table information from DB and then create all CRUD screens. VS LightSwitch is in its Beta1 and has quite a lot of potential. Should be a nice starting point.
First, any man trying to create MS Access is doomed to recreate MS Access. Badly.
You are better off using ASP.NET Dynamic Data (as suggested) or ASP.NET MVC Scaffolding. But runtime-generated playforms that actually make decent applications are really pipe dreams. You will need developer time to do anything complex. Or well.
What you are asking is non-sense. Why? Because the idea behind BLL and n-tier is that you know your data model well, and can create a static class model to represent your data model.
If your data model is dynamic, and changing, then you cannot create a static BLL (which is what a BLL is). What you will have to do dynamically build your queries at run-time. This is not something that any of the traditional methods are designed to handle, so you must do everything yourself.
While it's possible to dynamically generate classes at run-time, this is probably not the approach you want to take, because even if you manage to make your BLL adapt to your dynamic database.. the code that calls the BLL will not know anything about it, thus it will never get called.
This is not a problem you will solve overnight, or by copying any existing solution. You will have to design it from scratch, using low level ADO calls rather than relying on ORM's or any automation.
I've posted a few questions over the months about structure of ASP.NET applications and Database-Abstraction-Layers, for the purposes of rewriting (from the ground-up), a legacy web application. I've recently stumbled on MVC3/Entity-Code-First and after spending some time with it, have fallen in love with how it works, how things are abstracted out, and I'm looking for any excuse to use it!
The legacy application is a C++/CLI windows service that generates it's own HTML (very old-school HTML at that with CSS just used for colours, and tables-abound), and with interface very tightly coupled to business-logic. Basically, anything is going to be an improvement.
However, and perhaps this is because I have not spent enough time yet with MVC, I have a few nagging doubts and wondered if some of you MVC-Pros could waft their experience in my direction.
The legacy app uses custom controls (it's own form of them) to bind combo-boxes to data, and dynamically repopulate dependent combo-boxes based on selections in another. In ASP.NET, this question is answered easily as one just throws an asp:DataList control on the page, binds it to a data source and voila. A bit of simple code allows you to then filter other combo boxes on the selected value. It also would be easy in ASP.NET, to implement another data-list that even automated dependent data in this fashion (which would mimic the behavior of the legacy app quite nicely). I can't seem to find a notion of custom controls in MVC, though I assume this kind of stuff is handled by jQuery calls to get data and throw it in to a combo box. But is this done for every combo-box on every page that has one? Is this a case for partial views with appropriate parameters being passed, or this just stupid?
I guess this relates more to the Entity Framework than MVC, but most of the examples I've found on the web, and tutorials, perform LINQ queries to return a collection of objects to display, e.g this, from the MvcMovie example:
public ActionResult Index()
{
var movies = from m in db.Movies
where m.ReleaseDate > new DateTime(1984, 6, 1)
select m;
return View(movies.ToList());
}
Which is then rendered using a #foreach loop in the view. This is all great. The legacy application has a single browse page that is used by all the other areas of the system (there are over 50). It does this by inspecting the column order defined for the user logged on, flattening any foreign keys (so that the field on the foreign table is displayed as opposed to the non-user-friendly primary key value) and also allows the user to apply custom filters to any column. It does this also for tables that have upward of 100k rows. How would one go about writing something similar using the Entity-framework and views? In ASP.NET I'd probably solve this by dynamically generating a grid view of some sort and have it auto-generate the columns and apply the filters. This seems like it might me more work in MVC. I am missing something?
The legacy application has several operations that operate over large sets of data. Now because it was a service, it could launch these threads without worrying about being shut-down. One of my questions here on SO was about static managers being around and the introduction of an AppPool recycle, but I have decided that having an auxiliary service is a good option. That said, the legacy app applies an update statement to large groups of records rather than single rows. Is this possible with Entity-Framework without writing custom SQL against the database that bypasses the normal models? I hope I don't have to do something like this (not that I would, this is just for example)
var records = from rec in myTable
where someField = someValue
select rec;
foreach(rec in records)
rec.applyCalculation();
db.SaveDbChanges();
I suspect this could take a lot of time, whereas the legacy app would just do:
UPDATE myTable
SET field1 = calc
WHERE someField = someValue
So it's not entirely clear to me how we use our models in this manner.
The legacy application has some data panels in the layout that get carried around whatever page you're on. Looking here on Stackoverflow, I found this question, which implies that every view needs to pass this information to the layout? Is this so, or is there a better way? Ideally, I'd like my layout to be able to access a particular model/repository and display the data in a side-panel. Adding to every view page could be quite repetitive and prone to error. Not to mention the time it would take if I needed to modify something. A partial view would do here, but again I am unsure how to pass a model to it on the layout page.
Finally, I was disappointed, after installing Ef-Code-First, to find that a really nice attribute, SourceName has not made it in, yet. This would be very nice in mapping against legacy tables/columns and I am not entirely sure why it has been left out at this point (at least, my intellisense says it's not there!) Has anyone got an idea when this might come about? I could do without it for a while, but ultimately it would be incredibly useful.
Sorry for the lengthy questions. After ages of investigative work in ASP.NET and MVC3, I really want to go with MVC3!
If I managed to extract the questions correctly then this would be my reply:
You are right in your thinking about master - detail dropdowns (or other controls, for that matter). jQuery AJAX/JSON calls (mostly GETs) will be what you need. If you only have one dropdown on your page, then of course you don't need that kind of interactivity - you can just prepare the model for it in your controller action (you create a SelectList object).
Here you would most likely end up using some kind of a grid system like jqGrid or Flexigrid. They do most of the stuff regarding filtering/searching/querying themselves. Still you will have to provide JSON controller actions that will be serving data.
Yes you can execute SQL via EF. There's ExecuteStoreQuery() and ExecuteStoreCommand(). Here's more on those http://msdn.microsoft.com/en-us/library/ee358769.aspx
You can call RenderAction() from the view and have this action prepare the data on demand (whenever you call it) and render out the Partial (or normal) view and feed the data (model) to it. RenderPartial() is a bit more clumsy with this - it requires you to have the model already available in the view in which you are calling RenderPartial(). RenderPartial() never goes back to the controller action - it just renders out that HTML defined in the template using the model you provided in its call from within the view.
Unfortunately I don't know the answer to this.
HTH
You might not like it, but it could make a lot more sense to just refactor the c++ application. Especially to the business. There's nothing wrong with generating html. Much easier to refactor to modern html/css than a set of templates.
Should i consider ASP.NET MVC ViewModels only containing flat and primitypes types or it should contains complex Core/Domain model types ?
I'm looking for best practices.
Thanks.
Do what makes sense.
There are no authoritative sources that will tell you that using ViewModel with primitive types is going to kill kittens, because they would be wrong. And for every expert out there who tells you that using ViewData with magic strings is perfectly OK, there will be purists out there who will tell you that strongly-typed objects are the only way to go.
I write applications that read from a database and display data in a web page. I have tried it both ways (using ViewData and using a ViewModel object), and I am happiest when I have a ViewModel object to project into the web page. The ViewModel class is a place to encapsulate things like validation and view logic, if I need them, and it provides the data structure and strong typing that I like.
If I just want to display a record from one of my Linq to SQL classes, and I don't need extras such as dropdown data lists, I might use the Linq to SQL object directly. But if I do have extras, I put everything into a ViewModel class, and project that ViewModel instance (or an IEnumerable or IQueryable of them) into the view.
So I seldom use ViewData, but that's just my style. It's nice to know that it's still there if I need it.