Tuesday, June 30, 2020

How to Unit Test in Asp.Net C#

Unit Testing in DotNet C#

Testing Frameworks in DotNet


XUint - Most Popular testing framework is xUnit, which is now part of the open source .NET Foundation. 
MSTest - MSTest is recently made Microsoft's open sourced test framework.

Unit Testing is to test smallest part of program such as function or method, by using a unit testing framework, the unit tests become a separate entity which can then run automated tests on the program.

Each unit is tested separately before integrating them into modules and to test further.

AAA Pattern for Unit Test in C#

The AAA (Arrange, Act, Assert) pattern is a common way of writing unit tests for a method under test.

The Arrange section of a unit test method initializes objects and sets the value of the data that is passed to the method under test.

The Act section invokes the method under test with the arranged parameters.

The Assert section verifies that the action of the method under test behaves as expected.


To test the SortArray method of our example :

The unit test framework that we use and Visual Studio IntelliSense will help us to  write code for our unit tests for a code project and to run the same in Test Explorer.

First we will add UnitTesting project as console application in our solution, will add ArraySort class having simple SortArray method to sort list of strings.

public class ArraySort
    {
        public string[] SortArray(string[] strArray)
        {
            if (strArray.Count() == 0)
                throw new ArgumentException("Array list is empty.");
            Array.Sort(strArray);
            return strArray;
        }
    }

How to define unit test for above method 


Next we are going to define test project, go to Solution explorer right click and add new project of type UnitTest and add a name UnitTesting.Test.

To add project dependency go to Solution Explorer > select UnitTesting.Test Project and click on Add Reference and select UnitTesting first project we created, now we can access the methods and classes of our main project.

Here we are going to test two methods TestSortArray() and TestSortArrayEmptyList() to test conditions when list of array is passed or when list is empty, our method in ArraySort class will throw error of ArgumentException type.
[TestMethod]
        public void TestSortArray()
        {
            string[] strArray = new string[] { "d", "b", "c", "a" };
            UnitTesting1.ArraySort arraySort = new UnitTesting1.ArraySort();
            var result = arraySort.SortArray(strArray);
            var sortedArray = new string[] { "a", "b", "c", "d" };
            bool isEqual = Enumerable.SequenceEqual(sortedArray, result);
             
            Assert.AreEqual(isEqual, true);
        }
        [TestMethod]
        public void TestSortArrayEmptyList()
        {
            string[] strArray = new string[] {};
            UnitTesting1.ArraySort arraySort = new UnitTesting1.ArraySort();
            Exception ex = Assert.ThrowsException<System.ArgumentException>(() => arraySort.SortArray(strArray));
            Assert.AreEqual("Array list is empty.", ex.Message);
        }

Wednesday, May 15, 2019

How to integrate Google reCAPTCHA with Angular And Asp.Net MVC

Choosing the type of reCAPTCHA

There are four types of reCAPTCHA to choose from when creating a new site.


Selecting second method reCAPTCHA V2 -
The "I'm not a robot" Checkbox requires the user to click a checkbox for verifying that the user is not a robot. This will either pass the user immediately (with No CAPTCHA) or challenge them to validate whether or not they are human. This is simple way to integrate and requires two lines of html code.

How to generate secret key and site key

Sign up for a google reCAPTCHA and add your site domain 

Asp.Net Implementation for google reCaptcha

With asp.net we use server side implementation to validate for google recaptcha with the secret key. We  need to do server-side validation with the secret key.

For documentation about google reCAPTCHA visit url - https://developers.google.com/recaptcha/docs/verify.

Here is a simple Asp.net mvc method that helps to validate g-recaptcha-response which I have referred from stackoverflow questions.

public bool Validate(string encodedResponse)
    {
if (string.IsNullOrEmpty(encodedResponse)) return false; var secret = **your secret**;
if (string.IsNullOrEmpty(secret)) return false; var client = new System.Net.WebClient(); var googleReply = client.DownloadString(
string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secret, encodedResponse )); return JsonConvert.DeserializeObject(googleReply).Success; }
}

Here RecaptchaResponse is a simple class we have in added Asp.Net MVC model.


public class RecaptchaResponse
{
    [JsonProperty("success")]
    public bool Success { get; set; }

    [JsonProperty("error-codes")]
    public IEnumerable ErrorCodes { get; set; }

    [JsonProperty("challenge_ts")]
    public DateTime ChallengeTs { get; set; }

    [JsonProperty("hostname")]
    public string Hostname { get; set; }
}

Each reCAPTCHA user response token is valid for two minutes, and can only be verified once to prevent replay attacks. If you need a new token, you can re-run the reCAPTCHA verification.

API Request
URL: https://www.google.com/recaptcha/api/siteverify

METHOD: POST

REQUEST PARAMETER:

secret Required. The shared key between your site and reCAPTCHA.
response Required. The user response token provided by the reCAPTCHA client-side integration on your site.
remoteip Optional. The user's IP address.

Sunday, May 5, 2019

Upload files with AngularJS in Asp.Net MVC 5 controller

AngularJS file upload using Asp.Net MVC and angular directive having ngFileSelect attribute.

While I was working to build a web application using ASP.NET MVC 5 and AngularJS, I have to build a  file upload functionality. I then stumbled upon a couple of AngularJS directives for File upload using Angular. Here I will explain how to upload file with AngularJS and Asp.Net MVC using jQuery formData.

