Replace switch statement with strategy pattern

using NLog;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http.Filters;
using TaxMs.DTOs;
using TaxMs.Infrastructure.CustomExceptions;
using TaxMs.Infrastructure.Extensions;

namespace TaxMs.ApiNet.Filters
{
    public class AlertServiceFilter : ExceptionFilterAttribute
    {
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();

        public HttpStatusCode GetStatusCodeFromException(Exception exc)
        {
            if (exc is ArgumentException || exc is FileNotFoundException)
                return HttpStatusCode.BadRequest;
            if (exc is InvalidOperationException || exc is NotFoundException)
                return HttpStatusCode.NotFound;
            if (exc is FormatException)
                return HttpStatusCode.ExpectationFailed;
            return HttpStatusCode.InternalServerError;
        }

        private List GetReasons(Exception exc)
        {
            var outList = new List();
            if (exc is ArgumentException)
            {
                var currExc = exc as ArgumentException;
                foreach (DictionaryEntry item in currExc.Data)
                    outList.Add(item.Value.ToString());
            }
            else
                outList.Add(exc.GetInnerMostException().Message);

            return outList;
        }

        public override void OnException(HttpActionExecutedContext cont)
        {
            //cont.Response = new HttpResponseMessage(GetStatusCodeFromException(cont.Exception));
            var a = new ExceptionStrategy();
            cont.Response = new HttpResponseMessage(a.GetStatusCode(cont.Exception.GetType()));


            cont.Response.Content = new ObjectContent(new ErrorInfo
            {
                Date = DateTime.Now,
                Status = cont.Response.StatusCode.ToInt(),
                Reasons = GetReasons(cont.Exception),
                Message = cont.Exception.Message
            }, new JsonMediaTypeFormatter());

            _logger.Error(cont.Exception, cont.Exception.Message);
        }
    }
    /////////////////////////////////////////////////////////////////////////////////////////////////
    #region Strategy Interface

    public interface IHttpResponseMessageStrategy
    {
        HttpStatusCode GetStatusCode();
    }

    #endregion

    #region Concrete Classes

    public class ExpectationFailedExceptionStrategy : IHttpResponseMessageStrategy
    {
        #region IHttpResponseMessageStrategy Members

        public HttpStatusCode GetStatusCode()
        {
            return HttpStatusCode.ExpectationFailed;
        }

        #endregion
    }

    public class NotFoundExceptionStrategy : IHttpResponseMessageStrategy
    {
        #region IHttpResponseMessageStrategy Members

        public HttpStatusCode GetStatusCode()
        {
            return HttpStatusCode.NotFound;
        }

        #endregion
    }

    public class BadRequestExceptionStrategy : IHttpResponseMessageStrategy
    {
        #region IHttpResponseMessageStrategy Members

        public HttpStatusCode GetStatusCode()
        {
            return HttpStatusCode.BadRequest;
        }

        #endregion
    }

    public class InternalServerErrorExceptionStrategy : IHttpResponseMessageStrategy
    {
        #region IHttpResponseMessageStrategy Members

        public HttpStatusCode GetStatusCode()
        {
            return HttpStatusCode.InternalServerError;
        }

        #endregion
    }
    #endregion

    #region Context

    public class ExceptionStrategy
    {
        #region Members

        private readonly Dictionary _strategies = new Dictionary();

        #endregion

        #region Ctor

        public ExceptionStrategy()
        {
            _strategies.Add(typeof(ArgumentException), new BadRequestExceptionStrategy());
            _strategies.Add(typeof(FileNotFoundException), new BadRequestExceptionStrategy());
            _strategies.Add(typeof(FormatException), new ExpectationFailedExceptionStrategy());
            _strategies.Add(typeof(NotFoundException), new NotFoundExceptionStrategy());
            _strategies.Add(typeof(InvalidOperationException), new NotFoundExceptionStrategy());
            _strategies.Add(typeof(Exception), new InternalServerErrorExceptionStrategy());
        }

        #endregion

        #region Methods

