A simple, lightweight data access library for any ADO.Net providers like SQL server, Oracle & MySQL.

Source –

No Dependencies

Since Data.Net is written in .NetStandard 2.0 no third party libraries are required.

Supporting platforms

Data.Net support multiple frameworks and platforms.

  • Net Core 2.0 / ASP.NET Core 2.0
  • Net Standard 2.0
  • NetFramework 4.6.1
  • NetFramework 4.6.2
  • NetFramework 4.7.0


Install Data.Net via Nuget

PM> Install-Package Data.Net

Execute a query and return a single value from the first row

using (var db = new Database()) //make sure connection string is configured in the config file with <connectionStrings><clear/><add../></connectionStrings>
  var firstName = db.ExecuteScalar<string>("SELECT FirstName From Users_Test Where Email = @Email",
                  parameters:new DataParameters{{"Email", "" } });

Execute a query and convert to POCO object

public class User
    public string FirstName { get; set; } //make sure property name is same as table column name, otherwise use alias in sql query.
    public string LastName { get; set; }
    public string Email { get; set; }

using(var db = new Database(new OracleConnection("connectionString")))
    List<User> q = db.Query<User>("SELECT EmailAddress as Email,LastName FROM Users_Test");
    Assert.IsTrue(q.Count > 0);

Execute a stored procedure and get multiple output parameter and return value.

 var parameters = new DataParameters
    { "@Email", "" },
    { "@RecordCount"}, //Default parameter direction is 'output'
    { "@AnotherOutParameter"},
    { "@ReturnVal",ParameterDirection.ReturnValue}

  var q = db.Query<User>("PROC_NAME", CommandType.StoredProcedure, parameters);
  Assert.IsTrue(q.Count > 0);
  Assert.IsTrue(dataParameter.Value<int>("@RecordCount") > 0);
  Assert.IsTrue(dataParameter.Value<int>("@AnotherOutParameter") > 0);
  Assert.IsTrue(dataParameter.Value<int>("@ReturnVal") > 0);

Execute a command with DB transaction.

using (var db = new Database())
      db.BeginTransaction(); //create transaction.
      db.ExecuteNonQuery("sql", parameters:new DataParameters{{"Email", "" } });
      db.ExecuteNonQuery("sql", parameters:new DataParameters{{"Email", "" } });
      db.CommitTransaction(); //commit transaction.
  catch (Exception)
      db.RollbackTransaction(); // rollback if any failure. 

Execute multiple query using a single DB connection instance

using(var db = new Database())
  var reader1 = db.ExecuteReader("sql",CommandType.Text,parameters,CommandBehavior.Default);
  var reader2 = db.ExecuteReader("sql",CommandType.Text,parameters); //default behaviour is close connection

Create DB provider specific parameter object

Data.Net support multiple overloads so that you can create DB specific parameter object like below.

public void Add(IDbDataParameter parameter) {}  //For any Ado.Net specific provider
public void Add(string name, object value) {}
public void Add(string name, ParameterDirection direction = ParameterDirection.Output,DbType dbType = DbType.Int32, int size = 0) {}

Example usage

var p = new DataParameter();

p.Add(new OracleParameter("name","value"));

Please check out more samples in the Unit test app.

.Net Core porting challenges

I was recently porting a .Net 4.6.2 C# Scheduler app to .Net core 1.0.1 Cent OS.7 64 bit machine in Azure and I’ve learned a good lesson especially with HttpClient API. I will be mainly focusing some of the issues I’ve encountered with .Net Core HttpClient library in Linux platform in this article.

As I mentioned above, Initially this app was targeting to .NetFramework Windows server and later I ported to Linux. Once after the app has been deployed to Azure Linux I was getting the following issues.

NOTE : Most of the issues I am talking here did not show up in Windows platform (Windows 10, Windows Server 2012 R2).

1) AppDomain & Unhanded exceptions

AppDomain.CurrentDomain.UnhandledException += UnhandledException;

The above one liner code for handling UnhandledException exception doesn’t work .Netcore 1.0 or 1.1. AppDomain class supports started from .NET Framework 1.1, however this was removed in .NetCore due to performance issue and other reasons here here and here which is fine I am totally agree the point. However, it would be great if they have alternate solution for handling Unhanded exception. Hoping this would get added in .Net Core 2.0 release.

