RSS

Category Archives: General

WebApi ExceptionHandling.ExceptionHandler Sometimes Does Not Handle Global Exception. What ?!

See previous post on how to implement ExceptionHandler.

ExceptionHandler supposed to handle exception globally, but sometimes it does not… what ?!

There are few cases where ExceptionHandler will not capture exception. One of them is when CORS is enabled, see this.

To ensure ExceptionHandling to always capture exception, try:
1. If inherit from ExceptionHandler, override its method `ShouldHandle()`.

        public override bool ShouldHandle(ExceptionHandlerContext context)
        {
            return true;
        }

2. Instead of ExceptionHandling.ExceptionHandler, inherit and implement it’s interface `ExceptionHandling.IExceptionHandler`.

Advertisements
 
Leave a comment

Posted by on November 2, 2018 in General

 

Tags: , , , ,

Fix Linq Generate ‘ESCAPE’ Keyword on Contains/StartsWith/EndsWith Predicate and Cause Performance Hit

When using Linq to Entity (or Linq to SQL) with these predicates, Linq will generate ‘ESCAPE’ keyword in SQL statement which cause performance hit.

This code:

public IEnumerable GetUser(string filter)
{
    using (var db = new SomeEntities())
    {
        var result = db.User
            .Where(u => u.DisplayName.Contains(filter))
            .ToList();
    }
}

Will generate this sql statement:

SELECT [Extent1].[DisplayName] AS [DisplayName]
FROM   (SELECT [User].[DisplayName] AS [DisplayName]
        FROM   [dbo].[User] AS [User]) AS [Extent1]
WHERE  [Extent1].[DisplayName] LIKE '%garlan%' /* @p__linq__0 */ ESCAPE '~'

The `ESCAPE ‘~’` could potentially cause performance degradation.

Solution to this issue is to pass in constant into Contains predicate. It’s easier said than done.
If we have method like `GetUser` above which take ‘filter’ parameter, it’s not possible to convert to constant.
To overcome this, we have to create method that return predicate with constant.

This solution is proposed here.

Summary is to create extension class.

using System;
using System.Linq.Expressions;

namespace Blahblahblah
{
    public static class PredicateConstantCreator
    {
        public static Expression EmbedConstant(this Expression expression, TConstant constant)
        {
            var body = expression.Body.Replace(expression.Parameters[1], Expression.Constant(constant));

            return Expression.Lambda(body, expression.Parameters[0]);
        }

        private static Expression Replace(this Expression expression, Expression searchEx, Expression replaceEx)
        {
            return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
        }

        internal class ReplaceVisitor : ExpressionVisitor
        {
            private readonly Expression from;
            private readonly Expression to;

            public ReplaceVisitor(Expression from, Expression to)
            {
                this.from = from;
                this.to = to;
            }

            public override Expression Visit(Expression node)
            {
                return node == this.from ? this.to : base.Visit(node);
            }
        }
    }
}

And use it like this:

Expression predicate = (item, filterTerm) => item.DisplayName.Contains(filterTerm);
var result = User
    .Where(predicate.EmbedConstant(filter))
    .ToList();

Linq will generate sql statement like this:

SELECT [Extent1].[DisplayName] AS [DisplayName]
FROM   (SELECT [User].[DisplayName] AS [DisplayName]
        FROM   [dbo].[User] AS [User]) AS [Extent1]
WHERE  [Extent1].[DisplayName] LIKE '%garlan%' /* @p__linq__0 */

Alternative solution is to add function to generated XML file in EDMX. This solution is lay out here.

 
Leave a comment

Posted by on October 23, 2018 in General

 

Tags: , , , , ,

Karma: Only Run 1 Test

Useful hack to only run 1 test in Karma.

Instead of ‘it’, change test declaration to ‘fit’.
Example:

    fit('should create', () => {
        expect(component).toBeTruthy();
    });

This will force Karma to only run ‘should create’ test.

 
Leave a comment

Posted by on October 22, 2018 in General

 

Tags: , , , , , ,

How to Implement IExceptionLogger and IExceptionHandler in Web Api .Net

This works on Web Api 2+ and MVC 5+.

1. Create implementation of ExceptionHandler class. Note this class inherit from concrete class of ExceptionHandler, not the interface. Inherit from concrete class decrease effort to implement other methods.

using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.ExceptionHandling;

namespace BlahBlahBlah.ExceptionHandler
{
    public class GlobalExceptionHandler : System.Web.Http.ExceptionHandling.ExceptionHandler
    {
        public override Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
        {
            // Code to handle exception...

            return base.HandleAsync(context, cancellationToken);
        }
    }
}

2. Create implementation of ExceptionLogger class. Note this class inherit from concrete class of ExceptionLogger, not the interface. Inherit from concrete class decrease effort to implement other methods.

using System.Threading;
using System.Threading.Tasks;

namespace BlahBlahBlah.ExceptionHandler
{
    public class GlobalExceptionLogger : System.Web.Http.ExceptionHandling.ExceptionLogger
    {
        public override Task LogAsync(System.Web.Http.ExceptionHandling.ExceptionLoggerContext context, CancellationToken cancellationToken)
        {
            // Code to log exception...

            return base.LogAsync(context, cancellationToken);
        }
    }
}

3. Replace default Logger and Handler.

using System.Web.Http;
using System.Web.Http.ExceptionHandling;
using BlahBlahBlah.ExceptionHandler;

namespace BlahBlahBlah
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {            
            // Replace default exception handler and logger
            config.Services.Replace(typeof(IExceptionLogger), new GlobalExceptionLogger());
            config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

If you wonder difference between IExceptionLogger and IExceptionHandler, this is from Microsoft docs:

We provide two new user-replaceable services, IExceptionLogger and IExceptionHandler, to log and handle unhandled exceptions. The services are very similar, with two main differences:

1. We support registering multiple exception loggers but only a single exception handler.
2. Exception loggers always get called, even if we’re about to abort the connection. Exception handlers only get called when we’re still able to choose which response message to send.

Both services provide access to an exception context containing relevant information from the point where the exception was detected, particularly the HttpRequestMessage, the HttpRequestContext, the thrown exception and the exception source (details below).

 
Leave a comment

Posted by on October 12, 2018 in General

 

Tags: , , , , , ,

Angular 6 Sharing Service… or not…

Different ways to share Service instance in Angular 6.

Service instance shared across entire application.

  • Declare `providedIn: ‘root’` property of `@Injectable` decorator in the Service. Then inject service to component’s constructor as usual.
  • import { Injectable } from '@angular/core';
    
    @Injectable({
      providedIn: 'root'
    })
    export class Service1Service {
      constructor() {
      }
    }
    
  • Declare service in `providers` property of `@NgModule` decorator in highest module (Ie: app.module.ts). Then inject service to component’s constructor as usual.
  • app.module.ts

    @NgModule({
        declarations: [...],
        imports: [...]
        providers: [Service1Service]
    })
    

Service instance shared across module.
Declare service in `providers` property of `@NgModule` decorator in any module except the highest module (Ie: user.module.ts, order.module.ts, etc). Then inject service to component’s constructor as usual.

user.module.ts

@NgModule({
    declarations: [...],
    imports: [...]
    providers: [Service1Service]
})

Service instance in every single component (not shared).
Declare service in `providers` property of `@Component` decorator in any component. Then inject service to component’s constructor as usual.

component1.component.ts

import { Component } from '@angular/core';
import { Service1Service } from '../service1.service';

@Component({
  selector: 'app-component1',
  templateUrl: './component1.component.html',
  styleUrls: ['./component1.component.css'],
  providers: [Service1Service]
})
export class Component1Component {
  constructor(private service1: Service1Service) {
  }
}
 
Leave a comment

Posted by on September 25, 2018 in General

 

Tags: , , , ,

“The CodeDom provider type Microsoft.VisualC.CppCodeProvider could not be found” exception

This problem happened when you build project/solution in Visual Studio. Generally caused when you have compile-able files in your Visual Studio solutions but VS could not understand it.
In my case, I have infamous ‘node_modules’ folder.

To solve this issue, in Windows Explorer, I right click on it ‘node_modules’ folder and select ‘Properties’, check ‘Hidden’ under Attributes.

You can also exclude the folder. In Visual Studio Solution Explorer, right click on ‘node_modules’ and select ‘Exclude From Project’.

More reading.

 
Leave a comment

Posted by on September 12, 2018 in General

 

Tags: , , , , , , ,

Angular 6 Custom Elements’ Properties

If you are not familiar with Angular custom elements, read my previous post.

Here is tips on how to expose properties from your custom element so the user can do something like this:

<body>
  <fooComponent></fooComponent>

  <script>
    if (document.readyState === 'complete') {
      document.querySelector('fooComponent').value = 'i am value-able';
      document.querySelector('fooComponent').fooProp = 'i am foo prop';

      console.log(document.querySelector('fooComponent').value);
      console.log(document.querySelector('fooComponent').fooProp);
    }
  </script>
</body>

First, this is our custom component, same setup as my previous post.

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ]
  entryComponents: [
    AppComponent
  ]
})
export class AppModule {
  constructor(private injector: Injector) {
    let customComponent = createCustomElement(AppComponent, { injector });
    window.customElements.define('fooComponent', customComponent);
  }

  ngDoBootstrap() {
  }
}

And how to expose properties.

app.component.ts

import { Component, Input, SimpleChanges } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  // Element's properties to expose
  @Input() value: string;
  @Input() fooProp: string;

  // Track changes of the properties
  ngOnChanges(changes: SimpleChanges): void {
    console.log(changes.value.currentValue);
    console.log(changes.fooProp.currentValue);
  }
}

Note here, though we use Angular’s Input directive, it also allow user to modify property value, so it’s important to validate before using it.

That’s it. Simple.

 
Leave a comment

Posted by on September 12, 2018 in General

 

Tags: , , , ,

 
%d bloggers like this: