Log4Net – Logging for .NET
Before I was thinking of rewriting my own logging for my application but after having a careful thought, I decided just to get one from NuGet package instead of reinventing the wheel. I heard a lot about Log4Net and decided to try that out. It’s really simple to get this logging up and running on your application
This is what you need to do:
1. install Log4Net from NuGet
2. Modify your web.config to add a new section and new configuration – In this case, I decided to use FileLogger. but you can have different type logger if you want (e.g event log, console, etc) or you can even build your own one that implemented ILog, this configuration allow you to create a new log file when the log file already reached the limit
- <configSections>
- <section name=“log4net” type=“log4net.Config.Log4NetConfigurationSectionHandler, log4net“ />
- </configSections>
- <log4net>
- <root>
- <levelvalue=“DEBUG“ />
- <appender-ref ref=“LogFileAppender“ />
- </root>
- <appender name=“LogFileAppender“ type=“log4net.Appender.RollingFileAppender“ >
- <param name=“File” value=“C:\\log.txt“ />
- <param name=“AppendToFile” value=“true“ />
- <rollingStyle value=“Size“ />
- <maxSizeRollBackups value=“10“ />
- <maximumFileSize value=“10MB“ />
- <staticLogFileName value=“true“ />
- <layout type=“log4net.Layout.PatternLayout“>
- <param name=“ConversionPattern“ value=“%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n“ />
- </layout>
- </appender>
- </log4net>
3. Code implementation – in this case I decided to register it in my global container and retrieve it later. You need to call log4net.Config.XmlConfigurator.Configure in order for Log4Net to get the settings from web.config – This is very important otherwise you will find that there is no log being generated
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- RegisterGlobalFilters(GlobalFilters.Filters);
- RegisterRoutes(RouteTable.Routes);
- BundleTable.Bundles.RegisterTemplateBundles();
- RegisterDependency();
- }
- #region “Dependency Injection”
- private static Container Container;
- public static T GetInstance<T>() where T : class
- {
- return Container.GetInstance<T>();
- }
- protected void RegisterDependency()
- {
- //Create a main containers
- var container = new Container();
- // 2. Configure the container (register)
- container.RegisterPerWebRequest<IUnitOfWork>(() => new UnitOfWork(new PosDataContext()));
- //Register logger
- log4net.Config.XmlConfigurator.Configure();
- container.Register<ILog>(() => log4net.LogManager.GetLogger(typeof(MvcApplication)));
- container.Verify();
- Container = container;
- }
- #endregion
calling the logger from my code (controller in this context)
- public ActionResult Index()
- {
- ViewBag.Message = “Menu”;
- MvcApplication.GetInstance<ILog>().Info(“Test Info”);
- MvcApplication.GetInstance<ILog>().Error(“Test Error”);
- MvcApplication.GetInstance<ILog>().Debug(“Test Debug”);
- return View();
- }
PS: if you want to implement your own logger, then I’d recommend you to have your logger to implement ILog interface and change it through web.config but don’t wrap/call Log4Net inside your custom logger because you don’t want to limit the rich functionality of Log4Net with your custom logger
Another tips, is when you started to add logging in your application then there should be some performance overhead eventhough it is minor. In the example below MyFunctionOutput function will still be called eventhough you disabled the logging on the config, in order to make sure the debugging code only executed
- MvcApplication.GetInstance<ILog>().Debug(“My Function Output:” + MyFunctionOutput());
When you want to have the debug/logging omitting the log whenever the logging is enabled then you can wrap around the logging with this property (there are another properties IsErrorEnabled, IsInfoEnabled, etc)
- if (MvcApplication.GetInstance<ILog>().IsDebugEnabled)
- {
- MvcApplication.GetInstance<ILog>().Debug(“My Function Output:” + MyFunctionOutput());
- }
Pass Model from Javascript to MVC Controller
Initially, I always pass individual object properties through JSON and form the model in the controller as I wasn’t sure how to pass/form a model from Javascript to controller
Controller
- [AllowAnonymous]
- public ActionResult JsonRegister(string username, string password, string confirmpassword,
- string email, string confirmemail)
- {
- MemberModel.RegistrationModel model = new MemberModel.RegistrationModel() {
- UserName = username,
- Password = password,
- ConfirmPassword = confirmpassword,
- Email = email,
- ConfirmEmail = confirmemail };
Javascript
- $.getJSON(‘@Url.Action(“JsonRegister”)‘, { UserName: $(“#UserName”).val(),
- Password: $(“#Password”).val(),
- ConfirmPassword: $(“#ConfirmPassword”).val(),
- Email: $(“#Email”).val(),
- ConfirmEmail: $(“#ConfirmEmail”).val()
- }, function (RegisterResult) {
- if (RegisterResult.success) {
- $(‘#RegistrationFields’).hide();
- $(‘#ErrorMessage’).text(”);
- $(‘#RegistrationMessage’).css(‘display’, ”);
- }
- else {
- $(‘#ErrorMessage’).css(‘display’, ”).text(RegisterResult.errors);
- }
- });
the code above is working just fine but I still feel that there is room for improvement. Below is the code that shows how you can still have your controller accepting the model instead of expanding the properties in the model as the parameters to the controller. The solution is just to have the model being assigned to a variable (in this context called as data) before passing it to the JSON, my previous code was forming the actual object in the JSON code
Controller
- [AllowAnonymous]
- public ActionResult JsonRegister(MemberModel.RegistrationModel model)
- {
- string error = string.Empty;
- if (ModelState.IsValid)
Javascript
- var data = { UserName: $(“#UserName”).val(),
- Password: $(“#Password”).val(),
- ConfirmPassword: $(“#ConfirmPassword”).val(),
- Email: $(“#Email”).val(),
- ConfirmEmail: $(“#ConfirmEmail”).val()
- };
- $.getJSON(‘@Url.Action(“JsonRegister”)‘, data, function (RegisterResult) {
- if (RegisterResult.success) {
- $(‘#RegistrationFields’).hide();
- $(‘#ErrorMessage’).text(”);
- $(‘#RegistrationMessage’).css(‘display’, ”);
- }
- else {
- $(‘#ErrorMessage’).css(‘display’, ”).text(RegisterResult.errors);
- }
- });
ModelState Errors in MVC through JSON
Normally, when you used HttpPost/Form submission to post the view through the controller then you can have the model validation applied automatically through @Html.ValidationSummary()
But how do you get the ModelState errors through Json? You can still use LINQ to get the model errors from the ModelState and pass it through JSON
- public ActionResult JsonRegister(MemberModel.RegistrationModel model)
- {
- string error = string.Empty;
- if (!ModelState.IsValid)
- {
- IEnumerable<System.Web.Mvc.ModelError> modelerrors = ModelState.SelectMany(x => x.Value.Errors);
- foreach (var modelerror in modelerrors)
- {
- error += modelerror.ErrorMessage + “\n”;
- }
- }
- return Json(new { success = false, errors = error }, JsonRequestBehavior.AllowGet);
- }
SlideRocket – Cloud
This is the cloud version of Microsoft Power Point. It is created by the company that I’m working for at the moment. I’m blogging this not because I’m working for them but I’m blogging this based on my personal opinion
It is a powerful web application and It really works as it allows you to use Slide Rocket to share and collaborate your presentation slides with everyone and you don’t need to carry your power point slides file or your laptop. It supports mobile device as well such as an iPad. You just need a connection to the internet
For the standard functionality (Create a presentation slides), it is FREE for life but when you want to use versioning for your presentation, or when you want to have more security control over your presentation, or even to analyse who has accessed your slide and when was it then you need to have monthly subscription. Check it out guys
ps: some guy is using this web application for their resume! and it’s impressive!
Dependency Injection using Simple Injector Tutorial
This is a simple tutorial in how to use Dependency Injection using SimpleInjector (You can get this package from NuGet)
In this case, I use SimpleInjector to manage my Data Context – I want my Data Context to be per request (Unit of Work per request). The concept of this dependency Injection is to have a global container where you can resolve your object from
1. Create an extension method to the Simple Injector
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using SimpleInjector;
- using System.Diagnostics;
- using System.Linq.Expressions;
- ///<summary>
- /// Extension methods for registering types on a per web request basis.
- ///</summary>
- public static partial class SimpleInjectorPerWebRequestExtensions
- {
- [DebuggerStepThrough]
- public static void RegisterPerWebRequest<TService, TImplementation>(
- this Container container)
- where TService : class
- where TImplementation : class, TService
- {
- Func<TService> instanceCreator =
- () => container.GetInstance<TImplementation>();
- container.RegisterPerWebRequest<TService>(instanceCreator);
- }
- [DebuggerStepThrough]
- public static void RegisterPerWebRequest<TService>(
- this Container container,
- Func<TService> instanceCreator) where TService : class
- {
- var creator =
- new PerWebRequestInstanceCreator<TService>(instanceCreator);
- container.Register<TService>(creator.GetInstance);
- }
- [DebuggerStepThrough]
- public static void RegisterPerWebRequest<TConcrete>(this Container container)
- where TConcrete : class
- {
- container.Register<TConcrete>();
- container.ExpressionBuilt += (sender, e) =>
- {
- if (e.RegisteredServiceType == typeof(TConcrete))
- {
- var transientInstanceCreator = Expression.Lambda<Func<TConcrete>>(
- e.Expression, new ParameterExpression[0]).Compile();
- var creator = new PerWebRequestInstanceCreator<TConcrete>(
- transientInstanceCreator);
- e.Expression = Expression.Call(Expression.Constant(creator),
- creator.GetType().GetMethod(“GetInstance”));
- }
- };
- }
- [DebuggerStepThrough]
- public static void DisposeInstance<TService>() where TService : class
- {
- object key = typeof(PerWebRequestInstanceCreator<TService>);
- var instance = HttpContext.Current.Items[key] as IDisposable;
- if (instance != null)
- {
- instance.Dispose();
- }
- }
- private sealed class PerWebRequestInstanceCreator<T> where T : class
- {
- private readonly Func<T> instanceCreator;
- internal PerWebRequestInstanceCreator(Func<T> instanceCreator)
- {
- this.instanceCreator = instanceCreator;
- }
- [DebuggerStepThrough]
- public T GetInstance()
- {
- var context = HttpContext.Current;
- if (context == null)
- {
- // No HttpContext: Let’s create a transient object.
- return this.instanceCreator();
- }
- object key = this.GetType();
- T instance = (T)context.Items[key];
- if (instance == null)
- {
- context.Items[key] = instance = this.instanceCreator();
- }
- return instance;
- }
- }
- }
2. Modify Global.asax – The class name will be MvcApplication in MVC Project
- #region “Dependency Injection”
- private static Container Container;
- public static T GetInstance<T>() where T : class
- {
- return Container.GetInstance<T>();
- }
- protected void RegisterDependency()
- {
- //Create a main containers
- var container = new Container();
- // 2. Configure the container (register)
- container.RegisterPerWebRequest<IUnitOfWork>(() => new UnitOfWork(new PosDataContext()));
- container.Register<ITableRepository, TableRepository>();
- container.Verify();
- Container = container;
- }
- #endregion
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- RegisterGlobalFilters(GlobalFilters.Filters);
- RegisterRoutes(RouteTable.Routes);
- BundleTable.Bundles.RegisterTemplateBundles();
- RegisterDependency();
- }
- protected void Application_EndRequest(object src, EventArgs e)
- {
- ServiceStack.MiniProfiler.Profiler.Stop();
- SimpleInjectorPerWebRequestExtensions.DisposeInstance<IUnitOfWork>();
- }
3. Consume it from the controller – Call the container in the Global.asax to resolve the object (GetInstance function)
- public ActionResult Index()
- {
- ViewBag.Title = “Tables”;
- return View(MvcApplication.GetInstance<IUnitOfWork>().TableRepository.Get(e => e.Active));
- }
IoC Container Benchmarks
I found this benchmark for different IoC in .NET. Personally I’ve been using Unity, Ninject and SimpleInjector. I like SimpleInjector because it is very simple and surprisingly it is quite fast compared with the rest. Performance is just one of the aspect of IoC but it doesn’t always mean everything
http://www.palmmedia.de/Blog/2011/8/30/ioc-container-benchmark-performance-comparison
Debugging Knockout
I’ve been learning Knockout recently and I found that sometimes it is hard to find out how your View Model is being formed especially when you create the view from Model in MVC
To inspect your view model, you can use firebug console and run below command, this will give you a full navigated View Model and allow you to drill down
console.group(“Dumping view model”);
console.dir(ko.toJS(new JobResultViewModel()));
console.groupEnd();
alternatively you can also put this code in your template
<div data-bind=”text: ko.toJSON($data)”></div>
Feel free to let me know if you have any other way to debug