CQS and ASP.NET MVC Actions - asp.net-mvc

Those who have read about CQS principle know that:
CQS states that every method should
either be a command that performs an
action, or a query that returns data
to the caller, but not both.
Speaking of ASP.NET MVC Actions, does CQS indicate that we shouldn't have an Action like this?
public PartialView InsertOrder(Order order)
{
OrderService.InsertOrder(order);
return PartialView("OrderDetails", order);
}
This method is changing the state of the system and returning the current state. If CQS is applied here, we should have 2 separate Actions: one for inserting a new order and one for getting the system of the system (which should be called from the client if the first Action was completed successfully). However, this complicates programming.
I'd like to know your opinions on this.
Mosh

A common example of Command/Query Separation on the web is Post/Redirect/Get.
In ASP.NET MVC, this is usually implemented in the simplest way as
[HttpPost]
public ActionResult UpdateOrder(Order order){
UpdateOrder(order);
return RedirectToAction("ViewOrder", new { order.OrderId });
}
[HttpGet]
public ActionResult ViewOrder(int orderId){
return View(GetOrder(orderId));
}
For AJAX, and a partial view, this might not be the best strategy, since the problems that Post/Redirect/Get solves aren't really relevant, and the redirect can be tricky.

CQS is only concerned with command and queries to the same object. Since a OrderView the Order are not the same object (I guess from your implementation) the principle does not apply, so your code is not counter the principle neither in favor :)

I've never heard of CQS, but if you are doing ASP.NET MVC (MVC pattern) the action you wrote is perfectly fine (assuming this OrderService there is an abstraction to the real service). The controller manipulates the model and decides which view to render and passes this model to the view.

