It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am trying to use ASP.NET MVC without EF and possibly without LINQ. To start with I created just one table/model/controller/view on basic ASP.net mvc template in VS2010(Just index page and Index method is implemented). I am currently going with try/error as all tutorials on the web are based on EF and I have an embedded c background.
My questions are:
Is the architecture correct?
I saw repository pattern is used in some open source projects such as nearforums. What's its advantage and how does it fit into this, does it replace DAL?
Should I pass datatables to view or objects representing the datatable?
Can I pass more than one model to razor page? How can I list 2 different tables for example?
Is it better to put all DAL code in one file?
DAL:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Configuration;
using MySql.Data.MySqlClient;
namespace MvcApplication1.Models
{
public class DAL
{
public DAL()
{ }
public DataTable getDataTable(string tableName)
{
using (MySqlConnection conn = new MySqlConnection(ConfigurationManager.ConnectionStrings["MySQLConn"].ConnectionString))
{
using (MySqlCommand command = conn.CreateCommand())
{
command.CommandText = "select * from " + tableName;
command.CommandType = CommandType.Text;
conn.Open();
var table = new DataTable();
table.Load(command.ExecuteReader());
return table;
}
}
}
}
}
Product.cs class that represents Product table in the code:
namespace MvcApplication1.Models
{
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Producer { get; set; }
public int UnitPrice { get; set; }
}
}
ProductController.cs
namespace MvcApplication1.Controllers
{
public class ProductController : Controller
{
//
// GET: /Product/
DAL dal = new DAL();
public ActionResult Index()
{
DataTable dt = dal.getDataTable("Product");
Product[] products = new Product[dt.Rows.Count];
for (int i = 0; i < dt.Rows.Count; i++)
{
products[i] = new Product();
products[i].ProductId = (int)dt.Rows[i]["ProductId"];
products[i].Name = (string)dt.Rows[i]["Name"];
products[i].Producer = (string)dt.Rows[i]["Producer"];
products[i].UnitPrice = Decimal.ToInt32((decimal)dt.Rows[i]["UnitPrice"]);
}
return View(products);
}
........
........
}
Index.cshtml:
#model IEnumerable<MvcApplication1.Models.Product>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ProductId)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Producer)
</td>
<td>
#Html.DisplayFor(modelItem => item.UnitPrice)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ProductId }) |
#Html.ActionLink("Details", "Details", new { id=item.ProductId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ProductId })
</td>
<br>
</tr>
}
I saw repository pattern is used in some open source projects such as nearforums. What's its advantage and how does it fit into this, does it replace DAL?
The benefits of the repository pattern are that it allows you to switch out your data access logic/ORM. For example, if you wanted to switch from Entity Framework to NHibernate, you just update your registrations inside you IoC container and like magic your code is using NHibernate with 0 knowledge of you ever making the switch. It allows your code to be agnostic of the underlying persistence framework. For all it knows, results code be coming from a file, web service call, or an in memory list. You'll also get reuse in the event that you had to make the same query from another component. Another gain is unit testing. With your current implementation, you cannot unit test your controller as it's going to connect directly to your database every time, thus by definition making it an integration test. You will certainly want to leverage an ORM, or you'll be writing the same code over and over again until it makes you cry. Setting up/tearing down connections, type casting all your primitives to native .NET types, etc. Dealing with native ADO.NET is a thing of the past nowadays. Make your life easier and use an ORM. At the same time, with great power comes great responsibility. ORMs can be a nightmare if you don't validate the queries that are being generated and executed against your database. If not used properly, they'll generate performance problems. You'll be able to leverage LINQ for most of your queries, but sometimes you'll have to get dirty funky native and go with raw SQL. You ORM will still be able to handle both scenarios.
Should I pass datatables to view or objects representing the datatable?
You certainly don't want to pass datatables. You want to pass view models or entities to your view. The view should know nothing about the database. All you do is give it data, and it displays in on the screen not ever knowing the source of that data. You want to be careful with passing entities directly to your view if you're using something like NHibernate, because you run into problems associated with lazy loading and N + 1 queries. View models are typically slimmed down versions of your entity. For example, if you had an entity with 4 properties but the view only needed to consume 2/4 of those properties, you'd make a separate view model with 2 properties and use a mapping library like Automapper to map from your entity to view model.
Can I pass more than one model to razor page? How can I list 2 different tables for example?
This is quite simple. You make a top level object and give it 2 properties to represent the entities you want to access.
public class MyViewModel
{
public Entity1 FirstObject { get; set; }
public Entity2 SecondObject { get; set; }
}
Then you'd make a strongly typed view and render FirstObject and SecondObject using the strongly typed view helpers you used in your razor view posted in your question. #Html.TextBoxFor(), etc.
Lastly, your controller would accept MyViewModel as an argument and populate FirstObject and SecondObject based on the form inputs rendered in your view.
Is it better to put all DAL code in one file?
You want to put related DAL code in the same file. Things are typically mapped out by table but that all depends on the relationships between your objects (what's your aggregate root for example). What you don't want to do is blindly implement one repository per table. You'll just end up with a really procedural and anemic data model that results in stitching together object graphs and relationships via multiple calls to the database. I'd recommend looking into Domain Driven Design to get a good idea on how to tackle this problem.
I've just scratched the surface here. You'll basically need to pick up the latest patterns and practices if you want to do this stuff properly. It's a different movement all together. Not like the good old days of monolithic code behind files, view state, and DataGrid controls. There are some really good books out there like:
Brownfield Application Development
Domain Driven Design (Eric Evans)
Clean Coder (Robert C Martin)
Refactoring: Improving the Design of Existing Code (Martin Fowler)
Patterns of Enterprise Application Architecture (Martin Fowler)
I'm not saying read all these books verbatim, but I'd strongly recommend the first 2. I'm sure the community will have even more to say about these development practices, but this is my perspective on it all. Thanks and good luck.
Related
Translate code in Laravel to asp.net mvc. I am passing a subset of the model and summarizing the fields by year. My EF model has 50+ fields.
This is my Laravel route:
Route::get('/metrics', 'MetricsController#index');
My Laravel Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class MetricsController extends Controller
{
public function index()
{
$metrics = DB::select('select year(date_id) as Year, Sum(Revenue) from metrics Group By year(date_id)');
return ($metrics);
}
}
I would like to display the model data in a #foreach loop in the view? The dump in the Laravel view displays the data in the following way.
[{"Year":2009,"Sum(Revenue)":"61302670.65"},
{"Year":2011,"Sum(Revenue)":"68397989.00"},
{"Year":2012,"Sum(Revenue)":"69245803.00"},
{"Year":2013,"Sum(Revenue)":"67184051.00"},
{"Year":2014,"Sum(Revenue)":"33445434.00"}]
I will keep it simple, sticking to the fact that you need to show the data in the View. For that, I will assume that you already have your DbContext, Models and data loading parts ready.
Model
I will create a sample model just for the sake of example. But it could, obviously, be more advanced.
public class Result
{
public string Year { get; set; }
public decimal SumRevenue { get; set; }
}
Action Method (in the Controller)
The most important here is the fact that you are loading a "List of" model as result of your query. As you are using EF, you could load it directly from your DbContext or probably use a repository pattern. Since we don't know, I am just making a simple method call so just imagine the DB logic is in there :)
public ActionResult Index()
{
// Here is where you load your data. I am using this line just as example.
List<Result> resultList = RandomLibrary.LoadData();
return View(resultList)
}
View
Remember to prepare your View to receive the List you got in the Action Method.
#model List<Result>
#foreach(var item in Model)
{
<p>
<strong>Year: </strong>#item.Year
<br />
<strong>Sum of revenue: </strong>#item.SumRevenue
</p>
}
This is an oversimplification of the process. You can see it in more details in the official documentation. Or just let us know if you will need a more detailed explanation as your case might be a bit different.
I have an asp.net-mvc site and i am trying to understand the recommended practice around transactions and lazy loading.
When doing research around implementating nhibernate second level cache, one rule of thumb is around wrapping everything in a transaction (see here and here). I am trying to reconcile this point with how lazy loading works because they seems to be at odds given deferred query execution.
Lets say i have a query that looks like this . .
I have two entities:
Project
Owner
Here is a query in a transaction
public CacheTestViewModel GetCacheTestViewModel()
{
var vm = new CacheTestViewModel();
var session = Repository.Session;
using (var tx = session.BeginTransaction())
{
vm.Projects = Repository.Session.Query<Project>().Cacheable()
tx.Commit();
}
return vm;
}
but in my view I have the following code:
<% foreach (var project in Model.Projects {%>
<% = project.Owner %>
<%} %>
so that queries the Owner object when required due to lazy loading but when reviewing nhibernate profiler, it appears that these queries are happening AFTER the transaction commit is done so wanted to see if that breaks the principle in the first place. It seems like this will always be an issue with any lazy loading (either Fetch().Select() or Fetch().Select().Batch()
What is the recommended practice here?
You should create ViewModels that represent everything that the View needs to be rendered. You should not be issuing database queries from the view if at all possible. To summarize the link above here:
It increase the time that the connection to the database have to be
open. The recommendation is to keep that open only for the duration of
the action, not throughout the lifetime of the request.
It make it
that much harder to understand what are the data requirements for a
particular action is.
When writing views, you shouldn't be bothered
with thinking about persistence, or the number of queries that you
views are generating.
The views are often the most changeable parts in
the application, and having the application issue queries from the
views may result in significant changes to the way the application
data access pattern between revisions.
Most often, queries from the
views result from lazy loading, Select N+1 or similar bad practices.
We strongly recommend that you'll avoid generating queries in the
view, instead, perform all your queries in the action, and provide in
memory access only to the view for them to render themselves.
(Emphasis on the last point mine).
The practical implications of this are that you should not be lazy loading anything in a view. So what should you do instead? This is where the ViewModel layer comes in. You should be fully populating a thin ViewModel with the information you need and then rendering the view with that.
Furthermore, ViewModels shouldn't even contain classes mapped with NHibernate (this appears to be what you're doing in your example).
With all this in mind I would change your current code:
public class CacheTestViewModel
{
public List<ProjectViewModel> Projects { get; set; }
}
public class ProjectViewModel
{
public string Owner { get; set; }
/* etc. */
}
.. And then your code to populate those ViewModels:
public CacheTestViewModel GetCacheTestViewModel()
{
var vm = new CacheTestViewModel();
var session = Repository.Session;
using (var tx = session.BeginTransaction())
{
var projects = Repository.Session.Query<Project>().Cacheable();
foreach (var project in project)
{
vm.Projects.Add(new ProjectViewModel { Owner = project.Owner.Name });
}
tx.Commit();
}
return vm;
}
Now you might be thinking "gee, that's a lot of code to map domain entities to ViewModels. I can see that getting out of hand." You'd be right about that. There's a library called AutoMapper that you can use to semi-automate your mappings.
The recommended practice is to have a view model that is separate from your domain model, and to have one view model per view. For a Projects view, there would be a corresponding ProjectsViewModel class that might look like:
public class ProjectsViewModel
{
public IList<ProjectViewModel> Projects { get; set; }
public class ProjectViewModel
{
public int ProjectId { get; set; }
public string Title { get; set; }
public string OwnerName { get; set; }
}
}
The ProjectsViewModel class would be fully populated in the transaction scope so that no lazy loading is necessary.
Somewhere I had to use a linq statement for select a result set from my Model that Controller returned in Index ActionResult.
for doing this, I googled "how to use linq in view razor" and I get the result and my application worked properly, but I see some recommendation that say "Don't use Linq in view".
Why we shouldn't use it however it's possible?
And if I don't want using it what's the solution?
This is my query :
#using System.Linq
#{var lst = (from x in item.Showtimes select x.ShowtimeDate).Distinct();}
#foreach (var showTimeItem in lst)
{
<option value="#showTimeItem">#showTimeItem</option>
}
UPDATE
This is my controller Index
public ActionResult Index()
{
MelliConcert.Models.MelliConcertEntities db = new Models.MelliConcertEntities();
var listOfConcerts = (from x in db.Concert
orderby x.ID ascending
select x).Take(15).ToList();
return View(listOfConcerts);
}
And i use it in the view like this :
#model IEnumerable<MelliConcert.Models.Concert>
#foreach (var item in Model)
{
#if (item.OpenedForFirst == true)
{
//...
}
//Some Codes
#using System.Linq
#{var lst = (from x in item.Showtimes select x.ShowtimeDate).Distinct();}
#foreach (var showTimeItem in lst)
{
<option value="#showTimeItem">#showTimeItem</option>
}
}
My linq statement placed in this loop.
What should i do?
There's nothing inherently wrong with using LINQ in a view per se. The problem isn't that you're using LINQ, the problem is that you're doing this:
#{var lst = (from x in item.Showtimes select x.ShowtimeDate).Distinct();}
Any time you have to declare and set a variable inside your view, that's probably an indication that you need to modify your model. Your view model should have a property on it for this purpose. Something like this:
public IEnumerable<SomeType> DistinctShowtimes
{
get
{
return (from x in item.Showtimes select x.ShowtimeDate).Distinct();
}
}
Then the point about LINQ in the view becomes moot, as all you'd need is this:
#foreach (var showTimeItem in Model.DistinctShowtimes)
{
<option value="#showTimeItem">#showTimeItem</option>
}
UPDATE (in response to your updated question):
Now the problem (albeit slightly less of one) is this:
#model IEnumerable<MelliConcert.Models.Concert>
While this works fine, it's limiting. And what you're experiencing is that limitation. You're asking yourself, "How do I return more than one thing to the view?" The answer is to create a custom view model for that view. Right now your view is binding to an enumeration of Concert objects. Which is fine, if that's all it needs. But it turns out that's not all it needs. It has some custom logic that requires a little more. So, you create a custom view model. Something like this:
public class ConcertsViewModel
{
public IEnumerable<Concert> Concerts { get; set; }
// other properties, methods, anything
}
Then in your controller action, you return one of those instead:
public ActionResult Index()
{
using(var db = new Models.MelliConcertEntities())
{
var concertsModel = new ConcertsModel();
concertsModel.Concerts = (from x in db.Concert
orderby x.ID ascending
select x).Take(15).ToList();
return View(concertsModel);
}
}
(Note also the use of the using statement, which should always be employed when making use of IDisposable resources.)
So now your view is still getting the list of Concert objects, but it's packaged in a custom view model onto which you can add any more functionality you need for that view. Next, in your view, change the model declaration:
#model MelliConcert.Models.ConcertsViewModel
(This assumes you put it in the Models namespace. Depending on the scale of your application, you might want to break out view models into their own namespace. I don't often use the Models namespace in the actual application for core business objects, so our projects are likely structured very differently. This should get you going, but you'll want to make sure you keep your concerns cleanly separated.)
Then in the view code you can reference what you need from that object. So if you need to access the list, instead of just calling something like #foreach (var item in model) you would call #foreach (var item in model.Concerts).
I think in this case the argument would be to do the maximum amount of processing on your model before returning it to the view.
So why not return distinct showtimes to the view and then just loop through them?
The only problem with your current set up is it may undermine the spirit of MVC which was to separate concerns. The view shouldn't be applying any logic that needs to be tested (or as little as possible). By keeping logic in the models and controllers you make unit testing easier and the views are simpler for a developer to read.
EDIT
Hey #samangholami, you can return multiple objects to a view using a class. Create a class called "PAGENAMEViewModel" or something similar and create a property for every value you want to return. For example:
public class MovieViewModel
{
public string MovieName { get; set; }
public IEnumerable<string> Actors { get; set; }
public IEnumerable<ShowTimeRecord> Showtimes { get; set; }
public class ShowTimeRecord
{
public string TheaterName { get; set; }
public string TheaterAddress { get; set; }
public DateTime ShowtimeDate{ get; set; }
}
}
Then return your complex model like so:
public ActionResult Index()
{
MovieViewModel model = myMovieHelper.GetMovieData();
return View(model);
}
Besides the possible separation of concerns problem you also might have a performance problem that can be more difficult to diagnose.
If your LINQ query is somehow connected to the database via some ORM or something like that by looping through the results you might create a N+1 problematic scenario.
Moving it off the view might not prevent it, but at least puts it into somewhere that is more visible.
I believe that's because it's not respecting the separation of concerns principle, which is a fundamental concept of MVC. By performing that query in the view, you're taking business logic to it.
It has nothing to do with Linq itself. You could, for example, have a Linq statement to perform an OrderBy. That's ok because it's not business logic, it's a proper view operation (to order data into a table, let's say).
Im new to ASP.NET MVC, trying to learn the basics.
Im now trying to learn the relationship between the model ,view and controller.
The interaction between these three looks different, why? (Look at the arrows)
Source 1: MSDN
Source 2 (Page 65): Steven Sanderson
I would be glad if you help me sort out my confusion
Thanks
Edit:
What you are saying is that mvc can be implemented differently?
(Still asking about asp.net mvc - Not mvc in general)
I have been looking at the mvcmusicstore
and it looks like this.
Controller:
public ActionResult Details(int id)
{
var album = storeDB.Albums.Find(id);
return View(album);
}
Model:
public class Album
{
public int AlbumId { get; set; }
public int GenreId { get; set; }
public int ArtistId { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public string AlbumArtUrl { get; set; }
public Genre Genre { get; set; }
public Artist Artist { get; set; }
}
view:
(Had to add as image, add code the normal way did not work)
This looks like the MSDN version, how would this be rewritten to fit Sandersons diagram?
Maybe this will help me understand!
Edit again:
Hi again
Let me sum this up. Please respond if I'm wrong.
The way Microsoft intended us to use mvc is the one we see in the above MSDN link and in MusicStore.
Then there are other "versions" of mvc such as Sandersons (or whereever it originates from).
So Microsoft give us a basic way of how to use the mvc framework, but it is ok to do it other ways.
A newbie should not get stressed by seeing different versions, sticking to the one seen in MSDN/MusicStore is perfectly fine.
The key difference is the inclusion of the "Presentation Model" in Sanderson's diagram. The ASP.NET MVC implementation often uses the Model as the Presentation Model, even though they can be different (and I would argue that they should be different, but it's a holy war and there's no need to get into that).
In most very simple ASP.NET MVC applications, the model is the data entity. Whether it's an EF entity or a Linq2Sql entity, makes no difference. This is because most applications are simple forms-over-data and the presentation is probably one-to-one with the persistence.
The MVC pattern itself, however, doesn't require this. In a more pure framework-agnostic form, Sanderson's diagram illustrates the fact that the controller is interacting with the model. The model is really the "gateway to the domain core" in this sense. Controllers and views are part of the application, but the model has the underlying business logic and, beneath that, layers of persistence and other infrastructure information (properly separated, of course) which are unknown to the application. The boundary between the controller and the model is the application boundary, the point at which other applications can also connect to the domain core and interact with it.
A presentation model is usually nothing more than a simple value object. It's not an entity of any kind in the sense that it doesn't have to exhibit any business behavior or maintain its lifecycle the way that a persistable business entity would. It's just a flat object with some attributes of data.
It can have some behavior, but that behavior is for the application and not for the domain core. For example, maybe it has some methods or properties that the view can use. The presentation model is part of the application, so it's presentation-layer-aware. Essentially it just holds data that the controller needs to pass to the view (or even receive from the request, depending on the framework).
In ASP.NET MVC you'll very often see the model used also as the presentation model. The same object may be playing two roles in those cases, but the two roles are definitely different.
Edit: Just noticed your updated question...
In that example, Album is playing the role of both domain model and presentation model. (In fact, I would argue that it's not a domain model at all because it's too anemic. Notice that it has no functionality, just bare data.) In a richer domain model, Album would likely have more functionality. For a contrived example, imagine that instead of auto-implemented properties it has properties which enforce business logic when set, and it has methods on it such as AddSong(Song song) and Play() and other such behaviors.
This richer model can still be used as a presentation model, but the functionality might not make sense in the scope of a view. A view is really suited more toward just bare data elements. The controller would interact with the model's functionality. So you might create a presentation model similar to the Album domain model in structure, and it would look just like the one in your example.
Going forward, what if the view needs other data as well? Maybe the view needs to know something about other models which aren't part of the same aggregate as Album. It wouldn't make sense to modify the domain models to accommodate the view. That's backwards. The presentation should wrap around the domain core, not the other way around. So you might add properties to the presentation model which are populated from other things inside the controller.
So you might end up with something like this...
Domain model:
public class Album
{
public int ID { get; private set; } // might need to be immutable
private string _title;
public string Title
{
get { return _title; }
set
{
// don't allow empty titles
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentNullException("Title");
_title = value;
}
}
private Album() { }
public Album(int id, string title)
{
ID = id;
Title = title;
}
public void Play()
{
// some implementation
}
public void SomeOtherMethod()
{
// some implementation
}
}
As the business domain grows and changes, this model could change with it. The main point is that it changes at the behest of the domain core and the business logic, not at the behest of UI implementations.
A particular "page" on a particular website which uses this domain core may need specific information about an album, and maybe some other information as well. You'd tailor a presentation model to fit that:
public class AlbumViewModel
{
public int ID { get; set; }
public string Title { get; set; }
public string Owner { get; set; }
public IEnumerable<Listener> Listeners { get; set; }
public string SomeCompletelyUnrelatedValueNeededByTheView { get; set; }
}
The controller would then construct this presentation model for the view:
public ActionResult Details(int id)
{
// TODO: validate and sanitize any inputs
var album = AlbumRepository.Get(id); // after all, why bind the UI _directly_ to the DB? that's just silly
var someOtherObject = SomeOtherRepository.Get(someOtherValueFromSomewhereElse);
var albumVM = new AlbumViewModel
{
ID = album.ID,
Title = album.Title,
Owner = somethingElse.SomeValue,
Listeners = someOtherObject.GetListeners(album),
SomeCompletelyUnrelatedValueNeededByTheView = "foo"
};
return View(albumVM);
}
This is a much more manual approach overall. It's useful when you have more complex domain models, multiple complex applications interacting with that domain, different technology stacks throughout the domain, etc. For simple forms-over-data applications the standard ASP.NET MVC implementation usually works fine. Most of the tutorials for it reflect this, consolidating multiple responsibilities into fewer objects, using decorators instead of explicit code (assuming the use of the same stack of tools across the board), etc.
The examples you're looking at get you to a working application very quickly with very little code. As with any framework, it works beautifully if you do things the way the framework intends you to do them. If you need to step outside the bounds of the framework, you can still maintain the pattern in a more abstract and framework-agnostic way.
Edit: For your update again...
In a way, yes. ASP.NET MVC is a framework which borrows a lot from the MVC pattern in general. As with all things, there's more than one way to do it. Sticking with simple implementations and quick applications, the functionality provided by the ASP.NET MVC framework and explained in its various tutorials is perfectly acceptable and is a great example of the use of a framework... Using a tool to get a job done.
They stick to the pattern in all the most meaningful ways. At the same time, however, in the true nature of a framework (which is generally outside the scope of a pattern description), they try to give you tools which make very light work of the actual development. If you don't have a pressing need to separate your domain models from your presentation models, you don't have to. One model can play both roles. If you don't have a pressing need to abstract your data access behind, say, a repository pattern, you don't have to. You can throw together some quick Entity Framework functionality directly in your Models and be done with it.
Ultimately it's up to the needs of the project, the preferences of the developer(s), and so on. The patterns are more academic, the frameworks are more pragmatic. Balancing the two is the key.
I guess the distinction is that in asp.net MVC you can have strongly typed views which have 'knowledge' of your model and the entity being passed through to the view. In its purest sense though the View shouldn't (or rather, neednt) have any knowledge of the model. For that reason I say Steven Sandersons example is better.
Fantastic book by he way!
I wouldn't sweat it - Stephen Sanderson's diagram is showing less of the cycle but in more detail.
I'd interpret the MS article arrows as:
Controller populates model (from services, etc)
Controller directs to view
View populates through binding model
The microsoft diagram isn't really that useful or informative or useful though in my opinion. You could equally argue that arrows could go in different directions - or even in both directions like Sanderson's do. E.g. Controller also received models from binding, etc.
The Sanderson arrows are annotated well and are self-explicit, and the book is great.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I am developing an MVC application using a mysql database.
I searched a lot through SO and other sites about the architecture/structure. I found a lot of similar questions but I am still in doubt.
In my applications there is a categories section; the structure is shown below:
View:
Category - (views in category folder listed below)
CreateCategory
DeleteCategory
ManageCategory
Controller:
CategoryController - (action names listed below)
CreateCategory
DeleteCategory
ManageCategory
Model: This is where I have doubts. I have a model named CategoryModels but I don't know if I doing things the right way or not. I don't know where I should put the service functions - for example where I put functions to create or delete categories.
What I did is create a CategoryServices class inside CategoryModel.cs and write functions inside that. DAL file is put in app code folder, so to access the DB the function will create an object of DAL and call it. Is this the right way?
In CategoryModels.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Web.Mvc;
using System.Web.Caching;
namespace TraktorumMVC.Models
{
public class CategoryModels // contain properties for the 3 views (CreateCategory,DeleteCategory and ManageCategory
{
public IEnumerable<SelectListItem> CategoryList { get; set; }
public IEnumerable<SelectListItem> AvailableCategories { get; set; }
//etc..........
}
public class CategoryServices // this class contain all service functions related to categories
{
public int RemoveCategory(int categoryId) // this will remove a category
{
int status = -1;
try
{
string query = Resources.Queries.RemoveCategory;
DAL objDAL = new DAL(); //DAL file is in Appcode folder. IS this right way
string[] inParamNameArray = { "Id"};
string[] inParamValueArray = { categoryId.ToString()};
object[] inParamTypeArray = { DbType.Int32 };
status =Convert.ToInt32( objDAL.ExecuteScalar(query, inParamNameArray, inParamValueArray, inParamTypeArray, true));
}
catch (Exception ex)
{
DeveloperLog.WriteExceptionLog(ex, "CategoryServices.RemoveCategory");
}
return status;
}
public bool InsertCategory(int parentCategoryId, string icon, string name)
{
//bla bla
}
}
}
Is this right way to do this? Did this break the model concept?
The "Model" in ASP.NET MVC is not very prescriptive, and is certainly less prescriptive than the Views or Controllers.
That said, there isn't necessarily a right or wrong way to do your model, but there are a few popular/common approaches that people take:
Leverage an ORM like Entity Framework (EF) or NHibernate to be your model. This works out well on simple sites that are mostly CRUD driven. In your situation, EF could handle all of the CRUD work you need to do on categories.
Another common approach to is to leverage some sort of services layer which might encapsulate business and data access logic. This layer might return to your application data transfer objects - very simple, data only containers - that you can change and send back.
Either way, it's a good idea to separate your "View Model" from your "Domain Model". An example of this is not simply passing Entity Framework controlled objects to the View for rendering. Instead you'd map those objects (and potentially others) into a "View Model" specifically created for just that view. A popular tool to help developers accomplish this is the excellent http://automapper.org/
In your situation, if you can, I'd recommend putting in an ORM to handle the persistence of categories. If your current DAL is doing more than just persistence, then I'd recommend you separate it out to a service, with corresponding interface, that your controller can get a reference to and use to drive your application forward.
You don't really have a Category model here, what you have is a view model for a particular part of some views. As #nikmd23 alludes to, you probably want to separate your view model and domain model. A domain model is something that describes the data which makes up your system. A view model is something that describes how you would like to share that data through an interface.
In this case, start by creating a domain model, something like:
public class Category
{
public string Name { get; set; }
public int Id { get; set; }
}
Then your DAL contains some functionality for getting a collection of Category objects:
public interface DAL
{
IEnumerable<Category> GetCategories();
}
And when you want to construct a view model of your categories, you would map it to view model:
var dal = new DALImplementation();
var categories = dal.GetCategories();
var categoryListViewModel = categories.Select(m => new SelectListItem
{
Text = m.Name,
Value = m.Id.ToString()
});
There are many different implementation patterns for each of these steps, but the whole idea is to start by creating a domain model, then build your services to interact with those domain models, and for each request with a view, construct a view model which only shows the exact information you want to share with your user.