Friday, April 12, 2019

Using AutoMapper - Map from one object to another object C#

1) Install the automapper to your project through NuGet package manager


2) Initialize the automapper in the Global.asax file

        protected void Application_Start()
        {
            AutoMapper.Mapper.Initialize(cfg => cfg.AddProfile<AutoMapperProfile>());
         }


3) My classes to be mapped are:

   //DAO classes
    public class Passenger
    {
        public int OrderNo { get; set; }
        [Key]
        public int TcNo { get; set; }
        public string PsgrName { get; set; }
        public string FlightId { get; set; }
        public string CarrierCode { get; set; }
        public string FlightNo { get; set; }
        public string Origin { get; set; }
        public string Destination { get; set; }
        public string DepDateTime { get; set; }
        public string ArrDateTime { get; set; }
        public virtual ICollection<Device> Devices { get; set; }
    }

    public class Device
    {
        public string Language { get; set; }
        [Key]
        public string RegistrationId { get; set; }
        public string DeviceType { get; set; }
        public int TcNo { get; set; }
    }

//DTO classes to be mapped
    public class PassengerDTO
    {
        public int OrderNo { get; set; }
        public int TcNo { get; set; }
        public string PsgrName { get; set; }
        public string FlightId { get; set; }
        public string CarrierCode { get; set; }
        public string FlightNo { get; set; }
        public string Origin { get; set; }
        public string Destination { get; set; }
        public string DepDateTime { get; set; }
        public string ArrDateTime { get; set; }
        public virtual ICollection<DeviceDTO> Devices { get; set; }
    }

    public class DeviceDTO
    {
        public string Language { get; set; }
        public string RegistrationId { get; set; }
        public string DeviceType { get; set; }
    }

4) Create a mapper profile to map between the DAO and DTO object

    public class AutoMapperProfile : Profile
    {
        public AutoMapperProfile()
        {
            CreateMap<Passenger, PassengerDTO>();
            CreateMap<Device, DeviceDTO>();
        }
    }

5) Do the actual mapping in the code

IList<PassengerDTO> data = db.Passengers.Where(p => p.FlightId == FlightId).ProjectTo<PassengerDTO>().ToList();

Saturday, March 9, 2019

SvcUtil to generate Proxy from the WSDL file

To generate the proxy from the wsdl file, use the svcutil.exe. You can access it either by navigating via command prompt to the physical path of the file (Example: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin)  or simply by using Visual Studio Command Prompt

svcutil.exe ProvideShopping.wsdl  /Language=c# /t:Code /out:Shopping.cs /config:Shopping.config

You might get an error in case you don't specify the xsd files along with the WSDL file

Example errors might be:

Error: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.dataContractSerializerMessageContractImporter
Error: Schema with target namespace "http://someUrl" could not be found 

Error: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.

Add the related .xsd files to the folder which contains the wsdl and run command again

svcutil.exe ProvideShopping.wsdl commontypes.xsd ShoppingQ.xsd ShoppingS.xsd edist.xsd bis.xsd structures.xsd System1.xsd  /Language=c# /t:Code /out:Shopping.cs /config:Shopping.config

Please note if you are not interested in going through the generated code, but you only want a service reference in Visual Studio, then simply provide the path to the wsdl file location in your computer. There also you have to have the related .xsd files in the folder containing the wsdl or else you will get an error when Visual Studio generates the service reference for you.

Wednesday, January 2, 2019

Log4Net - Logging to the Database and Troubleshooting logging Issues

There are a three parts to log4net. There is the configuration, the setup, and the call

There are seven logging levels, five of which can be called in your code.

OFF - nothing gets logged (cannot be called)
FATAL
ERROR
WARN
INFO
DEBUG
ALL - everything gets logged (cannot be called)

1) Setting up log for net in your project

Select Tools menu > NuGet package manager > Manage NuGet packages for the solution

Once the NuGet is installed you get the log4net dll under the References list.

2) Add the below line to the AssemblyInfo.cs file

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

Configurations


  •  In The App.config file add the log4net configurations


