Skip to main content

Posts

Showing posts from June, 2018

TFS Build Agent - SSL certificate problem: unable to get local issuer certificate

After upgrading to a new TFS server and going full HTTPS, our git based builds started to fail with the following error message: 2018-06-12T21:28:45.8463514Z ##[command]git init "D:\Builds\dev-agent-1\_work\5\s" 2018-06-12T21:28:45.9154418Z Initialized empty Git repository in D:/Builds/dev-agent-1/_work/5/s/.git/ 2018-06-12T21:28:45.9219662Z ##[command]git remote add origin https://tfs/DefaultCollection/_git/Sample 2018-06-12T21:28:45.9821910Z ##[command]git config gc.auto 0 2018-06-12T21:28:46.0407163Z ##[command]git config --get-all http.https://tfs/DefaultCollection/_git/Sample.extraheader 2018-06-12T21:28:46.0994413Z ##[command]git config --get-all http.proxy 2018-06-12T21:28:46.1508406Z ##[command]git -c http.extraheader="AUTHORIZATION: bearer ********" fetch --tags --prune --progress --no-recurse-submodules origin 2018-06-12T21:28:46.3636860Z fatal: unable to access 'https://tfs/DefaultCollection/_git/Sample/': SSL cert

ASP.NET - Sharing state between Action Filters and Controllers

The support for ActionFilters in ASP.NET MVC and Web Api gives you a nice execution pipeline to run code before or after specific stages in the request processing pipeline: They are a great fit for a lot of use cases, like validation, caching, … and allow you to have an AOP like approach in your controllers. Their are 2 things I find annoying about the usage of ActionFilters: They introduce an extra layer of abstraction with some hidden magic. It is not always clear what’s going on the request pipeline and what happened in a specific filter. It is not easy to share state between your action filter and your controller (which can be useful sometimes). Recently I discovered a great trick that solves the problems above. Did you know that a controller is also a filter – as it implements both IActionFilter and IAsyncActionFilter interfaces, you can override the related methods and turn your controller into an action filter?

NHibernate Immutable Types

To prevent that changes to your objects end up accidently into your database, NHibernate supports type immutability. This is something you can set at the ClassMap level(if you are using the mapping by code): With Fluent Nhibernate, you have to use the ReadOnly property: Remark: Using this property makes sure that the objects that you retrieve are read-only, so you cannot UPDATE them. However, it does NOT prevent the creation of new records or even the deletion of existing records in the database.

OData Query error: The query specified in the URI is not valid. The limit of '0' for Top query has been exceeded. The value from the incoming request is '100'