2) ServicePointManager 

In .Net core there is no ServicePointManager class instead use base HttpHandler class and If you are on Windows use WinHttpHanlder and non windows platform make sure to use HttpClientHandler to call the method and properties like below.

 var handler = new HttpClientHandler
     AllowAutoRedirect = false;
     AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
 handler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) =&amp;gt; true;

3) PlatformNotSupportedException for ServerCertificateCustomValidationCallback

One of the common error you might encounter while using .Net core or Net standard in non windows platform is PlatformNotSupportedException. Hopefully they are going to address this in 2.0 versions. ServerCertificateCustomValidationCallback works fine in windows. However, by default this won’t work in Linux and MAC OS unless the libcurl library point to OpenSSL. I have opened a github issue and .Net corefx team was provided some solution to address the issue. Unfortunately there are no documentation explains these kind of issues.

The libcurl library in use (7.29.0) and its 
SSL backend ("NSS/3.19.1 Basic ECC") do not support custom handling of certificates. 
A libcurl built with OpenSSL is required.

4) System.Net.Http.HttpRequestException: The server returned an invalid or unrecognized response.
I have encountered this exception lately and I opened a new github issue and the corefx team planing to address this issue in 2.0.


Porting to .net core app is really great experience and good learning curve for the new platform. I would definitely recommend to check .NET Portability Analyzer to find out how much libraries and APIs are supporting to .Net Core. Also, follow github issue tracker for .Net Corefx repository.

References / Tools –

Convert C# camel case json property to pascal case

I am pretty sure that many of them faced the same scenario where you would end up copy/paste some json data from a third party API sites And using one of the tools like Visual Studio IDE or to generate POCO classes. However, these tools will not generate pascal case property’s automatically And if you want to maintain the coding standard you have to change the property’s to pascal case manually.

For example : Default camel case property’s generated based on Visual Studio IDE

public class Refunds
   public string @object { get; set; }
   public bool has_more { get; set; }

Since I had to convert many json property’s to pascal casing which is a tedious task so I have developed an app to convert camel case csharp json property to pascal case.

jsonProperty2TitleCase Core Features:

  • Convert property to Title case which is Pascal case
  • Add NewtonsoftJson property attribute to add the actual json property name for deserializing purpose.
  • Also, handles nested classes hierarchies.
  • Beautify your csharp code  (Remove all extra white spaces)

jsonProperty2TitleCase Output:

using Newtonsoft.Json;

public class Refunds
    public string Object { get; set; }

    public bool HasMore { get; set; }


Please feel free to give this a try and let me know your thoughts and suggestions.

Asp.Net MVC5 Authorization

The sample application will walk you through how to create Claim based Authorization Middleware with Owin and Katana libraries using .Net 4.5.2 framework.

