Technical Insights: Azure, .NET, Dynamics 365 & EV Charging Architecture

Author: fransiscuss Page 8 of 19

Trello – Collaboration TODO Web App

My manager recommended us to check this website in order to help us keep tracking of what need to be done

What I like is the simple UI and easy to use. It helps people to manage their projects and resources or even it helps you to organise your daily activities. It is free to use as well

http://trello.com

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

Code Snippet
  1. <configSections>
  2.     <section name=log4nettype=log4net.Config.Log4NetConfigurationSectionHandler, log4net />
  3.   </configSections>
  4.   <log4net>
  5.     <root>
  6.       <levelvalue=DEBUG />
  7.       <appender-ref ref=LogFileAppender />
  8.     </root>
  9.     <appender name=LogFileAppender type=log4net.Appender.RollingFileAppender >
  10.       <param name=Filevalue=C:\\log.txt />
  11.       <param name=AppendToFilevalue=true />
  12.       <rollingStyle value=Size />
  13.       <maxSizeRollBackups value=10 />
  14.       <maximumFileSize value=10MB />
  15.       <staticLogFileName value=true />
  16.       <layout type=log4net.Layout.PatternLayout>
  17.         <param name=ConversionPattern value=%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n />
  18.       </layout>
  19.     </appender>
  20.   </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

Code Snippet
  1. protected void Application_Start()
  2.         {
  3.             AreaRegistration.RegisterAllAreas();
  4.             RegisterGlobalFilters(GlobalFilters.Filters);
  5.             RegisterRoutes(RouteTable.Routes);
  6.             BundleTable.Bundles.RegisterTemplateBundles();
  7.             RegisterDependency();
  8.         }
  9.         #region “Dependency Injection”
  10.         private static Container Container;
  11.         public static T GetInstance<T>() where T : class
  12.         {
  13.             return Container.GetInstance<T>();
  14.         }
  15.         protected void RegisterDependency()
  16.         {
  17.             //Create a main containers
  18.             var container = new Container();
  19.             // 2. Configure the container (register)
  20.             container.RegisterPerWebRequest<IUnitOfWork>(() => new UnitOfWork(new PosDataContext()));
  21.             //Register logger
  22.             log4net.Config.XmlConfigurator.Configure();
  23.             container.Register<ILog>(() => log4net.LogManager.GetLogger(typeof(MvcApplication)));
  24.             container.Verify();
  25.             Container = container;
  26.         }
  27.         #endregion

calling the logger from my code (controller in this context)

Code Snippet
  1. public ActionResult Index()
  2.         {
  3.             ViewBag.Message = “Menu”;
  4.             MvcApplication.GetInstance<ILog>().Info(“Test Info”);
  5.             MvcApplication.GetInstance<ILog>().Error(“Test Error”);
  6.             MvcApplication.GetInstance<ILog>().Debug(“Test Debug”);
  7.             return View();
  8.         }

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

Code Snippet
  1. 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)

Code Snippet
  1. if (MvcApplication.GetInstance<ILog>().IsDebugEnabled)
  2.             {
  3.                 MvcApplication.GetInstance<ILog>().Debug(“My Function Output:” + MyFunctionOutput());
  4.             }

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

