31/08/2016

AjaxExtensions.BeginForm doesn't work. Really?

Home


Source: own resources, Authors: Agnieszka and Michał Komorowscy

The goal of using Ajax is to communicate with the server asynchronously without reloading the entire page. Specifically AjaxExtensions.BeginForm can be used to updated a selected part of a web page. It is relatively easy in use but can be also troublesome. Especially, when we try to apply it in an application which wasn't using Ajax earlier. I decided to wrote this short technical post because recently I came across the following issue the few times:

AjaxExtensions.BeginForm redirects a user to a new page instead of refreshing a fragment of a current one.

This problem has an easy explanation. Under the hood AjaxExtensions.BeginForm uses Java Script library called Microsoft jQuery Unobtrusive Ajax. The issue is that this library is not installed by default if we create a new project. It's easy to forget about it.

If you have the described problem:
  • Check in packages.config file contains Microsoft.jQuery.Unobtrusive.Ajax package.
  • Check if jquery.unobtrusive-ajax.js file is referenced in html e.g.: <script src="/scripts/jquery.unobtrusive-ajax.js"></script>
  • If you use bundles checik if jquery.unobtrusive-ajax.js was included in a bundle e.g.:
    public static void RegisterBundles(BundleCollection bundles)
    {
       ...
       var js = new ScriptBundle("~/bundles/MyBundle").Include("~/Scripts/jquery.unobtrusive-ajax.js");
       ...
    }
  • Besides, check if a bundle with jquery.unobtrusive-ajax.js is rendered properly e.g.:
    @Scripts.Render("~/bundles/MyBundle")

23/08/2016

.NET Developer Days 2016 are coming

Home


.NET Developer Days 2016 is a third edition of the biggest conference in Central and Eastern Europe dedicated to the .NET platform. I didn't participate in previous editions but this time I'll be. Why? Well, I read a few quite good reviews of a former editions. Besides, recently a friend of mine told me that he was going to go there what is also a good recomendation.

To make things funny, when I was about to buy tickets organizers of the conference asked me to write about it. So yes it is a sponsored text but I wouldn't write it if didn't want to go there anyway. Let's start with a few facts about .NET Developer Days 2016:
  • What: 3 tracks with 24 presentations.
  • Where: 
    • Conference: EXPO XXI Exhibition Center – Warsaw, Prądzyńskiego 12/14
    • Workshops: GoldenFloor, Millenium Plaza – Warsaw, Al. Jerozolimskie 123 a
  • When: 19th-21th October 2016. The workshops will take place on October 19th, and the conference will start one day later. Organizers also plan a party at the end of day one. I think that it'll be a good occasion for networking.
  • Language: 100% English
I'm still thinking which presentations to choose but I have a few solid candidates. I remember Jon Skeet from Dev Day conference. He gave a really good presentation so it is my number one. This time he will start the conference and then will talk about Abusing C# and Immutability. I also saw a few presentations delivered by Tomasz Kopacz in the past. As far as I remember he was always a mine of information. His presentations were advanced and demanding but you could learn a lot from them.

I also heard a lot of good about Maciej Aniserowicz so his presentation about CQRS is also on my list. I don't know other speakers but there are many other promising topics to choose from. For example, I'd like to listen Alex Mang who will talk about containers or Adam Granicz who will give a presentation about funcional programming or ... Actually, I already see some potenial conflicts in my personal agenda so as you can see the choice is not easy. I encorage you to see the full agenda on the conference site. If you want to buy a ticket do it sooner than later because the price goes up every 2 months.

See you there!

19/08/2016

My struggels with GitHub, Subtrees and Nuget

Home


Source: own resources, Authors: Agnieszka and Michał Komorowscy

Some time ago I decided to publish my projects on GitHub. This decision had very positive repercussion because it mobilized me to do more refactoring and to clean my solutions. Additionally, I switched totally to management of external references via NuGet. Earlier, I had some binaries in a dedicated directory on my computer. It took me some time but it was worth doing it.

I also had to solve the following problem. I have a solution called Common. It is a collection of libraries, utilities, algorithms, helpers etc. that are used in my other projects. Before migration to GitHub, after a build, all Common binaries were copied to the well known location i.e. N:\bin Thanks to that all other projects could reference them from this location. It works. However, if someone wants to download my projects from GitHub, he or she will need to create a mapped drive N manually. I din't like it.

The next step was to switch from absolute references to binaries to relative references to projects. For example let's consider a library MK.Utilities and a project LanguageTrainer that uses it. Initially LanguageTrainer was referencing:

N:\bin\MK.Utilities.dll

After migration this reference was changed to:

..\..\Common\MK.Utilities\MK.Utilities.csproj

Much more better, isn't it? Still, it is not perfect. This relative path will work only if the folder with Common and LanguageTrainer solutions will be in the same place on the disk. Besides, in order to compile LanguageTrainer solution Common solution must be built first. What's more Common and LanguageTrainer are two separate repositories which have to be downloaded individually. My goal was to be able to download any repository/solution and then be able to compile it without any further steps.

I started reading about possible solutions and I found information about git submodules and git subtrees. There is so much about them in Internet so I will not repeat others. For example see this post. At the end I decided to use subtrees. Simplifying a subtree is a copy of some repository in the another one. Returning to my earlier example, by using subtrees I got a copy of Common repository/solution in LanguageTrainer repository/solution. Then I could change the reference to MK.Utilities as follows:

..\Common\MK.Utilities\MK.Utilities.csproj