<configuration>

  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"></section>
  </configSections>


  • Adding the appender and the logger details.


  <log4net>
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
            <bufferSize value="1" />
            <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
            <connectionString value="data source=MyDatabaseServer;initial catalog=MyDatabaseName;integrated security=false;persist security info=True;User ID=sa;Password=****" />
            <commandText value="INSERT INTO Log ([logdate],[message]) VALUES (@logdate, @message)" />
            <parameter>
              <parameterName value="@logdate" />
              <dbType value="DateTime" />
              <layout type="log4net.Layout.RawTimeStampLayout" />
            </parameter>
          <parameter>
          <parameterName value="@message" />
          <dbType value="String" />
          <size value="255" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%message" />
          </layout>
        </parameter>
    </appender>
    <logger name="AdoNetAppender">
      <level value="INFO" />
      <appender-ref ref="AdoNetAppender" />
    </logger>
  </log4net>

In the code, declare the logger

private static ILog myLog = LogManager.GetLogger("AdoNetAppender");

In the code add logging

myLog.Info(string.Format("{0}\t{1}\t{2}", DateTime.Now, "Before do work", i));

The logger pushes logging info to the DB in batches. So maker sure to push each log by using the <bufferSize value="1" /> as configured in the app.config above.

Trouble shooting Logger issues

Example 1 : Logger does not log anything to the database

To troubleshoot logger issues add the below configurations to the app.config file.

     <appSettings>
      <add key="log4net.Internal.Debug" value="true"/>
   </appSettings>

  <system.diagnostics>
        <trace autoflush="true">
        <listeners>
            <add
                name="textWriterTraceListener"
                type="System.Diagnostics.TextWriterTraceListener"
                initializeData="C:\tmp\log4net.txt" />
        </listeners>
    </trace>
  </system.diagnostics>

This will log issues in the mentioned text file.

Example 2 : After the DB goes offline or losing DB connectivity and comes back online, the logger does not Log anymore.

to solve this add the tag  <reconnectonerror value="true" />

Example:

    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
            <bufferSize value="1" />
            <reconnectonerror value="true" />

Adding this might slow down the app performance since, log4net trys to reconnect to the server till the connection attempt time outs.

To overcome that you need to set a connection timeout in the connection string as shown below:

 <connectionString value="data source=MyDatabaseServer;initial catalog=MyDatabaseName;integrated security=false;persist security info=True;User ID=sa;Password=****;Connect Timeout=1" />

If you had the troubleshooting configurations as shown in an above step, then you would get an output similar to this:




Tuesday, January 1, 2019

Install Uninstall Windows Service

From start menu select the "Developer Command Prompt for Visual Studio". right click on the menu item and run as administrator.



In the command prompt change the working directory to the bin/Debug folder of the Windows service Solution. Then give the command to install.

To install:

 installutil.exe MyWindowsService.exe

To uninstall:

installutil.exe /u MyWindowsService.exe

Saturday, December 1, 2018

Postman testings on WEB API

1) Get - WEB API method signature


    Get - Postman Call


2) Post WEB API method signature


      Post - Postman Call


  • Body part of the call



  • Header and Result




3) Post - Multipart request, including Image file




  • WEB API method signature


Postman call -  Multipart, including Image file


Capturing the HTTP multi-part requests data within the WEB API method:

                if (HttpContext.Current.Request.Params["FirstName"] != null)
                {
                    newUser.FirstName = HttpContext.Current.Request.Params["FirstName"];
                }

Capturing the image file sent:

var imageFile = HttpContext.Current.Request.Files.Count > 0 ? HttpContext.Current.Request.Files[0] : null;


Querying Database tables using Linq


Join two tables. Check for boolean values in columns. Select multiple columns 

var eventFBQuestions = (from FQ in db.FeedbackQuestions join FT in db.FeedbackTypes on FQ.FeedbackTypeId equals FT.Id where (!FQ.Archived && !FT.Archived && FT.Name == "Event") select new { FQ.Id, FQ.Question }).ToList();

Get the count

var countForOne = (from Fb in db.Feedbacks where (Fb.FeedbackQuestionId == question.Id && Fb.FeedbackScore == 1) select Fb.Id).Count();


