Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Newbie question on ASP.Net MVC: I have a project and I manage two "Models" - let's say "Products" and "Clients". Each Model has it's own Controller, and set of Views to implement the basic CRUD operations.
Now I want to list from a different View (lets say Home Page) all Products and all Clients.
Should I create new methods in Products and Clients Controlers to list their items and call these methods from the Index view from Home? Should the Home Controller call the Products and Clients methods?
How should I correctly address this?
Thansk in advance!
Pedro
The answer to this question is to some degree both subjective and opinion-based. That being said..
It is fine for HomeController to call Product and Client related methods to return what will effectively become your HomeIndexViewModel (which would comprise of some kind of ProductViewModel and ClientViewModel properties - your view would access the data via Model.ProductViewModel, Model.ClientViewModel, etc).
I would go a step further and add an orchestration component, which will be responsible for handling the request and application logic required by the Index action of your HomeController. This should keep your controller thin and decoupled from the backend.
public class HomeController : Controller
{
private readonly IOrchestrator orchestrator;
public HomeController() : this(IOrchestrator orchestrator)
{
}
public HomeController(IOrchestrator orchestrator)
{
this.orchestrator = orchestrator;
}
public async Task<ActionResult> Index()
{
var homeIndexViewModel = await orchestrator.GetHomeProductsAndClientsAsync();
return View(homeIndexViewModel);
}
}
GetHomeProductsAndClientsAsync() will obviously be a method of your FooOrchestrator class that will be handling the application logic to return a HomeIndexViewModel.
The orchestrator is passed in to HomeController as an interface (IOrchestrator, rather than the FooOrchestrator class which will implement the IOrchestrator interface) to facilitate dependency injection (though, IMHO, the approach is still beneficial without DI).
Some reading:
"Never Mind the Controller, Here is the Orchestrator" (Dino Esposito)
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I want to know which is the best convention for controller, action and view naming in ASP.Net MVC
When i create a "Product" Controller, should i name it productController or ProductController ?
By default, visual studio Create ProductController.
But that means the url will be http://mywebsite/Product/xxxx
Or we should not have upper case like this in URLs ?
So i do not know which convention apply.
This is the same for view names and action names...
you can use First latter capital as default MVC does, and for lower case url you can use RouteCollection.LowercaseUrls Property
check below link
https://msdn.microsoft.com/en-us/library/system.web.routing.routecollection.lowercaseurls.aspx
Example:
public static void RegisterRoutes(RouteCollection routes)
{
routes.LowercaseUrls = true;
}
Controller is just a class and should follow class capitalization rules, iow should use PascalCase: https://msdn.microsoft.com/en-us/library/x2dbyw72(v=vs.71).aspx
You can use StyleCop to check your code for such things as casing rules, spaces, etc: https://stylecop.codeplex.com/
But still nobody can prevent you from naming like 'productController'.
Also, if you wish to change appearance of controller name in URL, please check next question and corresponding answers (but usually people ten to use default naming): How to Change ASP.NET MVC Controller Name in URL?
In short, you can do this with RoutePrefixAttribute or by configuring routing (not shown here):
[RoutePrefix("product")]
public class ProductController
{
...
}
I'm looking for a bit of experience and explanation here, given that different sources give different recommendations. I am totally new to MVC. I know this question has been asked before, but I am not (currently) using EF or Linq.
I have a SQL database with many stored procedures. Previously when used with webforms, there was a business layer that contained helper methods for calling the procedures and returning DataSets to the pages. The important part is that the procedures often interrogated about 20 tables; the pages do not simply reflect the database structure exactly (as I see in the majority of MVC tutorials):
SQL database <--> stored procedures <--> business layer <--> web forms
I want to take the best approach here to start on the right footing and learn properly but appreciate there may not be a correct answer. Therefore if you post, could you please offer some explanation as to "why"?
Should stored procedure logic (SQLCommand/business methods etc) go within Model or
Controller?
One post advises neither, but retain the business layer. Another expert advises that
[Models/Entities] should not have any addon methods outside of what's
coming back from the database
If the business layer is retained, where are the methods called from (e.g. Model or Controller)?
If the above answer is "Neither", does that mean the Model part will go unused?
That almost feels that things aren't being done properly, however in this tutorial that appears to be what happens.
Should I plug in the Entity Framework into the Model layer to call the business layer?
That feels like overkill, adding all that additional logic.
Your controllers should gather the information required to build the page the user is currently viewing. That's it.
Controllers should reference classes in your business logic layer.
For example here's your controller. All it does is translate the http request and call the business logic.
public class MyController : Controller
{
private IMyBusinessLogic _businessLogic;
public MyController(IMyBusinessLogic businessLogic)
{
_businessLogic = businessLogic;
}
[HttpPost]
public ActionResult UpdateAllRecords()
{
_businessLogic.UpdateAllRecords();
return Json(new Success());
}
}
And your business logic class
public class MyBusinessLogic : IMyBusinessLogic
{
public void UpdateAllRecords()
{
// call SP here
using(SqlConnection conn = new...
}
}
There are a number of advantages to this:
Your business logic is completely separated from your UI, there's no database code in your presentation layer. This means your controller can focus on it's job and code doesn't get polluted.
You can test your controller and see what happens when your business logic succeeds, throws exceptions etc.
For extra bonus points you should look into creating a data access layer.
public void DataAccess : IDataAccess
{
public void RunStoredProcedure(string spName)
{
}
}
Now you can test that your BLL is calling and processing your SP results correctly!
Expanded following the comment questioning the models:
Ideally your model should have no logic in it at all. It should simply represent the data required to build the page. Your object which you're loading represents the entity in the system, the model represents the data which is displayed on the page. This is often substantially lighter and may contain extra information (such as their address) which aren't present on the main entity but are displayed on the page.
For example
public class Person
{
public int PersonID {get;set;}
public string Firstname {get;set;}
public string Lastname {get;set;}
public Address Address {get;set;}
}
The model only contains the information you want to display:
public class PersonSummaryModel
{
public int PersonID {get;set;}
public string FullName {get;set;}
}
You then pass your model to your view to display it (perhaps in a list of FullNames in this case). Lots of people us a mapper class to convert between these two, some do it in the controller.
For example
public class PersonMapper
{
public PersonSummaryModel Map(Person person)
{
return new PersonSummaryModel
{
PersonID = person.PersonID,
FullName = string.Concat(person.Firstname, " ", person.Lastname)
};
}
}
You can also use some automatic solutions such at AutoMapper to do this step for you.
Your controller should really only be involved with orchestrating view construction. Create a separate class library, called "Data Access Layer" or something less generic, and create a class that handles calling your stored procs, creating objects from the results, etc. There are many opinions on how this should be handled, but perhaps the most
View
|
Controller
|
Business Logic
|
Data Access Layer
|--- SQL (Stored procs)
-Tables
-Views
-etc.
|--- Alternate data sources
-Web services
-Text/XML files
-and son on.
if you feel like learning tiers and best way
MSDN have great article on this link
MSDN
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am building an application where i do not want my user to fetch data off an on from the database. What i really want is to have all the relevant data to be fetched from the database inside a public array variable.
What I am currently doing is using a Public Shared variable. But I am unable to access that variable from other parts of my application.
Could somebody guide me on this requirement?
But I am unable to access that variable from other parts of my
application.
You need to create a Public Shared field or (better) property. You can use a class or Module (similar to a static class in C#):
Public Module MyGlobalVars
Public FooAs String = "Foo"
End Module
You can access it via class-name + field/property-name:
Dim foo As String = MyGlobalVars.Foo
You can also use a class which has the advanatage that you can use it's shrared constructor to load the array from database:
Public Class MyGlobalVars
Shared Sub New()
SomeDbStrings = GetDbStrings()
End Sub
Private Shared Function GetDbStrings() As String()
' load from db and return
End Function
Public Shared Property SomeDbStrings As String() = Nothing
End Class
The class or module must be accessible,
so if the class is in a different dll you need to reference it,
if it's in a different namespace you either have to specify the full path like
MyNamespace.MyGlobalVars.SomeDbStrings
or add the Imports statement at the beginning of the file.
Imports MyNamespace
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
My question evolves around best practice.
Right now im using entity framework with ASP.NET and would like it top performance.
Would you generally check in the database for a existing record before adding one, or would you rely on the exception being throw or even expect that the parameters given are relevant and active.
Example: (ASP.NET with Identity)
public ResultWrapper AddUserToRole(string user, bool userId, string role, bool roleId)
{
ApplicationUser appUser = FindUser(user, userId);
ApplicationRole appRole = FindRole(role, roleId);
if (appUser == null || appRole == null)
return new ResultWrapper(false, "Unknown user or role");
else
{
IdentityResult result = userManager.AddToRole(appUser.Id, appRole.Name);
db.SaveChanges(); // AutoSaveChanges is false, so update.
return new ResultWrapper(result.Succeeded, result.Errors);
}
}
Besides being a very opinion based question, I think there are appropriate guidelines one can follow.
Would you generally check in the database for a existing record before adding one, or would you rely on the exception being throw or even expect that the parameters given are relevant and active.
This completely depends on context in my opinion.
For extremely high transactions, I would write a stored procedure.
Otherwise it depends on the concurrency of the operation, and in this particular instance, I don't think multiple people are going to try to add the same person to the same role, so exceptions are minimized and acceptable.
In my project, i have first created my Data Access Layer using Entity Framework with the following projects in a single solution,
1.Domain Model - Entity Model (.edmx)
2.Services - Business Services, Dtos, Infrastructure(Configurator), Interfaces and Models(Repository)
Now the problem is, i want to connect this data access layer to my MVC project, i do not know how to make the data access layer projects to behave as the models for my mvc project. So can anyone tell me how to connect my data access layer into my controllers and views.. any references is appreciated. Thanks in Advance !
I think what you're asking is what's the best way for controllers to interact with your services and data layer?
One option is to use the mediator pattern, and decouple the services from the controllers.
There's a great implementation for ASP.NET MVC apps: ShortBus, also available on nuget that I've used in a number of projects, and so far it's worked great.
One of the nice things about ShortBus is it's support for dependency injection. In the example below, all the services are created with Ninject, and require the appropriate registration.
The basic idea is you define queries and commands that the controllers will use, and then add handlers to perform the actual work.
public class AddUser : ICommand<User>
{
public string Email { get; set; }
}
and then a handler:
public class AddUserHandler : ICommandHandler<AddUser, User>
{
private IDatabaseService _database;
private IEmailService _email;
public AddUserHandler(IDatabaseService database, IEmailService email)
{
_database = database;
_email = email;
}
public User Handle(AddUser command)
{
bool created = _database.CreateUser(command.Email);
if (created)
{
_email.SendWelcome(command.Email);
}
}
}
Then inside your controller, all you'd do is issue the command:
public class UsersController : Controller
{
private IMediator _mediator;
public UsersController(IMediator mediator)
{
_mediator = mediator;
}
public ActionResult Create(string email)
{
User user = _mediator.Send(new AddUser("foo#bar.com"));
}
}
The things I like about this pattern are:
Controllers don't need to know how to create a user. It issues a command, and the appropriate business logic handles it.
Each handler can require the services it needs. There's no need to pollute the controllers with services only used by a single action.
It's really easy to unit test. I use a mock, and only need to verify that _mediator.Send() was called with the correct parameters. Then to test the handler, I mock IDatabaseService and IEmailService and verify they are called correctly in the 2 cases.
Commands and queries can be reused, and again, the caller never needs to know what's required to handle the request.
As for the Views, I'd recommend ViewModels.
Each View gets it's own ViewModel, which holds whatever is required for showing that particular page. You'd then map your domain objects to their own individual ViewModels, possibly with AutoMapper.
What's nice about ViewModels is you can format the data appropriately (formatting a DateTime maybe), and then your Views don't need any special logic. If later you decide to update the DateTime format, you only need to change it in one place.
Create a (shared) interface to pass to the layer that's between the DAL and MVC, especially if you're unit testing. Use a repository pattern. Check it out here:
http://csharppulse.blogspot.com/2013/09/learning-mvc-part-5repository-pattern.html
This should get you going...