Code Snippet
  1. [AllowAnonymous]
  2.         public ActionResult JsonRegister(string username, string password, string confirmpassword,
  3.                                             string email, string confirmemail)
  4.         {
  5.             MemberModel.RegistrationModel model = new MemberModel.RegistrationModel() {
  6.                                                                                         UserName = username,
  7.                                                                                         Password = password,
  8.                                                                                         ConfirmPassword = confirmpassword,
  9.                                                                                         Email = email,
  10.                                                                                         ConfirmEmail = confirmemail };

Javascript

Code Snippet
  1. $.getJSON(@Url.Action(“JsonRegister”), { UserName: $(“#UserName”).val(),
  2.                                                     Password: $(“#Password”).val(),
  3.                                                     ConfirmPassword: $(“#ConfirmPassword”).val(),
  4.                                                     Email: $(“#Email”).val(),
  5.                                                     ConfirmEmail: $(“#ConfirmEmail”).val()
  6.                                                 }, function (RegisterResult) {
  7.                                                         if (RegisterResult.success) {
  8.                                                             $(‘#RegistrationFields’).hide();
  9.                                                             $(‘#ErrorMessage’).text();
  10.                                                             $(‘#RegistrationMessage’).css(‘display’, );
  11.                                                         }
  12.                                                         else {
  13.                                                             $(‘#ErrorMessage’).css(‘display’, ).text(RegisterResult.errors);
  14.                                                         }
  15.         });

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

Code Snippet
  1. [AllowAnonymous]
  2.         public ActionResult JsonRegister(MemberModel.RegistrationModel model)
  3.         {
  4.             string error = string.Empty;
  5.             if (ModelState.IsValid)

Javascript

Code Snippet
  1. var data = { UserName: $(“#UserName”).val(),
  2.             Password: $(“#Password”).val(),
  3.             ConfirmPassword: $(“#ConfirmPassword”).val(),
  4.             Email: $(“#Email”).val(),
  5.             ConfirmEmail: $(“#ConfirmEmail”).val()
  6.         };
  7.         $.getJSON(@Url.Action(“JsonRegister”), data, function (RegisterResult) {
  8.             if (RegisterResult.success) {
  9.                 $(‘#RegistrationFields’).hide();
  10.                 $(‘#ErrorMessage’).text();
  11.                 $(‘#RegistrationMessage’).css(‘display’, );
  12.             }
  13.             else {
  14.                 $(‘#ErrorMessage’).css(‘display’, ).text(RegisterResult.errors);
  15.             }
  16.         });

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

Code Snippet
  1. public ActionResult JsonRegister(MemberModel.RegistrationModel model)
  2.         {
  3.             string error = string.Empty;
  4.             if (!ModelState.IsValid)
  5.             {
  6.                 IEnumerable<System.Web.Mvc.ModelError> modelerrors = ModelState.SelectMany(x => x.Value.Errors);
  7.                 foreach (var modelerror in modelerrors)
  8.                 {
  9.                     error += modelerror.ErrorMessage + “\n”;
  10.                 }
  11.             }
  12.             return Json(new { success = false, errors = error }, JsonRequestBehavior.AllowGet);
  13.         }

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

http://www.sliderocket.com

ps: some guy is using this web application for their resume! and it’s impressive!

http://www.sliderocket.com/blog/2012/05/creative-resume-idea/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+SliderocketMissionControl+%28SlideRocket+Mission+Control%29

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

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using SimpleInjector;
  6. using System.Diagnostics;
  7. using System.Linq.Expressions;
  8. ///<summary>
  9. /// Extension methods for registering types on a per web request basis.
  10. ///</summary>
  11. public static partial class SimpleInjectorPerWebRequestExtensions
  12. {
  13.     [DebuggerStepThrough]
  14.     public static void RegisterPerWebRequest<TService, TImplementation>(
  15.         this Container container)
  16.         where TService : class
  17.         where TImplementation : class, TService
  18.     {
  19.         Func<TService> instanceCreator =
  20.             () => container.GetInstance<TImplementation>();
  21.         container.RegisterPerWebRequest<TService>(instanceCreator);
  22.     }
  23.     [DebuggerStepThrough]
  24.     public static void RegisterPerWebRequest<TService>(
  25.         this Container container,
  26.         Func<TService> instanceCreator) where TService : class
  27.     {
  28.         var creator =
  29.             new PerWebRequestInstanceCreator<TService>(instanceCreator);
  30.         container.Register<TService>(creator.GetInstance);
  31.     }
  32.     [DebuggerStepThrough]
  33.     public static void RegisterPerWebRequest<TConcrete>(this Container container)
  34.         where TConcrete : class
  35.     {
  36.         container.Register<TConcrete>();
  37.         container.ExpressionBuilt += (sender, e) =>
  38.         {
  39.             if (e.RegisteredServiceType == typeof(TConcrete))
  40.             {
  41.                 var transientInstanceCreator = Expression.Lambda<Func<TConcrete>>(
  42.                     e.Expression, new ParameterExpression[0]).Compile();
  43.                 var creator = new PerWebRequestInstanceCreator<TConcrete>(
  44.                     transientInstanceCreator);
  45.                 e.Expression = Expression.Call(Expression.Constant(creator),
  46.                     creator.GetType().GetMethod(“GetInstance”));
  47.             }
  48.         };
  49.     }
  50.     [DebuggerStepThrough]
  51.     public static void DisposeInstance<TService>() where TService : class
  52.     {
  53.         object key = typeof(PerWebRequestInstanceCreator<TService>);
  54.         var instance = HttpContext.Current.Items[key] as IDisposable;
  55.         if (instance != null)
  56.         {
  57.             instance.Dispose();
  58.         }
  59.     }
  60.     private sealed class PerWebRequestInstanceCreator<T> where T : class
  61.     {
  62.         private readonly Func<T> instanceCreator;
  63.         internal PerWebRequestInstanceCreator(Func<T> instanceCreator)
  64.         {
  65.             this.instanceCreator = instanceCreator;
  66.         }
  67.         [DebuggerStepThrough]
  68.         public T GetInstance()
  69.         {
  70.             var context = HttpContext.Current;
  71.             if (context == null)
  72.             {
  73.                 // No HttpContext: Let’s create a transient object.
  74.                 return this.instanceCreator();
  75.             }
  76.             object key = this.GetType();
  77.             T instance = (T)context.Items[key];
  78.             if (instance == null)
  79.             {
  80.                 context.Items[key] = instance = this.instanceCreator();
  81.             }
  82.             return instance;
  83.         }
  84.     }
  85. }

2. Modify Global.asax – The class name will be MvcApplication in MVC Project

Code Snippet
  1. #region “Dependency Injection”
  2.         private static Container Container;
  3.         public static T GetInstance<T>() where T : class
  4.         {
  5.             return Container.GetInstance<T>();
  6.         }
  7.         protected void RegisterDependency()
  8.         {
  9.             //Create a main containers
  10.             var container = new Container();
  11.             // 2. Configure the container (register)
  12.             container.RegisterPerWebRequest<IUnitOfWork>(() => new UnitOfWork(new PosDataContext()));
  13.             container.Register<ITableRepository, TableRepository>();
  14.             container.Verify();
  15.             Container = container;
  16.         }
  17.         #endregion
  18.         protected void Application_Start()
  19.         {
  20.             AreaRegistration.RegisterAllAreas();
  21.             RegisterGlobalFilters(GlobalFilters.Filters);
  22.             RegisterRoutes(RouteTable.Routes);
  23.             BundleTable.Bundles.RegisterTemplateBundles();
  24.             RegisterDependency();
  25.         }
  26.         protected void Application_EndRequest(object src, EventArgs e)
  27.         {
  28.             ServiceStack.MiniProfiler.Profiler.Stop();
  29.             SimpleInjectorPerWebRequestExtensions.DisposeInstance<IUnitOfWork>();
  30.         }

3. Consume it from the controller – Call the container in the Global.asax to resolve the object (GetInstance function)

Code Snippet
  1. public ActionResult Index()
  2.         {
  3.             ViewBag.Title = “Tables”;
  4.             return View(MvcApplication.GetInstance<IUnitOfWork>().TableRepository.Get(e => e.Active));
  5.         }

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

http://www.iocbattle.com/

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

How to Debug WCF Service Issue?

1. Change the app.config/web.config of your application that calls the WCF service by adding System.diagnostics detail as below

Code Snippet
  1. <system.diagnostics>
  2.     <sources>
  3.       <source name=System.ServiceModel switchValue=Verbose,ActivityTracing propagateActivity=true>
  4.         <listeners>
  5.           <add type=System.Diagnostics.DefaultTraceListenername=Default>
  6.             <filter type=“” />
  7.           </add>
  8.           <add name=ServiceModelTraceListener>
  9.             <filter type=“” />
  10.           </add>
  11.         </listeners>
  12.       </source>
  13.       <source name=System.ServiceModel.MessageLogging switchValue=Verbose,ActivityTracing>
  14.         <listeners>
  15.           <add type=System.Diagnostics.DefaultTraceListenername=Default>
  16.             <filter type=“” />
  17.           </add>
  18.           <add name=ServiceModelMessageLoggingListener>
  19.             <filter type=“” />
  20.           </add>
  21.         </listeners>
  22.       </source>
  23.     </sources>
  24.     <sharedListeners>
  25.       <add initializeData=MyWCFTraceLog.svclog
  26.       type=System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
  27.       name=ServiceModelTraceListenertraceOutputOptions=Timestamp>
  28.         <filter type=“” />
  29.       </add>
  30.       <add initializeData=MyWCFTraceLog.svclog
  31.           type=System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
  32.           name=ServiceModelMessageLoggingListenertraceOutputOptions=Timestamp>
  33.         <filter type=“” />
  34.       </add>
  35.     </sharedListeners>
  36.     <trace autoflush=true />
  37.   </system.diagnostics>

2. Run your application as usual until it throws the error or until the stage where you can reproduce your issue, once you are done, quit your application or take out the diagnostics section from the config file straight away so your log will not be growing too quickly/massively

3. The log file will be called as MyWCFTraceLog.svclog (as we define in the config file) and it will be located on the same folder as the executable – normally it is in the bin folder

4. How to open svclog file? Go to your program files (x86) or program files/Microsoft SDKs/Windows/v7.0A/Bin/SvcTraceViewer.exe

5. SVCTraceViewer will display you the story line of your WCF and it will help you to pinpoint the underlying issue

Delayed Script/Waiting in Javascript

I was struggling in finding out of how to make a simple delegate like in AJAX request through javascript. It takes me a few days to figure this out

Basically the problems are:

-I need to execute a piece code of javascript after getting the ticket from web service function

-The webservice function might not be responding to the first request because it waits for the state of the other external component

-The webservice will give the response when the external component is ready

-The client does not know when the external component is ready, neither the web service. But it wil be ready within 1-5 minutes which again depending external component

Possible Solution:

-Using the setTimeOut(function(){acquireTicket();}, 300000) will cause the application to wait for 5 mins before calling the web service , this approach will slowing down the user experience and waste of time because the external component can be ready earlier than 5 mins

-Using the while loop is not good because it makes the browser freezing while waiting and it will wasting the processing power because of the looping

Recommended Solution:

-Recall the function by itself using setTimeout Function using parameter to indicate whether it should go out of the loop or not

-The web service will be checked for every 2 seconds to check the response from the external component. Once the external component is ready then it will move on to execute the next line of code

Page 8 of 19

Powered by WordPress & Theme by Anders Norén