Join more than two tables. Alter the select columns by concatenating the select fields

            var sessions = (from s in db.Sessions
                        join t in db.Tracks on s.TrackId equals t.Id
                        join e in db.Events on t.EventId equals e.Id
                        where (!s.Archived && !t.Archived && !e.Archived)
                        select new {s.Id, Name = t.Name + " - " +  s.Name }).ToList();

same thing into a dictionary

            var sessions = (from s in db.Sessions
                        join t in db.Tracks on s.TrackId equals t.Id
                        join e in db.Events on t.EventId equals e.Id
                        where (!s.Archived && !t.Archived && !e.Archived)
                        select new {ID=s.Id.ToString(), NAME = t.Name + " - " +  s.Name }).ToDictionary(dic => dic.ID, dic => dic.NAME);

Saturday, November 24, 2018

D3 - Donut Chart

Here  I do a WEB API call and get the required data.


Sample code is as below

$(document).ready(function () {

    var jsonDataTshirt = {};
    var tshirts = [];

    jsonDataTshirt.tshirts = tshirts;
.
.
.


    //1) get tshirt sizes
    $.getJSON("API/MyWEBAPICall",
        function (Data) {

            $.each(Data, function (key, val) {

                if (key != "$id") {
                    var uCategory = { "fruit": key, "count": Number(val) };
                    jsonDataTshirt.tshirts.push(uCategory);
                }
            });

            // margin
            var margin = { top: 20, right: 20, bottom: 20, left: 20 },
                width = 400 - margin.right - margin.left,
                height = 400 - margin.top - margin.bottom,
                radius = width / 2 - 20;

            // color range
            var color = d3.scaleOrdinal()
                .range(["#BBDEFB", "#90CAF9", "#64B5F6", "#42A5F5", "#2196F3", "#1E88E5", "#1976D2"]);

            // donut chart arc
            var arc2 = d3.arc()
                .outerRadius(radius - 10)
                .innerRadius(radius - 70);

            // arc for the labels position
            var labelArc = d3.arc()
                .outerRadius(radius - 40)
                .innerRadius(radius - 40);

            // generate pie chart and donut chart
            var pie = d3.pie()
                .sort(null)
                .value(function (d) { return d.count; });

            // define the svg donut chart
            var svg2 = d3.select("#pie-tshirts-male").append("svg")
                .attr("width", width)
                .attr("height", height)
              .append("g")
                .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

            var data = jsonDataTshirt.tshirts;
            // parse data
            data.forEach(function (d) {
                d.count = +d.count;
                d.fruit = d.fruit;
            })

            // "g element is a container used to group other SVG elements"
            var g2 = svg2.selectAll(".arc2")
                .data(pie(data))
              .enter().append("g")
                .attr("class", "arc2");

            // append path
            g2.append("path")
                .attr("d", arc2)
                .style("fill", function (d) { return color(d.data.fruit); })
              .transition()
                .ease(d3.easeLinear)
                .duration(2000)
                .attrTween("d", tweenDonut);

            // append text
            g2.append("text")
              .transition()
                .ease(d3.easeLinear)
                .duration(2000)
              .attr("transform", function (d) { return "translate(" + labelArc.centroid(d) + ")"; })
                .attr("dy", ".35em")
                .text(function (d) { return d.data.fruit; });

            //Add the count in outside the arc
                g2.append("text")
                    .transition()
                    .ease(d3.easeLinear)
                    .duration(2000)
                    .attr("transform", function(d) {
                        var _d = labelArc.centroid(d);
                        _d[0]*= 1.4; //multiply by a constant factor
                        _d[1] *= 1.4; //multiply by a constant factor
                        return "translate(" +_d + ")";
                        })
                    .attr("dy", ".35em")
                    .text(function (d) {
                       return d.data.count;
                        })
                    .style("font-size", "10px");;

            function tweenDonut(b) {
                b.innerRadius = 0;
                var i = d3.interpolate({ startAngle: 0, endAngle: 0 }, b);
                return function (t) { return arc2(i(t)); };
            }

        });
.
.
.
});


Sample: Do nut chart is drawn as shown in the middle