        public HttpStatusCode GetStatusCode(Type type)
        {
            return _strategies.ContainsKey(type) ? _strategies[type].GetStatusCode() : _strategies[typeof(Exception)].GetStatusCode();
        }

        #endregion
    }

    #endregion

}
using NUnit.Framework;
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using TaxMs.ApiNet.Filters;
using TaxMs.DTOs;
using TaxMs.Infrastructure.Extensions;

namespace TaxMs.ApiNet.Tests.Filters
{
    public class AlertFilterServiceTests
    {
        public AlertServiceFilter _sut;
        public AlertFilterServiceTests()
        {
            _sut = new AlertServiceFilter();
        }

        [Test]
        public void Should_Log_ArgumentException()
        {
            var argException = new ArgumentException("Model validation exception !");
            argException.Data.Add("Mail", "Mail is required");
            argException.Data.Add("Name", "Name is required");

            var fakeInput = new System.Web.Http.Filters.HttpActionExecutedContext
            {
                Exception = argException,
                ActionContext = new System.Web.Http.Controllers.HttpActionContext(),
                Response = new HttpResponseMessage()
            };

            _sut.OnException(fakeInput);

            var expectdInput = fakeInput.Response.Content as ObjectContent;
            var expectedBody = expectdInput.Value as ErrorInfo;

            Assert.IsNotNull(expectdInput);
            Assert.AreEqual(expectedBody.Status, HttpStatusCode.BadRequest.ToInt());
            Assert.AreEqual(expectedBody.Reasons.Count, 2);
            Assert.AreEqual(expectedBody.Reasons[0], "Mail is required");
            Assert.AreEqual(expectedBody.Reasons[1], "Name is required");
        }

        [Test]
        public void Should_Log_Generic_Exception()
        {
            var argException = new Exception("Generic Exception");

            var fakeInput = new System.Web.Http.Filters.HttpActionExecutedContext()
            {
                Exception = argException,
                ActionContext = new System.Web.Http.Controllers.HttpActionContext()
            };

            fakeInput.Response = new HttpResponseMessage();

            _sut.OnException(fakeInput);

            var expectdInput = fakeInput.Response.Content as ObjectContent;
            var expectedBody = expectdInput.Value as ErrorInfo;

            Assert.IsNotNull(expectdInput);
            Assert.AreEqual(expectedBody.Status, HttpStatusCode.InternalServerError.ToInt());
            Assert.AreEqual(expectedBody.Reasons.Count, 1);
            Assert.AreEqual(expectedBody.Reasons.First(),"Generic Exception");
        }
    }
}

How to ignore files (untrack) that have already been committed to GIT repository

If your GIT repository is tracking files that you want to ignore (i.e. you init your repo without .gitignore file) then these files still be present in you repository index also after adding them to the just created .gitignore file.

Step 1 – Create (or modify) .gitignore file

If you need an helping hand go to https://www.gitignore.io/ (for csharp https://www.gitignore.io/api/csharp.

Step 2 – Commit all your changes

After .gitignore file has been saved, commit all you files, including your new .gitignore file.
git commit -m “Fixed .gitignore issue.”

Step 3 – Remove everything from the repository

Clear your repo by using:
git rm -r –cached .
where
rm is the remove command
-r will allow recursive removal
–cached will only remove files from the index. Your files will still be there.
The . indicates that all files will be untracked. You can untrack a specific file with git rm –cached foo.txt (thanks @amadeann).
The rm command can be unforgiving. If you wish to try what it does beforehand, add the -n or –dry-run flag to test things out.

Step 4 – Re-Add everything

By using
git add .

Step 5 – Commit

By using
git commit -m “.gitignore fix”

Step 6 – Push

Push the changes to your remote to see the changes effective there as well.
git push

Useful .gitignore template:

Javascript: https://gist.github.com/andreasonny83/b24e38b7772a3ea362d8e8d238d5a7bc

IIS Routing

I was getting a 404 error when calling an apparently well configured Web API endpoint routing.
I solved this issue by editing the node in web.config file adding this line:

...

...