Github source –


  • File -> New Project -> Asp.Net Web Application -> Asp.Net 4.5.2 Templates
  • Choose empty MVC project template


  • Install following nuget packages
    • Microsoft.AspNet.Identity.Core
    • Microsoft.AspNet.Identity.Owin
    • Microsoft.Owin
    • Microsoft.Owin.Host.SystemWeb
    • Microsoft.Owin.Security
    • Microsoft.Owin.Security.Cookies
    • Microsoft.Owin.Security.OAuth
    • Owin


  • Create a Owin Startup class and decorate with assembly attribute OwinStartup.
    using Microsoft.AspNet.Identity;
    using Microsoft.Owin;
    using Microsoft.Owin.Security.Cookies;
    using Owin;
    [assembly: OwinStartup(typeof(AspNetMVC5Authorization.Startup))]
    namespace AspNetMVC5Authorization
        public class Startup
            public void Configuration(IAppBuilder app)
            private void ConfigureAuthentication(IAppBuilder app)
                app.UseCookieAuthentication(new CookieAuthenticationOptions
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                    LoginPath = new PathString("/Auth/Login"), //sign page
                    CookieName = "AuthCookie",
                    CookieHttpOnly = true,
                    ExpireTimeSpan = System.TimeSpan.FromHours(1),
                    LogoutPath = new PathString("/Auth/Signout"), //sign out page
                    ReturnUrlParameter = "ReturnUrl",
                    CookieSecure = CookieSecureOption.SameAsRequest, //Use CookieSecureOption.Always if you intend to serve cookie in SSL/TLS (Https)
                    SlidingExpiration = true,


  • Create list of claims for the specific user with roles and other information
    internal class AuthenticationHelper
       internal static List<Claim> CreateClaim(UserSessionModel userSessionModel,params string[] roles) //Single or multiple roles
          var claims = new List<Claim>
              new Claim(ClaimTypes.NameIdentifier, userSessionModel.UserId.ToString()),  //User ideitifer
              new Claim(ClaimTypes.Name, userSessionModel.DisplayName),  //Username
              new Claim(Constants.UserSession, userSessionModel.ToJson()) //Custom entity with user info
          foreach (var role in roles) //custom roles goes here
              claims.Add(new Claim(ClaimTypes.Role, role, ClaimValueTypes.String, Constants.Issuer));
          return claims;


  • Create Authentication controller and process of the rest of the Authentication
    using Microsoft.AspNet.Identity;
    using Microsoft.Owin.Security;
    using System.Security.Claims;

    public class AuthController : BaseController
      private IAuthenticationManager AuthenticationManager
          get { return HttpContext.GetOwinContext().Authentication; }

      public ActionResult SignIn(SignInViewModel vm,string returnUrl = default(string))
              if (!ModelState.IsValid)
                  vm.ErrorMessage = "Email address and Password are required fields";
                  return View(vm);

              var userSession = Authenticate(vm); // Validate authentication from db or other source.

              if (userSession != null) //create claim with user info.
                  var identity = new ClaimsIdentity(AuthenticationHelper.CreateClaim(userSession, 
                  AuthenticationManager.SignIn(new AuthenticationProperties()
                      AllowRefresh = true,
                      IsPersistent = true,
                      ExpiresUtc = DateTime.UtcNow.AddHours(1)
                  }, identity);

                  if (!string.IsNullOrWhiteSpace(returnUrl) && Url.IsLocalUrl(returnUrl)) return Redirect(returnUrl);

                  return RedirectToAction("index", "home");
          catch (AuthenticationException e)
              vm.ErrorMessage = e.Message;
          return View(vm);

      private UserSessionModel Authenticate(SignInViewModel vm)
          if (vm.Email != "" || vm.Password != "password") throw new AuthenticationException("Login failed. Incorrect email address or password");

          return new UserSessionModel
              UserId = Guid.NewGuid(),
              DisplayName = "Deepu Madhusoodanan"

      public ActionResult Signout()
          return Redirect("~/");


  • Get the custom ojbect obect from Claim
public class BaseController : Controller
    protected internal UserSessionModel UserSessionModel { get; private set; }

    protected override void Initialize(RequestContext requestContext)
        var user = User as ClaimsPrincipal;
        if (user != null)
            var claims = user.Claims.ToList();
            var sessionClaim = claims.FirstOrDefault(o => o.Type == Constants.UserSession);
            if (sessionClaim != null)
                UserSessionModel = sessionClaim.Value.ToObject<UserSessionModel>();


[Authorize(ClaimType = ClaimTypes.Role, ClaimValue = "Contributor,User")]
public ActionResult Secure()
    var userSessionModel = UserSessionModel; //Get custom object from Security claim.
    return View();

Finally Custom Authorize attribute code

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
    public string ClaimType { get; set; }
    public string ClaimValue { get; set; }

    public override void OnAuthorization(AuthorizationContext filterContext)
        var principal = filterContext.RequestContext.HttpContext.User as ClaimsPrincipal;

        if (!principal.Identity.IsAuthenticated)
            filterContext.Result = new RedirectResult("~/auth/signin");

        var claimValue = ClaimValue.Split(','); //Split custom roles and validate custom cliams, issuer and vlaue.
        if (!(principal.HasClaim(x => x.Type == ClaimType && claimValue.Any(v => v == x.Value) && x.Issuer == Constants.Issuer)))
            filterContext.Result = new RedirectResult("~/Unauthorize.html");

MadMimi.Net Integration

I have been playing around with Transaction Email Services for a while and came across the tool named MadMimi, A email marketing tool lets you to send email from a different server so that you can track whether the email delivered or bounce.

MadMimi already have a C# version API and its quite old. The reason I wrote my own version is to prevent less code change to my current project so that if I want to switch to a different provider in the feature it would be easy.

A typical email sending code

using (var message = new MailMessage())
    message.From = new MailAddress("from");
    message.Subject = "Subject";
    message.Body = "This is test";
    using (var client = new SmtpClient())

Using Library

  var mailer = new Mailer("username", "apikey");
  using (var message = new MailMessage())
      message.From = new MailAddress("from email", "display name");
      message.To.Add("sender email");
      message.Subject = "Test";
      message.Body = "Email body";
      await mailer.SendAsync("Promotion Name", message);
  var status = mailer.TrackStatus; //URL to track the email
  var mailTransactionId = mailer.TransactionId; //Transaction Id.

When you compare the above code snippets you should see additional two liner code which integrate the library (Mailer class) and that is the only change you should make your existing project and apps if you would like to integrate this.

Sender Policy Framework) – MadMimi does not care if you have set up a SPF record in DNS. While most of the competitors, this is a mandatory requirement if you want to use your own “FROM” email address other than your DOMAIN.

1) Delivery speed – Some time the email take 5-6 minutes to deliver.
2) No SMTP relay support.
3) Attachment does not support via API.