Add new action into your controller for upload File functionality.

 public ActionResult SaveApplicationFile(HttpPostedFileBase httpPostedFile, string applicantName,
            string applicantEmail)
{
string fileSavePath = string.Empty;
try
{
if (System.Web.HttpContext.Current.Request.Files.AllKeys.Any())
{
if (httpPostedFile == null)
{
//return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest);
return Json(new { Valid = false, ErrorMessage = "No file is selected. Please select the file and try again." });
}
//Is the file too big to upload?
int fileSize = httpPostedFile.ContentLength;
var maxSizeMBs = 2;
var maxFileSize = maxSizeMBs * 1024 * 1024;
if (fileSize > (maxFileSize))
{
return Json(new { Valid = false, ErrorMessage = "Filesize of image is too large. Maximum file size permitted is " + maxSizeMBs + "MB" });
}

string contentType = httpPostedFile.ContentType; var dirFolder = applicantName;
dirFolder = RemoveWhitespace.RemoveWhitespaceLinq(dirFolder);
// server path
string tempFolderName = Server.MapPath("~/" + ConfigurationManager.AppSettings["Application.DocumentFolderName"] + "/" + dirFolder); string fileName = Path.GetFileName(httpPostedFile.FileName).Trim();
fileName = RemoveWhitespace.RemoveWhitespaceLinq(fileName);
fileSavePath = Server.MapPath("~/" + ConfigurationManager.AppSettings["Application.DocumentFolderName"] + "/" + dirFolder + "/" + fileName);
string filePath = "/" + ConfigurationManager.AppSettings["Application.DocumentFolderName"] + "/"
+ dirFolder + "/" + fileName; //db path if (!Directory.Exists(tempFolderName))
{
Directory.CreateDirectory(tempFolderName);
} TestApp.DataModel.FileContent fileContent = new TestApp.DataModel.FileContent();
fileContent.FileName = fileName;
fileContent.FilePath = filePath;
fileContent.ContentType = contentType;
fileContent.CreatedBy = applicantName; // save in db fileContent
var result = serviceHelper.SaveApplicationFile(fileContent); if (!result.IsExceptionOccured)
{
//save file image & pdf
string fileExt = Path.GetExtension(httpPostedFile.FileName).ToUpper(); if (httpPostedFile != null && httpPostedFile.ContentLength > 0 &&
(fileExt == ".PDF" || fileExt == ".DOC" || fileExt == ".DOCX"))
{
httpPostedFile.SaveAs(fileSavePath);
}
return Json(new { Valid = true, FilePath = fileSavePath });
}
else
{
return Json(new { Valid = false, ErrorMessage = result.ErrorMessage });
}
}
else
{
return Json(new
{
Valid = false,
ErrorMessage = "Please select file to upload"
});
}
}
catch (FileNotFoundException ex)
{
//NLogger.LogWrite().Info(ex.Message);
return Json(new
{
Valid = false,
ErrorMessage = ex.Message + " " + fileSavePath
});
}
catch (Exception ex)
{
//NLogger.LogWrite().Info(ex.Message);
return Json(new
{
Valid = false,
ErrorMessage = ex.Message + " " + fileSavePath
});
}
}

AngularJS Controller

Add a new js File for add a new AngularJS controller and a Directive. The file input type does not support 2 way binding, so we need to find an own solution for file uploads with AngularJS.
How to upload file using ng-file-Select attribute in angular. And save using Asp.Net MVC method on sever. We need to add headers in  angular $http post method.

$scope.SaveFile = function () {


            var formData = new FormData();
            formData.append("httpPostedFile", $scope.SelectedFileForUpload);

            //We can send more data to server using append to formData object.     
            formData.append("applicantName", $scope.applicantName); 
            formData.append("applicantEmail", $scope.applicantEmail); 

            $http.post("/Home/SaveApplicationFile", formData, {
                withCredentials: true,
                headers: { 'Content-Type': undefined },
                transformRequest: angular.identity
            }).success(function (response) {

                alert(response.ErrorMessage);
                
                $("#btnUpload").hide();
                //$("#btnUpload").prop('disabled', true);
                $scope.clearForm();
            }).error(function (error) {
                alert(error);
            })

        }

Angular Directive
ng-file-Select directive applying attribute to the html input file control, and also add $timeout for dependency injection in angularjs.

  .directive("ngFileSelect", ['$timeout', function ($timeout) {
        return {
            link: function ($scope, el) {
                el.bind("change", function (e) {
                    $scope.SelectedFileForUpload = (e.srcElement || e.target).files[0];
                   
                    var filename = $scope.SelectedFileForUpload.name; //$('input[type=file]').val().replace(/.*(\/|\\)/, '');
                    $scope.$apply(function () {
                        $scope.filename = filename;
                    });
                });
            }
        }
    }]);

Thursday, April 18, 2019

How To Create WCF Http Web Service In Asp.Net MVC


Windows Communication Foundation (WCF) allows you to create a service that exposes a Web endpoint. Web endpoints send data by XML or JSON, there is no SOAP envelope. This topic demonstrates how to expose such an endpoint.

Steps to create a WCF http rest based service

  1. Define a service contract using an interface marked with the ServiceContractAttribute, WebInvokeAttribute and the WebGetAttribute attributes.
  2. Implement the service contract.

Note: The only way to secure a Web endpoint is to expose it through HTTPS, using transport security. When using message-based security, security information is usually placed in SOAP headers and because the messages sent to non-SOAP endpoints contain no SOAP envelope, there is nowhere to place the security information and you must rely on transport security.



How to Unit Test in Asp.Net C#

Unit Testing in DotNet C# Testing Frameworks in DotNet XUint - Most Popular testing framework is xUnit, which is now part of the open source...