How to use Docker, EngineX and Redis to load balanace aspnet core

Load-balancing is one of those topics in system architecture that has not been easy ever since the scaling the application became a concern for solution architectures. I have always wanted to implemented a load balanced aspnet application in project that I was experiencing, either as developer or team leader.

I never give up about learning the topic and recently I read some good articles. After I could run the suggested solutions, I though be me it is not a bad idea to compile those article into a vide tutorial. There you go :

Load-balance aspcore applications using Docker, Redis and Nginx

How to create a regular backup job for SQL Server Express

Having a regular backup of your database is vital. In SQL Server, there is a feature called “Agent services” that help you create a regular job to clean up the database, do some operations periodically or backup your database. But if you use SQL express, this feature is not available there. So how can you create a backup which runs in an interval during the day?

First, you need a backup script. I found one on the internet (sorry I forgot the source) and changed it a little bit.  Here is the script :

DECLARE @path VARCHAR(500)
DECLARE @name VARCHAR(500)
DECLARE @pathwithname VARCHAR(500)
DECLARE @time DATETIME
DECLARE @year VARCHAR(4)
DECLARE @month VARCHAR(2)
DECLARE @day VARCHAR(2)
DECLARE @hour VARCHAR(2)
DECLARE @minute VARCHAR(2)
DECLARE @second VARCHAR(2)

-- 1. Getting the time values

SELECT @time   = GETDATE()
SELECT @year   = (SELECT CONVERT(VARCHAR(4), DATEPART(yy, @time)))
SELECT @month  = (SELECT CONVERT(VARCHAR(2), FORMAT(DATEPART(mm,@time),'00')))
SELECT @day    = (SELECT CONVERT(VARCHAR(2), FORMAT(DATEPART(dd,@time),'00')))
SELECT @hour   = (SELECT CONVERT(VARCHAR(2), FORMAT(DATEPART(hh,@time),'00')))
SELECT @minute = (SELECT CONVERT(VARCHAR(2), FORMAT(DATEPART(mi,@time),'00')))
SELECT @second = (SELECT CONVERT(VARCHAR(2), FORMAT(DATEPART(ss,@time),'00')))

-- 2. Defining the filename format

SELECT @name ='Backup' + '_' + @year + @month + @day + @hour + @minute + @second

SET @pathwithname = @name + '.bak'

-- 3. Run the Back up script 

BACKUP DATABASE [DatabaseNameToBackUp] TO  DISK = @pathwithname WITH  RETAINDAYS = 10, NOFORMAT, NOINIT,  NAME = N'PodcastDatabase-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO

What the script does, is that it creates a backup for a database you want, but for naming the back up file, it uses the current date time and appends them to the file name.

To run and see if it works, you can run the following command in CMD :

"\....\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\SQLCMD.EXE" -S server\sqlexpress -i "C:\backup.sql"

So the tool which we need here is “SQLCMD” and it is located under Tools\binn folder in the installation path of SQL server express. It requires two parameters, the SQL server instance, and the path of the script to run.

The next step would be run it automatically. Run the “Task Scheduler” application in windows and click on the “Create a basic Task”. Define a name for and and go to next step.

Now you need to setup the trigger condition, daily, weekly or etc.

When you reach to action step, choose “Start Program” and click next. In the dialog box, write the path to “SQLCMD” and in “Add Argument” section, write

-S server\sqlexpress -i "C:\backup.sql"

That is it !

Real-time collaboration in Visual studio

Almost all of us know about pair programming benefits. To name a few benefits I can say greater resiliency, fewer mistakes and bugs, Increased code quality and faster training. However it has its own downsides. For instance, working on a single initiative may seem like a waste of valuable resources. In addition, The ideal amount of time to spend pair programming seems to be around 2 to 2.5 hours. Moreover it is not always possible to do pair programming because these days the ability to work remotely made it easier for developers to work from where ever they want.

However by the feature introduced by Microsoft which is called Visual Studio Live Share, the costs and downsides of the pair programming may decrease. If you have the experience of editing of a document in Google drive with other people in real-time, you know how effective it could be. Therefore by using the Visual Studio Live Share you can collaborate with others in real-time. In fact it allows you to instantly and securely share your current project, and then as needed, share debugging sessions, terminal instances, localhost web apps, voice calls, and more.

