RSS

Tag Archives: asp.net mvc

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).

Advertisements
 
Leave a comment

Posted by on October 12, 2018 in General

 

Tags: , , , , , ,

Application Insights Intrumentation Key in Web.config

When using Azure Application Insights in ASP.Net application, by default, Visual Studio insert IntrumentationKey in ApplicationInsights.config.

To allow multiple environments tracking, move IntrumentationKey to Web.config by following this steps:

  1. Remove IntrumentationKey from ApplicationInsights.config. If you have MVC application, don’t forget to modify ApplicationInsights’ script (usually in View\Shared\_Layout.cshtml), replace:

    {instrumentationKey:"your instrumentation key"}
    

    with:

    {instrumentationKey:"@Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey"}
    
  2. Add new app settings for IntrumentationKey in Web.config under <appSettings>

    <add key="InstrumentationKey" value="your instrumentation key" />
    
  3. In Global.asax.cs, Application_Start() method, add:

    Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey = System.Web.Configuration.WebConfigurationManager.AppSettings["InstrumentationKey"];
    

That’s it for the configuration changes. Everything else is the same including tracking custom event or page view.
With this configuration, you will be able to define InstrumentationKey in Release management for each environments.

 
Leave a comment

Posted by on May 18, 2018 in General

 

Tags: , , , , , ,

Adding ASP.Net Identity (with OWIN) to Existing MVC 5 Project

The simple way is start empty MVC project with authentication and pick and choose ASP.Net Identity part you want to implement.

Here is the summary:

  • Install dependencies. See https://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity, scroll down to “Components of ASP.Net Identity”
    • Entity Framework
    • OWIN
    • Microsoft.AspNet.Identity.Core
    • Microsoft.AspNet.Identity.EntityFramework
    • Microsoft.AspNet.Identity.Owin
    • Microsoft.Owin
    • Microsoft.Owin.Host.SystemWeb
    • Microsoft.Owin.Security
    • Microsoft.Owin.Security.Cookies
    • Microsoft.Owin.Security.OAuth
    • Microsoft.Owin.Security.Google (if you want allow external login with Google)
    • Microsoft.Owin.Security.Facebook (if you want allow external login with Facebook)
    • Microsoft.Owin.Security.Twitter (if you want allow external login with Twitter)
    • Netwonsoft.Json
  • In Web.config
    • Under
      <system.web>

      Add

      <authentication mode="None" />

      This is to remove IIS authentication, because we are going to use OWIN

    • Add all OWIN dependencies
  • Add Startup.cs. This is a startup class run by OWIN
    • Don’t forget its dependency, Startup.Auth.cs in App_Start folder
  • Add all classes in IdentityConfig.cs
    • There are 4 classes, EmailService, SmsService, ApplicationUserManager, ApplicationSignInManager. I’d like to separate them into different files
  • Add all classes in IdentityModels.cs
    • There are 2 classes, ApplicationUser, ApplicationDbContext. I’d like to separate them into different files

Those are the basic setup needed for ASP.Net Identity. The rest of the setup is front-end side, AccountController and ManageController, which has its own view models and CSHTML.

 
Leave a comment

Posted by on December 27, 2016 in General

 

Tags: , , ,

JavaScript Bundle Doesn’t Work on ASP.Net MVC 5

Developers often make this very common mistake. You start an ASP.Net MVC app, add few JavaScript files and libraries, run. Everything works fine but the JavaScript.

ASP.Net MVC Bundling

public static void RegisterBundles(BundleCollection bundles)
{
    bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                "~/Scripts/jquery-1.*"));

    bundles.Add(new ScriptBundle("~/bundles/startstop").Include(
                "~/Scripts/startstop*"));
}

ASP.Net MVC bundle has default ignore list and one of ignore list is ‘*.min.js’ files. Yes, any minified JavaScript file.

You can add the following code RegisterBundles to clear the ignore list before adding anything to the bundle.

bundles.IgnoreList.Clear();

Once you clear the list, you are also able to build your own ignore list.

bundles.IgnoreList.Ignore("");
 
Leave a comment

Posted by on June 12, 2015 in General

 

Tags: , ,

Resource Files In ASP.Net MVC

Scott Allen has a great post explaining how resource files work in ASP.Net MVC project using Visual Studio. Technically speaking, this also applies to ASP.Net Web Form.

Basically, there are these problems:

  • Placing resource files in App_GlobalResources folder will break unit tests.
  • Intellisense has trouble recognizing syntax in the Views.
  • App_LocalResources seems to have similar behavior.

The solution is ostensibly simple. Just put resource files in a separate folder, name it anything you want. This will:

  • Embed the resource files in library when the project is compiled.
  • The generated class is internal by default. This is can be changed if you need to share the class publicly.

To change generated class to public, change ‘Custom Tool’ property of the resource file to ‘PublicResXFileCodeGenerator’ instead of ‘ResXCodeFileGenerator’.

 
Leave a comment

Posted by on June 2, 2015 in General

 

Tags: , , , ,

Claims-Based Authorization in ASP.Net MVC and Web Api

Normally, I would re-write a blog post in hope to provide better explanation and concise the article, but since this is from Dominick Baier, I think he does it the best.

So, here’s it, how to apply claims based authorization in ASP.Net MVC and Web Api:

http://leastprivilege.com/2012/10/26/using-claims-based-authorization-in-mvc-and-web-api/

 
Leave a comment

Posted by on May 28, 2015 in General

 

Tags: , , , , ,

Unit Testing WIF’s ClaimsPrincipalPermission.CheckAccess

WIF 4.5 has ClaimsPrincipalPermission.CheckAccess method, very useful to check user’s authorization. You can use this as method call or attribute.

// Imperative method call
using System.IdentityModel.Services;
public ActionResult Index()
{
    ClaimsPrincipalPermission.CheckAccess("foo", "bar");

    return View();
}

// Attribute
[ClaimsPrincipalPermission(SecurityAction.Demand, Operation="foo", Resource="bar")]
public ActionResult ViewFoobar()
{
    return View();
}

Either way, how do we unit test this? My approach is to first abstract out ClaimsPrincipalPermission and create a new wrapper class that will be injected to the dependent class.

Abstract Out

using System.IdentityModel.Services;

public class ClaimsPrincipalWrapper : IClaimsPrincipalWrapper
{
    public void CheckAccess(string resource, string action)
    {
        ClaimsPrincipalPermission.CheckAccess(resource, action);
    }
}

Dependency Injection

using System.IdentityModel.Services;

public class HomeController : Controller
{
    private readonly IClaimsPrincipalWrapper _ClaimsPrincipalWrapper;

    public HomeController(IClaimsPrincipalWrapper claimsPrincipalWrapper)
    {
        _ClaimsPrincipalWrapper = claimsPrincipalWrapper;
    }

    public ActionResult Index()
    {
        _ClaimsPrincipalWrapper.CheckAccess("foo", "bar");

        return View();
    }
}

Unit Test

[TestMethod]
public void TestIndex()
{
    // Arrange
    var _claimsPrincipal = new Mock<IClaimsPrincipalWrapper>();
    _claimsPrincipal.Setup(m => m.CheckAccess(It.IsAny<string>, It.IsAny<string>));
    var _controller = new HomeController(_claimsPrincipalMock.Object);

    // Act
    var _result = _controller.Index() as ViewResult;

    // Assert
    Assert.IsTrue(_result.View != null);
}
 
Leave a comment

Posted by on May 4, 2015 in General

 

Tags: , , , , , , ,

 
%d bloggers like this: