ASP.NET MVC: run code after view has rendered (close db transaction) - asp.net-mvc

I am using ASP.NET MVC2 with NHibernate, but am facing an issue. All calls to the database via NHibernate should be inside a transaction, however code inside the view kicks off database calls in some instances. Thus there is a need to be able to commit the transaction after the view has rendered.
For example displaying a list of users and their user roles you might show the user role using this code: <%: Model.UserRole.Name %>
This will cause a hit on the database as the UserRole is loaded using a NHibernate proxy.
You can fetch the UserRole eagerly which circumvents the issue in this case, but there are cases where it is much faster to use lazy loading.
Anyway, is there a way to run code after the view has rendered?

Have you tried to use session-per-request pattern? It's a very natural way of handling NHibernate sessions in web environment.
There are many information available when you do a Google search on "NHibernate session per request", like this blog post.
Also, take a look at great Bill McCafferty's article NHibernate Best Practices. Although it's written for NHibernate 1.2, it has a wealth of information. While there, his S#arp Architecture also looks very cool :)

How about an action filter?
public class CleanUpAttribute: ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
//cleanup code here
}
}
Then you decorate your controllers with this attribute.

Related

ASP.NET WEB API Multiple Interfaces

I am designing ASP.NET WEB API service with two interfaces. First interface is read-only and second one is admin interface (to be used with MVC app) with full CRUD support. Does anyone know where I can get more information on such setup, any tutorials, walk thought, sample design document?
Also does it worth splitting these into two interfaces or keep them in same? But problem is that in read-only I expose 2-3 properties for every object while for admin there are 10-15?
Similar setup for WCF or design spec will do.
If I understand what your wanting to do, may I suggest rather than having one URL, i.e. \dataStuff\dataView split off into another view, maybe \dataStuff\edit\ which only admin's have access to, can be done like so:
[Authorize(Roles = "Administrators")]
public ActionResult edit()
{
return View();
}
then next to each data element that your viewing add the following to ONLY admin's through use of User.IsInRole
#foreach (var item in Model.dataTable)
{
#*
write a value from the data table here
*#
#Html.ActionLink("edit", "edit").If(User.IsInRole("Administrators"))
<br/>
}
obviously you don't have to display your data like this, I'm just showing that you add to the end of each element of the database an edit ActionLink IF the user is admin.
This allows your admin to view data like a user and also have the added functionality they need. Code re-use is better than a single view which has two states, Admin and non Admin.
Sorry if this isn't the best explanation, fairly new to MVC
Seems like this concept is sometimes called CQRS.
Sample: http://martinfowler.com/bliki/CQRS.html

Requerying database on MVC postback

In a previous post (ASP.NET MVC 5 Model-Binding Edit View), the answer suggested this Controller code to process an edit-view postback:
public ActionResult Edit(WarrantyModelEditViewModel vm)
{
if (ModelState.IsValid)
{
var warranty = db.Warranties.Find(vm.Id);
.
.
.
}
Question:
Is re-querying the database for the warranty in question really the only way to do this in MVC and is it considered a best-practice approach? (I saw this post, How to re-use model data on post back with MVC, but it was a bit dated so I want to be sure my information is current as of MVC 5 and EF 6.)
In addition, I imagine there are various database concurrency issues, such as if the record was modified or deleted by another user after the view is rendered but before postback. Are there any good resources that discuss ways of handling the various scenarios?
You can also do an attach the entity which requires only one call to database. Check this solved thread.
In short something like this -
db.Users.Attach(updatedUser);
var entry = db.Entry(updatedUser);
entry.Property(e => e.Email).IsModified = true;
// other changed properties
db.SaveChanges();
For your second question to get optimistic concurrency, you can have a column called timestamp and can check for it during updates. Check this tutorial - Handling Concurrency with the Entity Framework in an ASP.NET MVC Application

Howto: simply read SQL Server database to MVC 4 view?

I am relatively new to MVC. I am trying to just display the contents of a remote SQL Server table on a page. It is READ ONLY, and nearly everything I find online is utilizing the Entity Framework or something similar which is overkill for what I am after. I just need to print all the rows from a table out to a view.
So my questions are:
should I just hack the sqlconn and everything into the view that I want the data printing out to?
Or should I add the sql in that view's controller?
Create a model and somehow get that data back into the view?
I know step #3 is the 'correct' way to do it, however I am looking for something simple and quick. :)
Thanks everyone!
You say EF is overkill, but that's the easiest way to do this. Maybe use Linq to SQL, since that's more lightweight. This is all there is to it:
Generate the EF / L2S entity classes
Instantiate the database context in the controller, and get all records
Return the IEnumerable records to the view
In the view, use #Html.DisplayForModel()
Here's a simple example. Note that returning the database entity classes is considered bad practice, you should map / automap them to a View Model type class first.
Home Controller
public ActionResult Index()
{
MyEntityModel[] items = MyDatabaseContext.GetAllRows();
return View(items);
}
Home/Index View
#model IEnumerable<MyEntityModel>
#foreach (MyEntityModel item in Model)
{
#Html.DisplayFor(m => item)
}
Without EF / L2S it's almost as easy, but you'd have to create your own entity / wrapper class for the database records and populate them manually.
There are also scaffolding projects for MVC that will generate repository and controller classes, as well as Razor views. See for example MVC Scaffolding on NuGet.
Once you get used to forcing yourself to use Entity Framework for even your "small" applications then and only then will you truly understand that is it the simplest way.
Sure, if you come from a background of memorized ADO.NET dataset/datatable/datareaders etc.. then sure you have projects with "canned" operations that you port over and modify but it is truly just old and cost you more time in the long run.
Use EF
Use multiple projects in a solution
Use a repository pattern if you can, it pays off in dividends for reasons you will discover
Keep your controllers "skinny"
Dont' use a "ViewModel" just to use / do it.
The SOC of having View and Controller are critical, but the Models folders does not need to be used, you can wire things up without it if you want, just pay attention to where your "model" is and abiding by SOLID principle etc..

CQS and ASP.NET MVC Actions

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

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