Screenshot of Visual Studio Live Share, showing participants in a collaboration session

How to do login in an ASP.NET MVC application using JMeter

One of the important things when it comes to load test your web application, is to fake an authenticated user to test the heavy load functions. Each web application has its own requirements to identify a user, but these days, all applications use some mechanism to prevent CSFR attacks. In an asp.net MVC applications, forms are protected by using AntiForgery tokens. In this article, I would show you how to do login in asp.net MVC application and load test with logged-in user.

I assume that you are familiar with simple http load testing in JMeter. Therefore, the first thing is to add a Cookie Manager to test plan, after you configured the Thread group. Some might say that getting the antiforgery token from the login form is enough, but all the action method annotated with “ValidateAntiForgeryToken” attribute, need forgery cookie in addition to forgerytoken in form request body.

You can add Cookie manager as below:

1

The next step is to add a Http GET Request to get the antiforgery from the login form. It is as easy as requesting the form, and just add Regular Expression Extractor and configure it to get the antiforgery value from the hidden input. In this step, you declare a variable to save the antiforgery value and use it in next steps.

2-1

2

The last step is to request login page, but this time with POST method. You just fill in the required parameters like username, password and the antiforgery token you saved in last step:

3

That’s all you need to load test a function or page with an identifiable user.

TeamCity 10 and ASP.NET MVC

I am new to team city and I read a book about it that describes how to build a java project using maven and use TeamCity to automate the build process.

But I am mainly .NET developer, so I started searching how to automate build and test of an ASP.NET MVC project.

The project was developed using Visual Studio 2015. First to consider when configuring TeamCity build step, is that you should have nuget installer as the first step. For that to work, you should already install nuget tools in TeamCity as below :

teamcity-1

Then in build steps, configure nuget installer:

teamcity-2

For the second step, you have to configure a Visual Studio runner type, so it would build the project:

teamcity-3