I had a vague recollection of this term from the eiffel days (which if followed all the way back, actually predates most current oop principles by a good decade or so (late 80's i think). I'd suggest that this term and/or principle may well be outmoded now and superceded by actionresults in mvc (be that asp or codeignitor etc, etc). I actually think that in terms of the definition (which i just looked up now), this separation is concerned with the logic that performs the action i.e. OrderService.InsertOrder(order) in your example. So, in a way, mvc as performed in your action is actually loosley following this pattern (InsertOrder doesn't attempt to present any stateful info, purely process the order object).
I'd suggest that you look at best practice for asp.net mvc which is fundementally based on returning an actionresult (or partial, contentresult etc, etc). this pattern was designed to simplify the paradigm to facilitate productivity in a uniform and universally accepted fashion.
of course, you could use your action return values to generate a success or fail for the insert/update/delete scenarios and then request partial views based on those return value. However, i personally don't think i'd leverage too much value from that approach bearing in mind the fact that the controller in MVC is concerned with stearing the logic of which view should be returned as the result of an action.
hope this helps
jim

Related

MVC [HttpGet] controller annotation optional?

If I have 2 controller actions:
[HttpGet]
public ActionResult Login()
{
//...
return View();
}
and
[HttpPost]
public ActionResult Login(FormCollection values)
{
//...
return RedirectToAction("Index","Home");
}
It seems that the Post decoration is required for this to work (which makes sense), but the HttpGet decoration is entirely optional. It works fine with or without. It seems that MVC defaults controller actions to HttpGet unless otherwise specified.
I'll have to decided if I want a future reader of my code to have to figure that out on my own or not, or whether I want to have to remember to add HttpGet everywhere for consistency. But my question is not about whether it is a good practice to include the explicit decoration even though it is defaulted that way already.
My question is: is it ALWAYS the case that I don't need to decorate controller methods with HttpGet? Is there some way that this can bite me if I do or do not explicitly specify? I've searched on this a but and all I can find is posts describing why you might want to use both annotations rather than the reason for/against including the HttpGet specifically.
You don't have to specify this explicitly, no. However, please note:
Not specifying the verb on an action will mean that the method accepts both GET and POST. If there are two actions, however, the one labelled POST will be used for POST and the other will default for GETs.
Applying HttpGet will mean an action accepts only GET requests.
Labelling actions as GET can make it more obvious to other developers what your intention is.
Is there some way that this can bite me if I do or do not explicitly specify?
Not very likely. I could imagine a situation where something might be showing some strange behaviour or not working as expected because of it, but it'd be rare.
Is there some way that this can bite me if I do or do not explicitly specify?
Here I want to develop an answer of Rowan Freeman about the consequences of not using [HttpGet] explicitly for every GET method.
As it was already mentioned, a method without [HttpGet] annotation will accept both GET and POST request (unless there is another method with same name that is annotated with [HttpPost]). If a method is explicitly annotated with [HttpGet], 405 Method Not Allowed will be returned.
One consequence that I could imagine is that if an attacker wanted to send big amount of data through GET request, it would have a limit. Without [HttpGet] annotation, this limit is not a problem, because an attacker can switch to POST and do the same without any limit.
Another similar case is that:
HTTPGet can carry only string data whereas HTTPPost can carry both string and binary data.
Yet another thing is that POST requests will probably not entirely be logged on a server, therefore an attacker can somehow hide it's activity from an administrator as attackers payloads won't be visible (body won't be present in logs).
A comparison between POST and GET (which I cited from) can be found here:
ASP.NET MVC 5 – HTTPGET And HTTPPOST Method With Example
Of course, all of these cases are pretty rare, but this is what exploiting is about - finding rare things that can turn out to be a vulnerability.
To conclude, it is a good habit to always write [HttpGet] annotation in controller methods. It is just a one line that can improve security of your web application.

Shuould we perform LINQ directly in asp net mvc views

Looking through the project we are working on (ASP MVC 3.0), I have seen this part of code in one of my ASPX views:
var groups = Model.GroupBy(t => new { t.OrganizationUnitName, t.OrganizationUnitId, t.ServiceTermDate }).OrderBy(m =>m.Key.ServiceTermDate).ThenBy(m => m.Key. OrganizationUnitId);
foreach (var group in groups){
var data = group.Select(t => new
{
t.PersonFullName,
t.ServiceTermStatusName,
t.VisitTypeName,
SubType = ControllerHelper.LocalizedPersonSubType(t.PersonSubTypeName),
t.MedicalServiceName,
t.PersonId,
t.ServiceTermId,
t.Phone,
CountryName = t.Name,
PersonUniqueNumber = t.GetUniqueIdentifyingNumber(),
}).OrderBy(m => m.HoursFromMinutesFrom);
foreach(var item in data){%>
...............
//render table and table rows, for sample
<tr>
<td><%= item.PersonFullName%></td>
</tr>
..............
<%}%>
<%}%>
<%}%>
I am not sure this is best coding practice, shouldn't LINQ statement be placed in controller helper (or somewhere else) instead in view directly? And if I'm right, how that could be done utilizing best coding practices?
Thank you in advance
It seems that LINQ which is performed directly in the view is not only at the wrong place but also it raise another interesting question: if we place it into service layer or controller or controller helper, then how it would be passed in this case - anonymous type IGrouping to strongly typed view?
Personally, I wouldn't use LINQ in the view. Do this in the controller for unit testing purposes.
If there is logic being performed, in a larger application I'd even move it out to a services assembly which would contain all of your LINQ queries.
Your view should be as basic as possible. Any ordering, grouping or sorting should be done in your controller (preferably with the help of a helper method which is re-usable for different actions across the application).
The philosophy of ASP.NET MVC (and I'd say of the MVC paradigm in general) is:
Put as little code as possible in the view. Ideally, you should just
reference data in the model class, perhaps with some loops or
conditional statements.
Do not put complex application logic in the controller methods.
Ideally, these methods should just collect the input data from the user
(if any), perform all the appropriate security and data validations, then pass the data to an application logic (or business logic)
class, then redirect to the appropriate view with the new model data
obtained from the logic class. (I once read that a controller method should have no more than 10 lines of code; maybe this is a bit exagerated but you get the point)
So I would say: not only the view should be LINQ free; the controller should be like this too.
Yes you can do it on View but i prefer to use Business logic work done through
controller rather than on View.
View is just used to display the GUI that must be as basic and simple to reduce the complexity of the GUI.
To make application code consistent, maintainable and reusable put these type of logic on Business Logic Classes except writing on Controller or view.
MVC is about abstraction of concerns.
The code you have posted above is breaking the most important rule of MVC. The view is the view, it has no business logic or data access code. It simply displays data that it is given to it in a nice way that can allow for presentation and user interaction. Think of the view as something you could give to a designer who knows nothing of asp.net.
The problem you have above is a perfect candidate for a ViewModel. The "Model" variable that is being used here is wrong, since you are taking it and then changing it to display something different. If the domain model doesn't fit then the controller should create a ViewModel that looks exactly as the view expects. There are a few ways of doing this. But one way is for example:
public ActionResult DoSomething()
{
List<DomainModel> modelCollection = getListOfDomainModels();
// Perform ViewModel projection
var viewModelList = modelCollection
.GroupBy(t => new { t.OrganizationUnitName, t.OrganizationUnitId, t.ServiceTermDate })
.OrderBy(m =>m.Key.ServiceTermDate)
.ThenBy(m => m.Key. OrganizationUnitId)
.Select(p => new MyViewModel()
{
FullName = t.PersonFullName,
StatusName = t.ServiceTermStatusName,
// etc ...
});
return View("DoSomethingView", viewModelList);
}
Now your Model variable will contain the correct model for the view.
Depending on your project's size and requirements you can make this alot better by performing the whole query in another layer outside of the controller and then projecting to a ViewModel inside your controller.
You should not be doing it in either the View or the Controller. Thus without giving you to much to chew at a a time you will want to have Separation of concerns (SOC) and keep it DRY (Don't repeat yourself) otherwise it becomes a maintenance nightmare.
If you put that code in the view (which is the worst place for it). 1. What happens if you want to use same or similar code elsewhere? 2. How will you step through debugging your code in this manner?
This is the equivalent of placing sql queries in a ASP.NET webforms .aspx file, not even in the code behind .aspx.cs file. Not using your model or a repository pattern and putting the code in the controller is another bad idea as a controller ActionResult has a Single Responsibility (SRP) of handling request, by smothering it with this code you have introduced an anti-pattern. Keep the code clean in organized areas. Don't be afraid to add class library projects. Look up the Repository pattern and eventually get to the point of doing unit testing and using DI (Dependency Injection) not just for unit test, but for a loosely coupled / highly cohesive application.

keeping asp.net mvc controller size down

I have a Controller. "OrderController". Currently it's 1800 lines. I like to reduce the size. I'm using static helper methods which is fine but i'm using ninject to call my repositories so don't have access to the repositories in the static methods without passing the properties in.
What are some good approaches for reducing controller noise?
How to get a Thin Controller
Refactor reusable functionalities that can apply to multiple types of output to ActionFilters. Consequence: Less repetitive code, thinner Controller actions, quicker future development
Refactor reusable functionalities that apply to a specific type of output to a custom ActionResult. Consequence: Less repetitive code, thinner Controller actions, quicker future development
Leverage ModelBinders to bind your input values to complex objects that are injected into your Controller action. Consequence: You don't need to handle the actual HTTP input (RouteData, Form values, querystring parameters) at all in your controller. You can also handle data validation in your model binder.
Implement Dependency Injection via a custom ControllerFactory. Consequence: You don't need to construct services in your Controller.
Refactor single Controllers with an excessive amount of Controller actions into multiple Controllers. Consequences: Your code becomes more maintainable.
Move your static helper methods to static classes. Consequence: Your methods become reusable by multiple controllers and you have less bloated code in the Controller, so it is easier to maintain and make changes to your app.
Other Notes
Plenty of open source resources exist to help accomplish these tasks. I definitely suggest looking into the MvcContrib project. They have a FluentController base class that was designed with building thin Controllers in mind. Also, I upvoted Darin because the video he recommended is helpful, so check it out
No way should there be that much code in your controller. I suspect you haven't separated your concerns.
I would have a look and a think at the answer to this SO question:
ASP.NET MVC Patterns
In short:
Put the complexity into Service classes that perform a clear cut purpose, ie, to deliver what the controller needs.
The controller should just have the application logic, ie, it should just be acting as a kind of air traffic, uhmm, controller, sending requests this way and that based on app logic. That is pretty much its function in a nutshell. Other stuff doesn't belong in a controller.
My controllers look like:
[Authorize(Roles="Admin, Tutor, Pupil")]
public partial class CourseController : Controller
{
ICourseDisplayService service;
public CourseController(ICourseDisplayService service)
{
this.service = service;
}
public virtual ActionResult Browse(int CourseId, string PupilName, string TutorName)
{
service.Initialize(CourseId, 1, PupilName, TutorName, User);
service.CurrentStepOrder = service.ActiveStepIndex;
if (Request.IsAjaxRequest())
{
return PartialView(MVC.Courses.Course.Views._Display, service.ViewModel);
}
else
{
return View(MVC.Courses.Course.Views.Display, service.ViewModel);
}
}
note the service instantiation in the controller's constructor and the calls to service in the actions.
1800 lines!!!!!!!!! Holy mother of God. I would recommend you watching the following video about putting your controllers on a diet.

Is it okay to hit the database from a custom model binder?

Say I have an object that gets some data from HttpPost and some from the database. I think I want to allow the ModelBinder to go to the database/repository for the that data missing from the post. In practice, is this a good or bad idea?
I've decided to edit my original answer given my thinking on these types of things has evolved since early 2010.
In my original answer, I basically expressed that, while my instincts told me you shouldn't do this, I was uncomfortable saying we shouldn't without being able to articulate why.
Now, I'd recommend against this on the grounds that the responsibility of a Model Binder is to translate a user request into a Request Model and that retrieving data outside of what can be derived from the request goes beyond this scope of responsibility.
I would say a bad idea. The idea of the model binder is that it takes the parameters from the request and creates your model from those. If your model binder, behind the scenes, fills in some of the details from the database this breaks the paradigm. I'd much rather expose the database call in my controller by explicitly fetching the required extra data from the database directly. Note that this could be refactored into a method if used frequently.
I think this is perfectly fine and use this technique all the time.
The only arguments against are very pedantic and amount to arguing over philosophy. IMHO you can put "fill in missing posted data" code into you MVC app as a method in your base controller vs. method in you ActionFilter vs method in you ModelBinder. It all depends on who get what responsibility. To me the model binder can do a lot more than simply wire up some properties from posted values.
The reason I love doing database calls in my modelbinder is because it helps clean up your action methods.
//logic not in modelbinder
public ActionResult Edit( KittyCat cat )
{
DoSomeOrthagonalDatabaseCall( cat );
return View( new MODEL() );
}
vs.
//logic in model binder
public ActionResult Add( KittyCat cat )
{
return View( new MODEL() );
}
It violates the way MVC is supposed to work. ModelBinder is for binging Models from the data that comes from the view. Populating missing info from the database is something that is supposed to be handled by the controller. Ideally, it would have same data layer/repository class that it uses to do this.
The reason it should be in the controller is because this code is business logic. The business rules dictate that some data may be missing and thus it must be handled by the brains of the operation, the controller.
Take it a step further, say you want to log in the DB what info the user isn't posting, or catch an exception when getting the missing data and email admins about it. You have to put these in your model binder this way and it gets more and more ugly with the ModelBinder becoming more and more warped from its original purpose.
Basically you want everything but the controller to be as dumb and as specialized as possible, only knowing out how to carry out its specific area of expertise which is purely to assist the controller.
I would say, no.
Here's why: It would create a dependency on your database for testing your controller actions that would not be easy to abstract out.
I would say it is ok. The argument that creates dependency to database is a false argument for 2 reasons:
1- Database access should be abstracted via repository interfaces. Repository interfaces are part of the domain model and their implementation is part of the infrastructure/data access layer. So there is no dependency to the database.
2- Model Binders and Controllers are both part of presentation layer implemented using ASP.NET MVC Framework. If Controllers are allowed to access database using repository interfaces, how come Model Binders are not allowed?
Also, there are situations that you'd "better" fill the missing data in your model from Model Binders. Consider the scenario where you have a drop-down list on your view. The first time the view is loaded, the drop-down list is populated. The user submits the form but the validation fails. So you'll need to return the form again. At this stage, you'll have to re-populate the list in the Model for the drop-down list. Doing this in Controller looks ugly:
public ActionResult Save(DocumentViewModel viewModel)
{
if (!ModelState.IsValid)
{
viewModel.Categories = _repository.GetAll();
return View(viewModel);
}
}
I believe the initialization of Categories here is ugly and like a code smell. What if you had a few properties that needed to be filled out from database? What if you had more than 1 action that had DocumentViewModel as an argument? You'd have to repeat this ugly step over and over. A better approach is to fill all the properties of the model using the Model Binder and pass it to the Controller. So the object that is passed to the controller is in a "consistent" state.

asp.net MVC - complex example?

We're evaluating asp.net MVC and are looking for some more complicated examples over and above NerdDinner.
Specifically, in a more complex web app, I might have a navigation bar (including primary nav, a search box and a log-in status display), a main content area, a sub-content area (including related content) and a footer. In MVC a controller returns a ViewModel (not a View if I'm thinking that I want to de-couple my Controller from my View) - would my ViewModel have to have properties to cover each and every aspect of the "page" I am aiming to render as output?
If this is unclear, I may be able to re-word my question.
BTW - I know this site is built using MVC. I'm after downloadable examples.
Thanks in advance.
Take a look at CodeCampServer.
Edit: With reference to your query about view models, this isn't the perfect answer to it but thought I'd draw attention to AutoMapper (used by CodeCampServer) which can assist with auto mapping data between models and view models which is a real time saver. Also worth considering the concept of Input Builders (there's some available with MVCContrib and also some in ASP.NET MVC 2) which will also reduce the amount of data you have to pass into a view by encapsulating common functionality across the board.
There's a good video on the ASP.NET MVC 2 offering here: http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-ASPNET-MVC-2-Preview-1-with-Phil-Haack-and-Virtual-Scott/.
Here ya go:
<% Html.RenderAction<LayoutController>(c => c.SearchBox()); %>
<% Html.RenderAction<LayoutController>(c => c.NavBox(Model)); %>
Put these in your masterpages, or on specific views for sidebar widgets, and abstract their logic away from your controller/viewmodel you are working on. They can even read the current RouteData (url/action) and ControllerContext (parameters/models), cause you are dealing with ambient values in these objects - and executing a full ActionMethod request!
I blogged about this little known secret here. I also blogged about where this is located, which is the ASP.NET 1.0 MVC Futures assembly that is a seperate add-on from Microsoft.
Steve Sanderson actually gives gives examples of complex logic and application building in a book I have called Pro ASP.NET MVC (shameless plug, I know, but it's what you are looking for in your question), where he actually uses the RenderAction! I made the blog post, before I even read the book so I am glad we are on the same page.
Actually, there are dozens of extensions and functionality that was developed by the ASP.NET MVC team that was left out of the ASP.NET MVC 1.0 project - most of which makes complex projects much more managable. This is why more complex examples (list above in most people's answers) have to use some type of custom ViewEngine, or some big hoop jumping with base controllers and custom controllers. I've looked at almost all of the open source versions listed above.
But what it comes down to is not looking at a complex example, but instead knowing the ways to implement the complex logic that you desire - such as your Navigation bar when all you have is a ViewModel in a single controller to deal with. It gets tiring very quickly having to bind your navbar to each and every ViewModel.
So, an example of these is the Html.RenderAction() extension (as I started off with) that allows you to move that more complex/abstracted logic off of the viewmodel/controller (where it is NOT even your concern), and place it in its own controller action where it belongs.
This littler baby has saved MVC for me, especally on large scale enterprise projects I am currently working on.
You can pass your viewmodel into the RenderAction, or just render anything like a Footer or Header area - and let the logic be contained within those actions where you can just fire and forget (write the RenderAction, and forget about any concern of what it does for a header or footer).
You are welcome to take a look at good.codeplex.com
It has much of what you seek above but there is work to be done! However, after you've looked I'd be happy to field questions on it here or over on codeplex.
This is what mygoodpoints.org is currently running on.
would my ViewModel have to have
properties to cover each and every
aspect of the "page" I am aiming to
render as output?
Yes. There is another option with RenderAction, but apart from that a ViewModel in generall is often big and you have to find a good way to fill it. I admit this sounds like a trouble spot first.
AtomSite is a blog engine written using ASP.NET MVC
As far as I know, a Controller directly returns a View and can pass data to the View using either the ViewData or the Context.
The former is just a loose bag of various bits of data, whereas the latter is a specific type.
The ViewModel would be passed to the View as the Context (and the mark-up of the View would be strongly-typed to the type of ViewModel it expects).
That's my 2c worth :) Hope that helped-- sorry I could not include any downloadable examples.
To automatically pass data to all views, you can make your own controller class and use that:
Example
public class MyController : Controller
{
private User _CurrentUser;
public User CurrentUser
{
get
{
if (_CurrentUser == null)
_CurrentUser = (User)Session["CurrentUser"];
return _CurrentUser;
}
set
{
_CurrentUser = value;
Session["CurrentUser"] = _CurrentUser;
}
}
/// <summary>
/// Use this override to pass data to all views automatically
/// </summary>
/// <param name="context"></param>
protected override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
if (context.Result is ViewResult)
{
ViewData["CurrentUser"] = CurrentUser;
}
}
}

Resources