Besides, I needed to add MK.Utilities project to LanguageTrainer.sln solution so that all projects could be build at the same time. Finally, my LanguageTrainer repository/solution looks in the following way. On left side you can see GitHub and on the right side Visual Studio:


If needed I can refresh a copy of Common repository/solution inside LanguageTrainer at any time. Why I used subtrees? Well, they work for me and are extreamly easy to create via Source Tree ;) By the way, I like git but I hate all this complex commands. Source Tree solves this problem and allows me to use git via friendly GUI. I strongly recommend it.

At the end I had to solve one more problem with Nuget. Let's return again to my example and let's assume that LanguageTrainer solution is located here:

C:\LanguageTrainer

In that case, by default, Nuget packages will be located here:

C:\LanguageTrainer\packages

However, we also have a subtree:

C:\LanguageTrainer\Common

And projects from a subtree expects that their packages will be here:

C:\LanguageTrainer\Common\packages

Of course they won't be there so Common projects will not compile. To overcome this problem I had to manually update csproj files and replace ..\packages with $(Solutiondir)packages. For example:

..\packages\structuremap.3.1.6.186\lib\net40\StructureMap.dll

Was changed as follows:

$(SolutionDir)packages\structuremap.3.1.6.186\lib\net40\StructureMap.dll

I hope that this post will help you in your struggles with GitHub, Subtrees and Nuget.

06/08/2016

Why did I do my PhD?

Home


Source: own resources, Authors: Agnieszka and Michał Komorowscy

This is my second post about the longest project I've ever participated in i.e. about doing PhD. I decided that at the beginning I'll write why I actually started my Ph.D. studies and what I think now about my motivations.

I remember quite well this time in 2009 when I made my decision to get a Ph.D. It was supported mainly by a few things. Firstly, at that point I was a newly minted graduate of Warsaw University of Technology and I had a very good memories of my studies, being a student... and I wanted to continue that. Secondly, I wanted to do something different from what I was doing professionally for money i.e. typical applications for business.

Thirdly, I associated Ph.D. title with the some kind of prestige that will allow me to distinguish myself in the future. Fourthly, a half year earlier my wife and a few of my friends also started Ph.D. studies. Don't understand me wrong. I wasn't jealous, I didn't feel worse or something. But taking into account what I've written earlier it was an additional motivation for me.

What I think about these motivations now? I'd say that they are neither good nor bad but they simply are. However, I think that I missed a few important thing in 2009. Do you agree with me that my way of thinking was somehow romantic? Now, I know that it was. I assumed that I would be working professionally for money and I would be doing Ph.D. to "do something different". I didn't think much about my future scientific carrier, doing habilitation... I also didn't think much what I actually want to achieve during my studies. Though thanks to that I had an occasion to play with technologies like Azul Systems or Agilent N2X before focusing on historical debuggers :)

Briefly summarising my Ph.D. studies were a little bit like a hobby. And as any hobby, on the one hand it gives you fun and satisfaction, but on the another hand it doesn't necessarily lead you to something, and can be easily set aside or abandon. Many times I had a moment of doubt or wanted to say stop.

Would I made the same decision if I could go back in time? Definitely yes, but I'd consider it much more carefully. I'd think through area of my research so that it would be more perspective and more valuable on the market. Probably because of financial reasons I'd share my time between Ph.D. and the professional job. However, I'd try to find a job somehow related to my studies, where Ph.D. could be potentially beneficial. Currently in the vast majority of job offers (that I receive) it isn't. I'd also consider doing Ph.D. abroad (outside of Poland) where funding is better so that I'd be able to focus on science. Thanks to that my result would be also better.

You must be both romantic and pragmatic when doing Ph.D.

24/07/2016

Report from the battlefield #5 - Logging can kill performance

Home

Public Domain, https://commons.wikimedia.org/w/index.php?curid=48390
Source: own resources, Authors: Agnieszka and Michał Komorowscy

So far in Report from the battlefield series I wrote about my experiences as an expert in the recruitment company. This time I'll write a bug that I found in the production. It was all about the performance. The problem was that in the new version of an application one operation slowed down about 6 times. Initially, I suspected that amount of data simply increased considerably or some network problems. Fortunately, I easily reproduced the issue on my dev machine. Reproducing a problem is half the battle. Though performance problem are usually difficult to analyse so I was ready for a long investigation.

I started stepping through the code with a debugger just to see what is going on. Everything seemed to be ok until... One of the final operations was to log into a file what was retrieved from a database. What's important the log level was set to Trace so even large amount of data shouldn't matter in the production. Why? Because in the production, precisely because of the performance reasons, the logger should be configured not to log everything to a file. In other words it should ignore messages usually with the log level = Trace or Debug. However, after I had pressed F10 (Step Over), I had to wait a few seconds till the logging ends. BINGO!

My first though was that someone configured the logger in the wrong way in the production. Typical PEBKAC problem. To verify my hypothesis I changed the configuration of the logger and executed the problematic operation. Unfortunately, the problem occurred again. Another look at the code and I know what was wrong. And do you already know?

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

The problem was that for large amount of data the application required a few seconds just to create/prepare a message for the logger. To make thing worse this message was created, regardless if it was later used by the logger or not. During development it may acceptable but not in the production! There are 2 potential solutions of this problem. Details depends on the logging framework:
  • The first approach is to simply check the logging level before creating/preparing a message e.g.:
    if(Logger.LogLevel == LogLevel.Trace) 
    {
        /* Prepare and log a message */
    }
    
  • The second approach is to use deferred execution for example lambdas e.g.:
    Logger.Trace(() => /* Prepare a message */).
    If a logger supports this syntax, a lambda will be executed if and only if it is required.