Tigraine

Daniel Hoelbling-Inzko talks about programming

NHibernate removes items from Many-To-Many upon Update of Entity due to Model Binding

Imagine the following scenario:

nh

Townships has two m:n collections mapped to Region. My Controller has special actions for updating these collections, while there is a generic Edit method that takes care of updating normal properties on Township. The code in question looks quite innocent:

[HttpPost]
public virtual ActionResult Edit([Bind]T item)
{
    if (!ModelState.IsValid) return View(item);
    using (var trans = session.BeginTransaction())
    {
        session.Update(item);
        trans.Commit();
    }
    return RedirectToAction("List");
}

Well, the problem is quickly found using NHProf:

image

Whenever I updated the Township entity all it’s associated Regions where cleared.

Turns out, the problem lies with the ModelBinder in MVC2: Since it reconstructs a new Township item and populates it with values from the request, there is no way for MVC to fill the WinterRegions and SummerRegions collection. So NHibernate got empty collections and assumed I removed all items from them and decided to persist that removal to the database, resulting in a DELETE.

There are two solutions to the problem: a) turn off Cascade.All b) Fill the collections before the update.

Since I already used the Cascade Behavior in other places I decided to go with b and select the entity prior to updating it. The resulting code looks like this:

[HttpPost]
public override ActionResult Edit([Bind]Township item)
{
    using (var trans = session.BeginTransaction())
    {
        var township = session.Get<Township>(item.Id);
        session.Evict(township);
        item.WinterRegions = township.WinterRegions;
        item.SummerRegions = township.SummerRegions;
        session.Update(item);
        trans.Commit();
    }
    return RedirectToAction("List");
}

Notice that it is important to first evict the fetched entity from the session, otherwise you’ll get an Exception stating that the same identified is already associated with this session cache.

To be honest: I don’t feel particularly fond of this solution, if anyone can point out a better solution please leave a comment or email me. While at it, it would be nice to be able to change the cascade behavior of entities for one session (like FetchMode for one criteria).

Filed under net, programmierung, nhibernate

dotless Version 1.1 Released!

logo

After a lot of work we finally released a new version of dotless. And this release is really sweet. We switched parsers from the troubled PEG parser we had to an all-new implementation of the less.js parser that gave us a ton of room for improvements and little tweaks.

Here’s a rundown of the most important features:

New Parser

New parser also means we finally have meaningful error messages and if there are syntax errors we tell you what line the error occured and what went wrong. So that’s a huge improvement for all the people who saw empty .css files trying to figure out what broke the compilation.

Parameter passing

One thing users have  been asking us for are parameters to be passed to the scripts. We finally found a good way to implement this and now it’s in.

If you use the HttpHandler you can simply pass parameters through the querystring. Let’s say you have a basecolor you want to pass to your .less file you simply call it from the site like this:

http://www.myserver.com/site.less?basecolor=#34679a

and the variable @basecolor will be set to #34679a for you in your script. This is especially handy if you are using the HSL functions where you can modify saturation, lightness etc.

If you are using the console compiler you can also leverage this new functionality through a very Ant like parameter syntax:

dotless.Compiler.exe test.less –Dbasecolor=%2334679a

Note: Parameters in querystrings have to be URL encoded or some browsers will act up.

Improved Caching

We also made sure that the cache works properly with parameters, so if two requests have the same parameters the cache will be used. If not, dotless will insert for every parameter/file combination one cache entry. Since parameters are by no means user-input values but usually limited to a set of values the designers specify this should still give you very good performance. Behind the scenes we are still using the ASP.NET cache infrastructure.

While at the topic of caching, we also improved cache invalidation. The old version did not watch all imported files for changes but only the main .less file. This has changed, you should now never have to think about disabling the cache during development.

The same change was also applied to the console compiler, if you start it with –watch the compiler will regenerate the CSS whenever any of the imported changes or the main file gets changed.

Runnable in medium trust

Well, nothing really exciting here, but you should now be able to run dotless in a shared hosting environment.

Other improvements

  1. Cleaner output
  2. better support for CSS3
  3. Many more..
    A big thanks goes to James Foster who did most of the heavy lifting involved with bringing you this new release. You can download the new version from our website at http://www.dotlesscss.com. Remember, dotless is open source and released under the Apache License, Version 2.0, the source can be easily found on GitHub.

ASP.NET MVC2 &ndash; Make Custom ControllerFactory less painful

When starting a new project on ASP.NET MVC2 I noticed something very annoying. When used with a custom ControllerFactory the framework will throw a HttpException whenever a browser requests a file that is not present on the file system or not mapped by a route.

That means you’ll hit an exception about once per page-load just because Google Chrome is requesting the favicon all the time unless it finds one.

The solution to this is to make the Debugger just step through your CreateController method so no Exceptions will be visible to Visual Studio there:

[System.Diagnostics.DebuggerStepThrough]
public override IController CreateController(System.Web.Routing.RequestContext requestContext,
                                                string controllerName)
{
    return base.CreateController(requestContext, controllerName);
}

This works reasonably well for me right now, at least the pain of hitting F5 every 10 seconds while debugging has gone away. It’s still not perfect since it makes it impossible to actually debug the method if something really goes wrong, but you’ve always got the yellow screen of death to figure out what’s wrong.

Hope this helps!

Filed under net, programmierung

My Photography business

Projects

dynamic css for .NET

Archives

more