Feel free to play around and fork it if you would like to make any change to this. The GitHub link is provided below for the sample project and library.

Repository –

First Data Global Gateway Integration in Asp.Net MVC C#

I have added a new Github repository for First Data Global Gateway Integration in Asp.Net MVC.  The sample provides a rest api implementation for credit card based payment processing. Since, I have choosen Asp.Net MVC empty project template you might need to install System.Net.HttpClient library from or install directly from visual studio.

Command – Install-Package Microsoft.Net.Http

Download Location or copy paste the url

This code was taken from the original source

Example Usage:

 var paymentService = new PaymentService("1.50", "0515","Card holder name","4111111111111111", "23".ToString()); //customer Id for Internal purpose to track which customer made the transaction...
 var transactionResult = await paymenetService.PostAsync();
 if (transactionResult == null) return;
 if (transactionResult.TransactionApproved && !transactionResult.TransactionError && transactionResult.CustomerRef == customerId.ToString())
 //transaction success....
 //transaction failed
 var message = transactionResult.Message;

Configuration Settings:
Following values needs to be changed in the web.config file.

<add key="GATEWAY_ID" value="Exact ID" />
<add key="GATEWAY_PWD" value="Password" />
<add key="TRANS_TYPE" value="00" />
<add key="HMAC_KEY" value="HMAC Key" />
<add key="KEY_ID" value="Key Id" />
<add key="GATEWAY_URL" value="" />

Transaction Summary file(transaction_summary.xml) from payment gateway is included in the App_Data folder.

Also, refer :

As per First Data knowledge base Note: “Code samples are provided “as is” and are not designed to be used in production.”


Custom Template in InfoPath 2010

I’ve been playing around with InfoPath forms this weekend  for converting paper forms to eForms (Infopath forms). One of the challenge  I have faced was maintaining the consistency of application look and feel for all the forms, since InfoPath designer doesn’t support master page layout  but it also provide an alternative solution called custom TEMPLATE control which you can convert any layout in to a .STP file and can reuse across all the forms.

Click here to Download the template

Open InfoPath Designer 2010 and select Template Parts as BLANK  and click Design Form

Design your own layout…I have created a sample STP layout and Save it as  Infopath Web Browser Template Part.

Once you  save the template as .STP file then you can add it as custom template in the template section

Click Add or Remove Custom Controls and select template part and browse your .STP file.

Once the template added successfully it will appear in the Custom control section

That’s it. Now you can reuse the new custom template / control to any new forms and existing forms.

Click here to Download the template

Hope this helps and If you have any comments, please feel free to write your feedback.