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");
}
}
}