But you may encounter an error while trying to build project, cause the teamcity server may not have proper MSIBUID tool, and libraries. So, according to the response in the stackoverflow, first you have to install the proper Build Tool  (you can find 2015 Version from https://www.microsoft.com/en-us/download/details.aspx?id=48159), and then copy the required web application folders for your targeted build.

It works, but if you have Unit test in your project, and it configured to use Visual Studio default Unit Test library, it may will fail cause it cant find appropriate dll.

In another post I will write about how to use NUnit and add it as build step in TeamCity.

Create Pie Chart For Dynamics CRM using HighCharsts

Dashboards and KPI`s are those tools that every manager wants from a Business software like CRM, ERP and etc.

In a company that I develop Dynamics CRM for their based on their requirements, I was asked to create a charts for the marketing dashboard. Default chart tool in Dynamics CRM helps you easily create chat using wizard but it has drawbacks, and one the main drawbacks is that filtering the data to be displayed in chart is not as easy as creating the chart.

So after lots of search and try, I selected Highcharts to use in dashboard. In the following, I explain a sample, that shows a pie chart by lead source.

Note: All the codes here work for Dynamics CRM 2011, but it also works for 2013.

Here is the code:

<html lang="en"><head>
			<link id="sharedaddy-css" href="new_pikaday.css" rel="stylesheet" type="text/css" media="all">
	<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
    <script src="new_jquery1.6.min.js" type="text/javascript"></script>
	<script src="new_sdk.rest.js" type="text/javascript"></script>
	<script src="new_json2.js" type="text/javascript"></script>
	<script src="new_sdk.metadata.js" type="text/javascript"></script>
	<script src="new_highcharts.js" type="text/javascript"></script>
	<script src="new_moment.js" type="text/javascript"></script>
	<script src="new_pikaday.js" type="text/javascript"></script>
	<script src="new_custom_reports_common.js" type="text/javascript"></script>
	<script type="text/javascript">
		var teamusers;
		function LeadSourceDataClass()
		{
			this.Name = '';
			this.Items = [];
		}
		
		function LeadSourceDataClassItem(title, code)
		{
			this.Title = title;
			this.Code = code;
			this.Data = 0;
		}
			
		LeadSourceDataClass.prototype.reSet = function(){
			this.Items = [];
		};
				
		LeadSourceDataClass.prototype.AddToItem = function(code){
			$.each(this.Items, function(index, item)
			{
				if(item.Code == code)
				{
					item.Data += 1;
					return false;
				}
			})
		};	
		var dataObj = new LeadSourceDataClass();
		
		function generateChart()
		{
			dataObj.reSet();
			var filter = getFilter();
			var options = "$select=LeadId,LeadSourceCode&$filter=" + filter + "&$top=" + Helper.XRM.CustomReports.MaxRecords;
			SDK.Metadata.RetrieveAttribute("Lead", "LeadSourceCode", "00000000-0000-0000-0000-000000000000", true, function (result) {
				for (var i = 0; i < result.OptionSet.Options.length; i++) {
					var text = result.OptionSet.Options[i].Label.LocalizedLabels[0].Label;
					var value = result.OptionSet.Options[i].Value;
					dataObj.Items.push(new LeadSourceDataClassItem(text, value));
				}
				SDK.REST.retrieveMultipleRecords("Lead", options, retrieveLeads, function (error) { console.log(error); }, retrieveLeadsCompleted);
			}, function (error) { console.log(error); })
		}
			
		function retrieveLeads(data)
		{
			$.each(data,function(index, item)
			{
				if(item.LeadSourceCode)
					if(item.LeadSourceCode.Value)
						dataObj.AddToItem(item.LeadSourceCode.Value);
			})
		}
			
		function retrieveLeadsCompleted()
		{
			var data = [];
			$.each(dataObj.Items, function(index, item)
			{
				data.push([item.Title, item.Data]);
			});
 			var series = [
				{
					type: 'pie',
					name: '',//name,
					data: data
				}
			];
			Helper.XRM.CustomReports.createPieChart('#chartcontainer', 'Leads by Source (Pie)', series, chartClickEvent, chartTooltipFunction);
		}
		
		function chartTooltipFunction()
		{
			return this.key + ': ' + this.y;
		}
		
		function chartClickEvent(event) 
		{
			
		}
		
		function getFilter()
		{
			var filter = "";
			
			
			
			
			if($('#fromPicker').val())
				filter += " and CreatedOn ge datetime'" + $('#fromPicker').val() + "T00:00:00Z'";
		    if($('#toPicker').val())
				filter += " and CreatedOn le datetime'" + $('#toPicker').val()   + "T23:59:59Z'";
			if($('#usersSelect').val())
				filter += " and CreatedBy/Id eq guid'" + $('#usersSelect').val() + "'";
			if (filter.substr(0, 5) == " and ")
				filter = filter.substr(5);
			return filter;
		}
		
		$(document).ready(function(){
			Helper.XRM.CustomReports.createDatePicker('fromPicker');
			
			Helper.XRM.CustomReports.createDatePicker('toPicker');
			
			
			$('#generateBtn').click(generateChart)
			
			
			
		});
	</script>
</head>
<body>
<div id="contentwrapper">
<div id="content" style="height: 62%;">
<div id="chartcontainer"></div>
</div>
<div id="filters">

				<a id="viewRecords" href="http://google.com" target="_blank">View Records</a>

<hr>

<table class="filtersTbl">
<thead>
<tr>
<th style="width: 25%;"></th>
<th style="width: 25%;"></th>
<th style="width: 25%;"></th>
<th style="width: 25%;"></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableLabel">From</td>
<td><input id="fromPicker" type="text"></td>
<td class="tableLabel">To</td>
<td><input id="toPicker" type="text"></td>
</tr>
<tr>
<td></td>
<td><input name="generateBtn" id="generateBtn" type="button" value="Generate"></td>
</tr>
</tbody>
</table>
</div>
</div>
</body></html>

So let’s explain each part separately.

You see that there are bunch of scripts and a CSS file in the first. You  can add web resources to Dynamics CRM using Customization section of main settings, so I skip the part.

I use pickaday library to make it easier for user to select the date range from a calendar. To interact with Dynamics API, I use these libraries : ClientGlobalContext.js.aspx, sdk.rest.js, json2.js, sdk.metadata.js. And the most important one, is Highchart js lib that I included in my file.

In the body of the file, I have some html elements that help user fill in the filtering data such as Creation Date range.

But the main part is in script I wrote.

LeadSourceDataClass, LeadSourceDataClassItem are helper objects to hold data I retrieve from Dynamics API. LeadSourceDataClassItem contains the title of Lead Source and its Numerical Code, as in Dynamics, Option Set field types, have a title and a corresponding numerical code.

In $(document).ready method, I setup some code and configuration. The helper method XRM.CustomReports.createDatePicker … initialize and setup a field to be Calendar type. $(‘#generateBtn’).click(generateChart) Bind the click event to “generateBtn’” element.

In generateChart method, first we call Dynamics API to retrieve Lead metadata, which in this case we only wants list of defined items of Lead Source options set.  We pass each record in the form of LeadSourceDataClassItem, and save it to dataObj. After reading all options ends, we pass a method named to be called. This is the method:

SDK.REST.retrieveMultipleRecords(“Lead”, options, retrieveLeads, function (error) { console.log(error); }, retrieveLeadsCompleted)

It first method accept the Entity you want to query, second accepts the filtering for the query, third is the success call back for each loop, and the last one is called when all the loops are finished being read.

But what I mean by each loop, in above? Using Dynamics CRM API, you cannot read all items of requested Entity, but you have to read it 1000 by 1000.

In retrieveLeads method, I read each lead and if it has value for Lead source, It is being added to list. The method AddToItem, check to which Lead Source it belongs and add it to corresponding list.

I missed to explain how options variable, which we use t filter data initiated. We use a helper method called getFilter, that read Selected Date vales from date pickers and creates the filtering string according to OData standards.

In retrieveLeadsCompleted mehod, we reduce our data to be show in Pie chart. By reduce I mean, reading each Lead Source title, and sum of its data, in this case count of items. Finally I use a helper method to show charts by using Highcharts API.

Here is the helper js file:

var Helper = Helper || {};
Helper.XRM = Helper.XRM || {};
Helper.XRM.CustomReports = Helper.XRM.CustomReports || {};

Helper.XRM.CustomReports.MaxRecords = 100000;

//OptionSet Filter
Helper.XRM.CustomReports.createOptionSetSelect = function (EntityLogicalName, AttributeLogicalName, itemToAppend, addEmptyValue){
	SDK.Metadata.RetrieveAttribute(EntityLogicalName, AttributeLogicalName, "00000000-0000-0000-0000-000000000000", true, function (result) {
			if (addEmptyValue)
			    itemToAppend.append('
<option value="null">' + '(Empty)' + '</option>');
			for (var i = 0; i < result.OptionSet.Options.length; i++) {
				var text = result.OptionSet.Options[i].Label.LocalizedLabels[0].Label;
				var value = result.OptionSet.Options[i].Value;
				itemToAppend.append('
<option value=' + value + '>' + text + '</option>');
			}
		},
		function (error) { console.log(error); }
	);
}
//End OptionSet Filter
//Create Pie Chart
Helper.XRM.CustomReports.createPieChart = function (chartcontainers, title, series, clickevent, tooltipfunction)
{
	$(chartcontainers).highcharts({
		chart: {
			type: 'pie',
		},
        credits: {
            enabled: false,
        },
		exporting: {
			enabled: false,
		},
		plotOptions: {
			pie: {
				allowPointSelect: true,
				cursor: 'pointer',
				dataLabels: {
					enabled: true,
					format: '<b>{point.name}</b>: {point.percentage:.1f} %',
					style: {
						color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black',
					},
				},
				point: {
					events: {
						click: clickevent,
					},
				},
			},
		},
		series: series,
		title: {
			text: title,
		},
		tooltip: {
			formatter: tooltipfunction,
		},
	});
}
//End Create Pie Chart	

//Create A Date Picker
Helper.XRM.CustomReports.createDatePicker = function (controlname)
{
	new Pikaday({
        field: document.getElementById(controlname),
        firstDay: 1,
        format: 'YYYY-MM-DD',
        minDate: new Date('2000-01-01'),
        maxDate: new Date('2020-12-31'),
        yearRange: [2000, 2020]
	});
}
//End Create A Date Picker
//Date Calculation
Helper.XRM.CustomReports.getDefaultStartDate = function()
{
	var firstOfThisMonth = moment();
	firstOfThisMonth.set('month', moment().month());
	firstOfThisMonth.set('date', 1);
	return firstOfThisMonth.subtract(6, 'months').format("YYYY-MM-DD");
}
Helper.XRM.CustomReports.getDefaultEndDate = function()
{
	var firstOfThisMonth = moment();
	firstOfThisMonth.set('month', moment().month());
	firstOfThisMonth.set('date', 1);
	return firstOfThisMonth.subtract(1, 'days').format("YYYY-MM-DD");
}
//End Date Calculation

This is the final look of chart in  a dashboard:

dashboard

Best Regards

ASP.NET MVC with models inheritance and views

Hi

Recently I bumped into a intersing question on stackoverflow.com. The problem was that user had a view but wanted to have some input elements based on variable model. I mean if model passed to view is a, render a Email text input and if it is b then render Name text input. But in mvc you can pass only one model to view. So I suggested have a base model and base view and by checking the type of model in view load the related view using partial as below:

 public ActionResult Base()
        {
            return View(new DerviedOne());
        }

 public class BaseModel
    {
        public int Id { get; set; }
    }

    public class DerviedOne : BaseModel
    {
        public string Email { get; set; }
    }

    public class DerviedTwo : BaseModel
    {
        public string Name { get; set; }
    }
 @using Models
@model Models.BaseModel

@{
    ViewBag.Title = "Base";
    Layout = "~/Views/Shared/_Layout.cshtml";
}


<h2>Base</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()


<div class="form-horizontal">

<h4>BaseModel</h4>

        <hr/>
        @Html.ValidationSummary(true, "", new {@class = "text-danger"})

<div class="form-group">

<div class="col-md-offset-2 col-md-10">
                @Html.TextBoxFor(x=>x.Id)
                <input type="submit" value="Create" class="btn btn-default"/>
            </div>

        </div>

    </div>


    if(Model is DerviedOne)
     {
         Html.RenderPartial("DerviedOneView", Model as DerviedOne);
     }

    if (Model is DerviedTwo)
    {
        Html.RenderPartial("DerviedTwoView", Model as DerviedTwo);
    }
}

Alternative forms for an entity based on user ownership

Hi. Long time no post!

In dynamics CRM, according to policies of your business, you can restrict users access to records using security role feature. For example a user can see only opportunities she/he owns. By at some points, some sales people need to have basic information about the business accounts they interact with, they want to know if the account already bought a product from the company or not. The easiest solution is ask the record owner, and the owner would tell the expert/salse person only detiails that is not considered secure.

But this solution causes lot of time waste. There is a feature in Dynamics CRM forms that you can define alternative forms. These forms could be seen by all roles or only specific roles. In out scenario, We want to users see to kind of forms, based on their ownership for the record. If the salesperson own the record she can see all details, if not alternate form is rendered to her. Is it achievable using a code like the following on form load event:

 

   if(CurrentRecordOwner!=CuurentActiveUser)
	   {
		         var currentFormId = Xrm.Page.ui.formSelector.getCurrentItem();

           $.each( Xrm.Page.ui.formSelector.items.get(),function(index,item){
              
                  if (item.getLabel()=="New Form Name" && currentFormId.getLabel()!="New Form Name")
                  {
                           form=item;
                  }
              });
      
          form.navigate();
	   }

It works fine! yes in first load of the form. But when forms redirect tho alternative for, from that moment, if you want to open another record of that type, CRM will use the last loaded form type, I meant if you are the owner you will see the alternate version. I inspected the loaded scripts and saw an amazing behavior. The script I binded to main form event load, was not loaded for the alternative one. Although in alternative form propeties I could see that the scipt bind for load event was there!

So in alternative form properties, I removed the corresponding script and bind it again and it worked! So I could redirect user correctly based on condition.

Slide show of categories for a wordpress widget

Hi

Most of the time you can find right plugin or widget end etc for open source CMS you choose.  When I started to run a new wordpress web site for a business, I thought there would be a widget out there that can show list of categories in sliding mode. But there was not such a thing. Actually It was not what I wanted. So I googled and got to some customized widget that show categories as plain or listed in widget. I picked one of that codes and developed it further to make is sliding also make it RTL so it can be shown in right-to-left templates.

The main code I found was this.

I am not a php or even wordpress developer, so I read wodpress docs and learnd how to use js libraries with my plugin. For sliding part, I used nice and neat jquery library called owlcarousel . But I changed it a little bit cause I used it in a RTL theme. Also to show images with categories, I installed ‘Categories Images‘ so I could use category image in my widget.

You can download the plug-in from here.