After configuration my OData service, I tried to do a first call by using a $top parameter to get the first 100 results. However this didn’t turned out to a big success. Instead of some data, I got the following error message back: {"error":{"code":"","message":"The query specified in the URI is not valid. The limit of '0' for Top query has been exceeded. The value from the incoming request is '100'.","innererror":{"message":"The limit of '0' for Top query has been exceeded. The value from the incoming request is '100'.","type":"Microsoft.OData.ODataException","stacktrace":"   at System.Web.OData.Query.Validators.TopQueryValidator.Validate(TopQueryOption topQueryOption, ODataValidationSettings validationSettings)\r\n   at System.Web.OData.Query.TopQueryOption.Validate(ODataValidationSettings validationSettings)\r\n   at System.Web.ODat

TFS Build error - System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.Web.Administration.Interop.IAppHostWritableAdminManager'.

After replacing one of our build servers, we got the following error when trying to execute a custom XAML build Workflow activity: System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.Web.Administration.Interop.IAppHostWritableAdminManager'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{FA7660F6-7B3F-4237-A8BF-ED0AD0DCBBD9}' failed due to the following error: Interface not registered (Exception from HRESULT: 0x80040155). at Microsoft.Web.Administration.ConfigurationManager.CreateAdminManager[TClass,TInterface](WebConfigurationMap webConfigMap, Boolean isAdminConfig) at Microsoft.Web.Administration.ConfigurationManager.CreateConfiguration(WebConfigurationMap configMap, String configPathToEdit, Boolean isAdminConfig) at Microsoft.Web.Administration.ConfigurationManager.GetConfiguration(String rawConfigurationPath, String cacheKey,

Razor View compilation in ASP.NET Core

Update 26/6/2018: It can happen that what I describe below lead to much longer build times. This is a know issue. More information here: https://www.danielcrabtree.com/blog/444/speed-up-compilation-of-asp-net-core-2-1-projects One of the ways to increase the speed of your ASP.NET MVC applications was by enabling view compilation. By default Razor views are not pre-compiled leading to longer startup times. Another disadvantage is that errors in views were not detected until you are running in the browser. Enabling view compilation solves this all. Here is how to enable this in ASP.NET MVC: https://www.codeproject.com/Articles/1169354/Pre-compiled-Razor-View-in-ASP-NET-MVC The question is, can you do the same thing in ASP.NET Core MVC? In ASP.NET Core MVC, this behavior is enabled when the Microsoft.AspNetCore.Mvc.Razor.ViewCompilation package is referenced. As the Microsoft.AspNetCore.All package pulls in this package, this behavior is enabled by default for all new projects. I

Cookie lifetime in Chrome

While documenting our security and privacy policies for GDPR, I got a question about the Windows Identity Foundation cookies created after logging into ADFS. When looking in the Chrome Developer tools, we noticed that the Expires/Max-Age setting was set to 1969-12-31…: We were wondering why this strange date? When I opened the same site in Edge, I saw the following in the Edge Developer Tools: The cookie lifetime is set to Session, which makes more sense. Probably the Chrome Developer Tools are showing a minimum date when the cookie lifetime is linked to the session. Kind of confusing…

ASP.NET Web API OData error: ValueFactory attempted to access the Value property of this instance.

After following the tutorial here; https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint I got the following error when I tried to run the OData endpoint: System.InvalidOperationException was caught   HResult=-2146233079   Message=ValueFactory attempted to access the Value property of this instance.   Source=mscorlib   StackTrace:        at System.Lazy`1.CreateValue()        at System.Lazy`1.LazyInitValue()        at System.Lazy`1.get_Value()        at System.Web.Http.Dispatcher.DefaultHttpControllerSelector.GetControllerMapping()        at System.Web.Http.Routing.AttributeRoutingMapper.AddRouteEntries(SubRouteCollection collector, HttpConfiguration configuration, IInlineConstraintResolver constraintResolver, IDirectRouteProvider directRouteProvider)        at System.Web.Http.Routing.AttributeRoutingMapper.<>c__DisplayClass2.<>c__DisplayClass4.<MapAttribu

Angular 5 Build issues - Cannot find module 'webpack/lib/dependencies/ContextElementDependency'

After upgrading to Node.js version 8 on our build server, one of our development teams contacted me because their build started to fail. Here is the error they got when running ‘ng build’: 2018-06-14T06:20:11.8790352Z ##[section]Starting: ng build 2018-06-14T06:20:11.9073421Z ============================================================================== 2018-06-14T06:20:11.9073421Z Task         : npm 2018-06-14T06:20:11.9073421Z Description  : Run an npm command 2018-06-14T06:20:11.9083182Z Version      : 0.2.22 2018-06-14T06:20:11.9083182Z Author       : Microsoft Corporation 2018-06-14T06:20:11.9083182Z Help         : [More Information]( https://go.microsoft.com/fwlink/?LinkID=613746 ) 2018-06-14T06:20:11.9083182Z ============================================================================== 2018-06-14T06:20:15.5560039Z [command]C:\Program Files\nodejs\npm.cmd config list 2018-06-14T06:20:17.1849642Z ; cli configs 2018-06-14T06:20:17.18496

Azure–Single Instance VMs with 99.9% SLA

When Microsoft introduced their IAAS offering on Azure, the general rule to have a 99.9% SLA was to have at least 2 VMs provisioned. Most of my customers who I talk to today remember this rule and think that it still applies. Where in fact, there is since 2016 an option to provide a single instance VM and have the 99.9% SLA guarantee too! The biggest requirement to achieve the 99.9% SLA guarantee for a single instance VM is to use Premium Storage. Premium Storage offers a much higher level of availability and performance with 5,000 IOPS per disk, versus 500 IOPS per disk with Standard Storage. The way Premium storage offers this is by utilizing SSD storage drives within the data center that are located on the same server hardware where the VM is running. Premium storage also offers a much higher throughput rate per disk of 2 Gbps. Why should I still prefer multi-instance VMs? It can still be adventagous to use a multi-instance VM configuration, because the SLA is a higher(99.9 5

Play with Kubernetes classroom

If you want to learn Kubernetes in a quick and easy way, have a look at https://training.play-with-kubernetes.com/ From the website: The Play with Kubernetes classroom is a new site provided by Docker that helps you get hands-on experience using Kubernetes. We provide a workshop that will allow you, in the browser, to follow a Kubernetes tutorial without having to install a single thing. Kubernetes Hands-on Workshop

C#–Task vs ValueTask

The combination of async/await with the power of the TPL(Task Parallel Library) makes async programming in .NET a breeze. The only disadvantage of using the Task based programming model, is that it’s like a virus that starts to spread all around your code. Since Task (Task) is a reference type, returning Task object from async method means allocating it on heap every time. And this is needed in many cases. In these cases where the async method returns a result immediately or completes synchronously, this allocation is unnecessary and can become costly. To avoid this extra allocation a ValueTask structure was added to .NET 4.7. The compiler doesn’t care if your async method returns a Task or ValueTask , so there are completely interchangeable; So why shouldn’t I switch to ValueTask everywhere? There are some tradeoffs you must take into consideration before using ValueTask. ValueTask is a value type with 2 fields. The Task is a reference type with just one field.   When y

Using Azure Container Instances to host ElasticSearch

As I’m doing a lot of demos using ElasticSearch, I like to use Azure Container Instances to spin up a new container image. To simplify the creation process, I’m using the Azure CLI in combination with the script below: Remark: this is a copy of one of the scripts found here; https://github.com/markheath/aci-getting-started/blob/master/m1-01-elasticsearch.ps1

ElasticSearch–Wait for index refresh

By default when you index a document in ElasticSearch it only becomes available for search operations after a certain time.  This is because ElasticSearch will refresh shards that have changed only after a certain interval(by default 1 second). If this is not the behavior you want,  you can control when changes are made visible by setting the refresh parameter to one of the following values: Empty string or true Refresh the relevant primary and replica shards (not the whole index) immediately after the operation occurs, so that the updated document appears in search results immediately. This should ONLY be done after careful thought and verification that it does not lead to poor performance, both from an indexing and a search standpoint. wait_for Wait for the changes made by the request to be made visible by a refresh before replying. This doesn’t force an immediate refresh, rather, it waits for a refresh to happen. Elasticsearch automatically refreshes shards that have changed ev

Entity Framework Core 2.1 - Avoiding the n+1 issue

With the release of Entity Framework Core 2.1, the team did some changes to the query translation to avoid executing n+1 SQL queries. The n+1 problem occurs when you first fetch the some root data and later on use a navigation property while looping through all results(for example when you project your domain model to a viewmodel to return it from an API call). An example; the following query normally gets translated into one query for Customers, plus N (where “N” is the number of customers returned) separate queries for Orders: To avoid the n+1 issue, you can optimize this query by buffering the results from the sub-query. To achieve this, you have to modify your query and add a ToList() in the right place: An example; this time the query will be translated to only two SQL queries: One for Customers and the next one for Orders. More information: https://blogs.msdn.microsoft.com/dotnet/2018/05/30/announcing-entity-framework-core-2-1/

NHibernate–Persist vs Save

While reviewing some code today I noticed that a developer was using the NHibernate session.PersistAsyc() method to save an entity in the database. I always used the session.SaveAsync() method so I was kinda intrigued about the difference between the two. Let’s first talk about how they are the same; both methods make a transient instance persistent. This means that a new object created somewhere inside your code will be inserted into the database using an INSERT statement. The picture below explains the different states of an NHibernate object quite well: The differences Ok, now we know in which way they are the same. How are they different then? The SaveAsync() method returns the persisted object whereas the PersistAsync() method returns nothing. The PersistAsync() method doesn't guarantee that the identifier value will be assigned to the persistent instance immediately, the assignment might happen at flush time. This means that when calling the SaveAsync() m

MediatR and StructureMap–Using Generic NotificationHandlers.

One of our application is using a CQRS approach in combination with MediatR and StructureMap . Part of the application is rather straightforward and to avoid a lot of boilerplate code we would like to use a NotificationHandler that could handle generic events. Here is the code we had written: However when we tried to register this using StructureMap nothing happened resulting in no event that was picked up by the NotificationHandler. Here is the registration code we had: The problem is that it is one level of generic too deep to handle by StructureMap, so StructureMap has no clue on how to close this open generic. To solve this problem we can create our own registry convention: As a last step we have to apply this convention when configuring StructureMap:

Issue building UWP apps: Error WMC1006: Cannot resolve Assembly or Windows Metadata file

A customer contacted me because they had errors building an UWP application on one of their build servers. Here are the related build logs: MarkupCompilePass1:   Creating directory "obj\x86\Release\intermediatexaml\". App1\App1.csproj(0,0): Error WMC1006: Cannot resolve Assembly or Windows Metadata file 'Type universe cannot resolve assembly: System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.' D:\Builds\dev-agent-1\_work\76\s\App1\App1.csproj : XamlCompiler error WMC1006: Cannot resolve Assembly or Windows Metadata file 'Type universe cannot resolve assembly: System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.'   (Out) GeneratedCodeFiles: 'D:\Builds\dev-agent-1\_work\76\s\App1\obj\x86\Release\App.g.i.cs;D:\Builds\dev-agent-1\_work\76\s\App1\obj\x86\Release\App.g.cs'   (Out) Compile: 'App.xaml.cs;MainPage.xaml.cs;Properties\AssemblyInfo.cs;D:\Builds\dev-agent-1\_

NHibernate auto-import

By default NHibernate supports the auto-import feature. This allows you to use unqualified class names in the HQL query language. This feature can become a problem if you have 2 classes with the same name (e.g. ExampleClass ) but living in a different namespace(e.g. Example1Namespace,Example2Namespace ). If you try to initialize your SessionFactory, you will end up with the following error message: "duplicate import: Example refers to both Example2Namespace.ExampleClass, Example2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null  and Example1Namespace.ExampleClass, Example1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null (try using auto-import=\"false\")" As a solution, you can set auto-import=false in your NHibernate mapping files. Remark: This however does introduce another issue – it forces you to use the fully qualified name of these classes in HQL queries.

Mobile vs Web: https://whatwebcando.today/

With the introduction of Progressive Web Apps, the discussion if web applications can and will replace native mobile applications has started all over again. To feed the discussion, have a look at https://whatwebcando.today/ and decide for yourself if you can rely on the Web Platform features to build your next mobile application…

Attempt by security transparent method 'System.Web.Http.GlobalConfiguration.get_Configuration()' to access security critical type 'System.Web.Http.HttpConfiguration' failed.

After doing a new deploy on our IIS server, we got the following error when we tried to start our ASP.NET MVC application: System.TypeAccessException: Attempt by security transparent method 'System.Web.Http.GlobalConfiguration.get_Configuration()' to access security critical type 'System.Web.Http.HttpConfiguration' failed. This rather obscure error didn’t ring a bell. And the explanation was not very helpfull. When we looked at what had changed between this version and a previous version of the application, we noticed that WebApi was added to the solution. The NuGet package.config showed us that one of the packages had a rather different version: <package id="Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net47" /> <package id="Microsoft.AspNet.WebApi.Core" version="5.2.6" targetFramework="net47" /> <package id="Microsoft.AspNet.WebApi.WebHost"