Silverlight component with chart

If you ever wanted to create your own Silverlight component, this is a good place to start. In this article I will show you how to create simple component displaying salary data on the chart.

In our example the data are being stored in the application but you can easily call a web service to display the it from the different server.

silverligt-component

After creating new silverlight project in Visual Studio we start from creating basic class structure that we will bind to our chart.

  public class NumericItemPair
    {
        public string Name { get; set; }
        public double Value { get; set; }
    }

    public class ProfessionItem
    {
        public string Name { get; set; }
        public double AVG { get; set; }
        public List<NumericItemPair> DataPoints = new List<NumericItemPair>();
    }

In our example we will get some dummy data based on user selection (drop down branch list). This data can be retrieved from database or web service. Please note that we will display aggregates based on 2 deciles; lower and upper and the median value.

  public class MyDataContext
    {
        public static ProfessionItem getData(int branch)
        {
            ProfessionItem itm = new ProfessionItem();
            if (branch == 0)
            {
                itm.AVG = 2332;
                itm.Name = "IT";
                itm.DataPoints = new List<NumericItemPair>();
                itm.DataPoints.Add(new NumericItemPair() { Name = "Lower decile", Value = 1567 });
                itm.DataPoints.Add(new NumericItemPair() { Name = "Median", Value = 1789 });
                itm.DataPoints.Add(new NumericItemPair() { Name = "Upper decile", Value = 2400 });
            }
            else if (branch == 1)
            {
                itm.AVG = 2132;
                itm.Name = "Production";
                itm.DataPoints = new List<NumericItemPair>();
                itm.DataPoints.Add(new NumericItemPair() { Name = "Lower decile", Value = 1267 });
                itm.DataPoints.Add(new NumericItemPair() { Name = "Median", Value = 1589 });
                itm.DataPoints.Add(new NumericItemPair() { Name = "Upper decile", Value = 2700 });
            }
            else
            {
                itm.AVG = 2532;
                itm.Name = "HR";
                itm.DataPoints = new List<NumericItemPair>();
                itm.DataPoints.Add(new NumericItemPair() { Name = "Lower decile", Value = 1167 });
                itm.DataPoints.Add(new NumericItemPair() { Name = "Median", Value = 1289 });
                itm.DataPoints.Add(new NumericItemPair() { Name = "Upper decile", Value = 1900 });
            }
            return itm;
        }
    }

Having done that we need to style our chart and assign bindings.

    ProfessionItem pit = MyDataContext.getData(cmbBranches.SelectedIndex);

    chart1.Title = "Branch: " + pit.Name;
    lblAVG.Content = pit.AVG.ToString("# ###") + " GBP ";

    LineSeries lineSeries = new LineSeries();
    //assign binding
    lineSeries.SetBinding(LineSeries.ItemsSourceProperty, new Binding());
    lineSeries.DependentValueBinding = new Binding("Value");
    lineSeries.IndependentValueBinding = new Binding("Name");

    // hide the legend 
    Style legendStyle = new Style(typeof(Legend));
    legendStyle.Setters.Add(new Setter(Legend.VisibilityProperty, Visibility.Collapsed));
    legendStyle.Setters.Add(new Setter(Legend.WidthProperty, 0));
    legendStyle.Setters.Add(new Setter(Legend.HeightProperty, 0));
    chart1.LegendStyle = legendStyle;

    Style titleStyle = new Style(typeof(Title));
    titleStyle.Setters.Add(new Setter(Title.ForegroundProperty, "#0004BD"));
    titleStyle.Setters.Add(new Setter(Title.FontSizeProperty, 12));
    titleStyle.Setters.Add(new Setter(Title.FontWeightProperty, "bold"));
    titleStyle.Setters.Add(new Setter(Title.HorizontalAlignmentProperty, "left"));
    chart1.TitleStyle = titleStyle;

    // hide the line series data points 
    Style datapointStyle = new Style(typeof(DataPoint));
    datapointStyle.Setters.Add(new Setter(DataPoint.VisibilityProperty, Visibility.Visible));
    datapointStyle.Setters.Add(new Setter(DataPoint.WidthProperty, 10));
    datapointStyle.Setters.Add(new Setter(DataPoint.HeightProperty, 10));
    datapointStyle.Setters.Add(new Setter(DataPoint.DependentValueStringFormatProperty, "{0:# ###} GBP"));

    lineSeries.DataPointStyle = datapointStyle;

    chart1.Series.Add(lineSeries);
    chart1.DataContext = pit.DataPoints;

Next we need to set up our xaml file to position elements within our component. We can do it manually or using Visual Studio design editor.

    <toolkit:Chart HorizontalAlignment="Left" Margin="15,0,0,346" Name="chart1"  Title="" VerticalAlignment="Bottom" Width="480" Height="370" UseLayoutRounding="True" BorderThickness="0" FontSize="11" Grid.ColumnSpan="2" Padding="10" Grid.RowSpan="2">
            <toolkit:Chart.LegendStyle >
                <Style TargetType="toolkit:Legend">
                    <Setter Property="Visibility" Value="Collapsed"/>
                </Style>
            </toolkit:Chart.LegendStyle>
            
            <!--Set X-Axis Format-->
            <toolkit:Chart.Axes>
                <toolkit:LinearAxis Orientation="Y" ShowGridLines="True" Title="Salary [GBP]" >
                    <toolkit:LinearAxis.AxisLabelStyle>
                        <Style TargetType="toolkit:AxisLabel">
                            <Setter Property="StringFormat" Value="{}{0:# ###} GBP"/>
                        </Style>
                    </toolkit:LinearAxis.AxisLabelStyle>
                </toolkit:LinearAxis>

                <toolkit:LinearAxis Orientation="X" ShowGridLines="False" Title="Salary range [%]" >
                    <toolkit:LinearAxis.AxisLabelStyle>
                        <Style TargetType="toolkit:AxisLabel">
                            <Setter Property="StringFormat" Value="{}{0:0%}"/>
                        </Style>
                    </toolkit:LinearAxis.AxisLabelStyle>
                </toolkit:LinearAxis>
            </toolkit:Chart.Axes>
        </toolkit:Chart>

After that we can test our application. I have included working example below. Happy coding 🙂

Silverlight-component

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...Loading...

Database driven rotating image gallery with jQuery

When building database driven websites sometimes there is a need to display image gallery based on pictures stored in database. Good solution for that is to combine jQuery scripts with asp.net controls. Today I will show you how to build simple database driven gallery with auto rotating pictures.

picture-gallery

In our example the pictures will be stored in application folder, we will only get picture urls from db.

Let’s start with creating simple asp.net website with the default.aspx page. Next we will create Photos class and bind it to the asp.net data list view control.

 public partial class gallery_Default : System.Web.UI.Page
 {
    public List<Photo> Photos = new List<Photo>();// our data source
    //our custom picture class
    public class Photo
    {
        public string Name { get; set; }
        public string Path { get; set; }
        public bool IsDefault { get; set; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            //get it from database
            Photos.Add(new Photo() { IsDefault = true, Name = "photo1", Path = "~/images/1.jpg" });
            Photos.Add(new Photo() { Name = "photo2", Path = "~/images/2.jpg" });
            Photos.Add(new Photo() { Name = "photo3", Path = "~/images/3.jpg" });
            Photos.Add(new Photo() { Name = "photo4", Path = "~/images/4.jpg" });
            Photos.Add(new Photo() { Name = "photo5", Path = "~/images/5.jpg" });
            Photos.Add(new Photo() { Name = "photo6", Path = "~/images/6.jpg" });
            /////////////

            gridList.DataSource = Photos;
            gridList.DataBind();
        }
    }
 }

In the page markup we create following structure

  <div class="gallery">
        <div class="thumb-image-frame">
            <span class="thumb-image-wrapper">
                <img id='thumb-large-image' alt="" />
            </span>
        </div>
        <div class="list">
            <asp:ListView runat="server" ID="gridList">
                <LayoutTemplate>
                    <ul class="thumb-list">
                        <asp:PlaceHolder runat="server" ID="itemPlaceHolder" />
                    </ul>
                </LayoutTemplate>
                <ItemTemplate>
                    <li>
                        <a class="thumb-link">
                            <img class="thumb-image" src='<%# ResolveUrl(Eval("Path").ToString()) %>' alt="" title='<%# Eval("Name") %>' />
                        </a>
                    </li>
                </ItemTemplate>
            </asp:ListView>
        </div>
    </div>

Next we need to create jQuery script that will run when page loads. In our example, slides start to rotate with the 5 seconds intervals. Rotating stops when user’s cursor enters the thumbnail area and resumes on mouseleave event. You can configure below script to suit your needs.

 var run = true; //init state rotate or not
 var rotateDelay = 5000; //in milliseconds
 /////////
 var all = 0;
 var c = 1;

$(document).ready(function () {
    $("a.thumb-link").click(thumbClicked);
    $("ul.thumb-list").children("li").first().find("a.thumb-link").click();

    // rotate calls
    $("ul.thumb-list").mouseenter(stopRotate).mouseleave(startRotate); //stop/start rotating on mouse enter/ leave (thumb list)
    all = $("ul.thumb-list").children("li").length; //get total images count

    if (all > 1) { setInterval('Rotate()', rotateDelay); } //if more than one picture start rotating
});

function thumbClicked() {
    var imageSource = $(this).find("img.thumb-image").attr("src");
    $("#thumb-large-image").fadeOut("fast", function () {
        $("#thumb-large-image").attr("src", imageSource);// switch the picture
        $("#thumb-large-image").fadeIn("fast");
    });

    $("ul.thumb-list").children("li").removeClass("selected");
    $(this).parent("li").addClass("selected");//select current thumb
}

function stopRotate() { run = false; }

function startRotate() { run = true; }

function Rotate() {
    if (!run) { return; }//return if turned off
    if (c >= all) { c = 0; } //reset if last picture

    var cnt = 0;
    $("ul.thumb-list").children("li").each(function () {
        if (cnt == c) {
            var el = $(this);
            el.find("a.thumb-link").click();
        }
        cnt = cnt + 1;
    });

    c = c + 1;
 };

At the end we only need to set some css styles for the gallery and we are ready to test it.

 ul.thumb-list { width: 400px; padding:0px; }
 ul.thumb-list li { display:inline-block;  }
 ul.thumb-list li a.thumb-link { display: inline-block; cursor: pointer; }
 ul.thumb-list li a.thumb-link img.thumb-image { width: 110px; height: 90px; padding: 7px; border: 2px  solid white;border-radius: 8px; }
 ul.thumb-list li.selected a.thumb-link img.thumb-image { border-color: #df7777;}
 .thumb-image-frame { width: 400px; min-width: 400px; height: 300px; min-height: 300px; text-align: center; margin-bottom: 10px; }
 .thumb-image-wrapper { line-height: 300px; }
 #thumb-large-image { height: 300px; min-height: 300px; width: 400px; min-width: 400px; vertical-align: middle;border-radius: 8px;}

As you can see creating custom image gallery is quite easy to do using jQuery and asp.net. You can of course create variety of additional functions to it e.g. animations when switching the pictures, custom play and pause menu etc.

I have included working example below. Feel free to adjust it to your needs.

jquery-gallery

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...Loading...

Finding the distance between two addresses using Google API

There are number of cases when you will need to calculate the distance between two addresses in your application. For example when building an social website or CRM solution. Calculating the distance between the addresses has never been so easy thanks to Google geolocation API. The API is available for free but it has the limit of 2500 requests per day, you can always buy the business version if your service gets more popular.

geolocation

Lets start with building the empty asp.net website. After creating basic UI controls we can implement the back end of our application. We will use Json serialization when getting response from API so we need to prepare serialization function and geolocation response class.

 public static T FromJSON<T>(string json)
 {
     JavaScriptSerializer jss = new JavaScriptSerializer();

     return jss.Deserialize<T>(json);
  }

We will use data contracts to deserialize Json response to our class

 [DataContract(Namespace = "")]
 public class GeocodeResponse
 {
    [DataMember(Name = "status", Order = 1)]
    public string Status { get; set; }

    [DataMember(Name = "result", Order = 2)]
    public List<Result> Results { get; set; }

    [DataContract(Name = "result", Namespace = "")]
    public class Result
    {
        [DataMember(Name = "geometry")]
        public CGeometry Geometry { get; set; }

        [DataContract(Name = "geometry", Namespace = "")]
        public class CGeometry
        {
            [DataMember(Name = "location")]
            public CLocation Location { get; set; }

            [DataContract(Name = "location", Namespace = "")]
            public class CLocation
            {
                [DataMember(Name = "lat", Order = 1)]
                public double Lat { get; set; }
                [DataMember(Name = "lng", Order = 2)]
                public double Lng { get; set; }
            }
        }
    }
 }

To get Json object from API we need to send request and read response from it.

 public static string WebRequestJson(string url)
 {
    var response = string.Empty;

    StreamWriter requestWriter;

    var webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
    if (webRequest != null)
    {
        webRequest.Method = "POST";
        webRequest.ServicePoint.Expect100Continue = false;
        webRequest.Timeout = 99000;

        webRequest.ContentType = "application/json";
        //POST the data.
        using (requestWriter = new StreamWriter(webRequest.GetRequestStream()))
        {
            requestWriter.Write("");
        }
    }

    HttpWebResponse resp = (HttpWebResponse)webRequest.GetResponse();
    using (Stream resStream = resp.GetResponseStream())
    {
        using (StreamReader reader = new StreamReader(resStream))
        {
            response = reader.ReadToEnd();
        }
    }

    return response;
 }

In our main function we are getting Json objects from API by making request to Google and passing address in request URL. Having Json objects for each address we deserialize it to our GeocodeResponse class. In this step we can check response if it is valid or contains only one location for one provided address.

 public static double GetDistance(string address1, string address2, DistanceUnit unit)
 {
    //make jason requests to google api
    string json1 = WebRequestJson(
        string.Format("https://maps.googleapis.com/maps/api/geocode/json?address={0}&sensor=false", address1)
        );
    string json2 = WebRequestJson(
        string.Format("https://maps.googleapis.com/maps/api/geocode/json?address={0}&sensor=false", address2)
        );

    //deserialize json to GeocodeResponse object
    var loc1 = FromJSON<GeocodeResponse>(json1);
    var loc2 = FromJSON<GeocodeResponse>(json2);

    //check is response is ok
    if (loc1.Status != "OK" || loc2.Status != "OK") { return -1; }

    //check if only one location found for each address
    //if (loc1.Results.Count > 1 || loc2.Results.Count > 1) { return -2; }

    //copy coordinate values
    var pos1 = new Coordinate()
    {
        Latitude = loc1.Results.First().Geometry.Location.Lat,
        Longitude = loc1.Results.First().Geometry.Location.Lng
    };
    var pos2 = new Coordinate()
    {
        Latitude = loc2.Results.First().Geometry.Location.Lat,
        Longitude = loc2.Results.First().Geometry.Location.Lng
    };

    //return distance in unit
    return CalculateDistance(pos1, pos2, unit);
}

When we have the final coordinates (latitude and longitude) for each address, we can now calculate the distance in the specified unit. We take the earth’s radius into account- the rest it’s just the pure mathematics.

  public static double CalculateDistance(Coordinate pos1, Coordinate pos2, DistanceUnit unit)
    {
        var R = 6371;//default in km

        switch (unit)
        {
            case DistanceUnit.Miles:
                R = 3960; break;
            case DistanceUnit.Kilometers:
                R = 6371; break;
            case DistanceUnit.Meters:
                R = 6371000; break;
        }

        //get location difference and convert to radians
        var dLat = DegreeToRadian(pos2.Latitude - pos1.Latitude);
        var dLon = DegreeToRadian(pos2.Longitude - pos1.Longitude);

        //calculate distance
        var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
            Math.Cos(DegreeToRadian(pos1.Latitude)) *
            Math.Cos(DegreeToRadian(pos2.Latitude)) *
            Math.Sin(dLon / 2) * Math.Sin(dLon / 2);

        var c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));

        var d = R * c;//convert to unit

        return d;
    }

When we have all implementation done, we can finally test our application. I have included complete working application for your tests.

Geolocation

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...Loading...

OpenXML Word templates processing

Office Open XML it’s the Microsoft’s zipped-xml based standard for processing Office documents. It allows to create, amend and process MS office files using e.g. .Net platform. In this article I will show you how to replace Word template with text and images using C# based application.

After creating new project we need to add two main references: DocumentFormat.OpenXml from DocumentFormat.OpenXml.dll and WindowsBase (.Net reference). Next, we need to prepare template with placeholders that our application will replace. For texts we will insert placeholder values in the the unique format that we can find parsing the document e.g. [#Project-Name#].

For the images we need to insert image placeholders (other images) and just remember their original names (e.g. myPicture2.jpg). This names needs to be provided in the parameter objects so we can find the placeholders by image name when parsing document.

word-template-300x184

The next step is to create parameters structure that we will use when processing the document. You may want to create your own parameters depending or your requirements.

  public class WordParameter
    {
        public string Name { get; set; }
        public string Text { get; set; }
        public FileInfo Image { get; set; }
    }

We will use them as follows when initiating the objects

    var templ = new WordTemplate();
    //add parameters
    templ.WordParameters.Add(new WordParameter() { Name = "[#Project-Name#]", Text = "Test project 123" });
    templ.WordParameters.Add(new WordParameter() { Name = "[#Features (string[])#]", Text = "Lorem Ipsum is simply dummy text of the printing \n Lorem Ipsum is simply dummy text of the printing \n Lorem Ipsum is simply dummy text of the printing..." });

    //original image names to be replaced with the new ones
    templ.WordParameters.Add(new WordParameter() { Name = "1.jpg", Image = new FileInfo(WordTemplate.GetRootPath() + @"\Images\1.jpg") });
    templ.WordParameters.Add(new WordParameter() { Name = "2.jpg", Image = new FileInfo(WordTemplate.GetRootPath() + @"\Images\2.jpg") });
    templ.WordParameters.Add(new WordParameter() { Name = "3.jpg", Image = new FileInfo(WordTemplate.GetRootPath() + @"\Images\3.jpg") });
    templ.WordParameters.Add(new WordParameter() { Name = "4.jpg", Image = new FileInfo(WordTemplate.GetRootPath() + @"\Images\4.jpg") });
    templ.WordParameters.Add(new WordParameter() { Name = "5.jpg", Image = new FileInfo(WordTemplate.GetRootPath() + @"\Images\5.jpg") });

    templ.ParseTemplate(); //create document from template

Having done that we can create our main function that parses the template and fills our placeholders with texts and images. Please see the inline comments within the function below.

 public void ParseTemplate()
 {
    using (var templateFile = File.Open(templatePath, FileMode.Open, FileAccess.Read)) //read our template
    {
        using (var stream = new MemoryStream())
        {
            templateFile.CopyTo(stream); //copy template

            using (var wordDoc = WordprocessingDocument.Open(stream, true)) //open word document
            {
                foreach (var paragraph in wordDoc.MainDocumentPart.Document.Descendants<Paragraph>().ToList()) //loop through all paragraphs 
                {
                    ReplaceImages(wordDoc, paragraph); //replace images

                    ReplaceText(paragraph); //replace text
                }

                wordDoc.MainDocumentPart.Document.Save(); //save document changes we've made
            }
            stream.Seek(0, SeekOrigin.Begin);//scroll to stream start point

            //save file or overwrite it
            var outPath = WordTemplate.GetRootPath() + @"\Output\DocumentOutput.docx";

            using (var fileStream = File.Create(outPath))
            {
                stream.CopyTo(fileStream);
            }
        }
    }
 }

Function that replaces the images. It gets all Blip objects from the paragraph and changes it’s embed ID that points to the image.

The cool thing about it is fact that you can give your own styles and transformation to the image template and it will be preserved and applied to the new image 🙂

Please see the inline comments.

 void ReplaceImages(WordprocessingDocument wordDoc, Paragraph paragraph)
 {
    // get all images in paragraph
    var imagesToReplace = paragraph.Descendants<A.Blip>().ToList();

    if (imagesToReplace.Any())
    {
        var index = 0;//image index within paragraph

        //find all original image names in paragraph
        var paragraphImageNames = paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Pictures.NonVisualDrawingProperties>().ToList();

        //check all images in the paragraph and replace them if it matches our parameter
        foreach (var imagePlaceHolder in paragraphImageNames)
        {
            //check if we have image parameter that matches paragraph image
            foreach (var param in WordParameters)
            {
                //replace it if found by original image name
                if (param.Image != null && param.Image.Name.ToLower() == imagePlaceHolder.Name.Value.ToLower())
                {
                    var imagePart = wordDoc.MainDocumentPart.AddImagePart(ImagePartType.Jpeg); //add image to document
                    using (FileStream imgStream = new FileStream(param.Image.FullName, FileMode.Open))
                    {
                        imagePart.FeedData(imgStream); //feed it with data
                    }

                    var relID = wordDoc.MainDocumentPart.GetIdOfPart(imagePart); // get relationship ID

                    imagesToReplace.Skip(index).First().Embed = relID; //assign new relID, skip if this is another image in one paragraph
                }
            }
            index += 1;
        }
    }
}

When replacing the texts we check if paragraph contains the text that matches our parameter. If yes, then we check if to include one or multiple lines of text.
Next we create new parameter by copying the old parameter’s OuterXML (this preserves the styles). We also need to replace text that is stored in our parameter.

 void ReplaceText(Paragraph paragraph)
 {
    var parent = paragraph.Parent; //get parent element - to be used when removing placeholder
    var dataParam = new WordParameter();

    if (ContainsParam(paragraph, ref dataParam)) //check if paragraph is on our parameter list
    {
        //insert text list
        if (dataParam.Name.Contains("string[]")) //check if param is a list
        {
            var arrayText = dataParam.Text.Split(Environment.NewLine.ToCharArray()); //in our case we split it into lines

            if (arrayText is IEnumerable) //enumerate if we can
            {
                foreach (var itemData in arrayText)
                {
                    Paragraph bullet = CloneParaGraphWithStyles(paragraph, dataParam.Name, itemData);// create new param - preserve styles
                    parent.InsertBefore(bullet, paragraph); //insert new element
                }
            }
            paragraph.Remove();//delete placeholder
        }
        else
        {
            //insert text line
            var param = CloneParaGraphWithStyles(paragraph, dataParam.Name, dataParam.Text); // create new param - preserve styles
            parent.InsertBefore(param, paragraph);//insert new element

            paragraph.Remove();//delete placeholder
        }
    }
}

Creating the new paragraph object preserving the styles

 public static Paragraph CloneParaGraphWithStyles(Paragraph sourceParagraph, string paramKey, string text)
 {
    var xmlSource = sourceParagraph.OuterXml;

    xmlSource = xmlSource.Replace(paramKey.Trim(), text.Trim());

    return new Paragraph(xmlSource);
 }

Please note that when replacing images, the image placeholder names must be found in the document. Images that don’t match the parameter name, wont be replaced.

Having done that we can finally test our application. I have included complete working application for your tests.
WordTemplates

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...Loading...

Finding non empty data periods T-SQL

Ever wanted to find non empty periods of data using T-SQL? I this article I will show you how to do it.
Example below shows the periods of days in which there have been at least one order. The days without orders are not being shown. This is very useful when creating advanced sales reports. Having non empty periods we can calculate additional values such as average sales in these ranges etc.

The code below simply gets all distinct dates then creates two partitions and joins them together.
In each partition the data are joined with each other using left and right join. The non null values are next being used in the final inner join.

 with temp(d) as 
 ( 
  select distinct CONVERT(date,OrderDate) d from tblOrders
 )
 select a1.id as id, a1.d as [from], a2.d as [to] from 
 ( 
   select b.d, ROW_NUMBER() over (partition by 1 order by b.d) id from temp a 
   right join temp b on dateadd(day,1,a.d) = b.d 
   where a.d is null 
 )
 a1 
 inner join  
 ( 
   select a.d, ROW_NUMBER() over (partition by 1 order by b.d) id from temp a 
   left join temp b on dateadd(day,1,a.d) = b.d 
   where b.d is null 
 ) 
 a2 on a1.id = a2.id 

sql-periods1

In order to calculate sales data in periods, simply join the final results using found dates. Hope I helped you with this sample. Happy coding 🙂

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...Loading...

SHA1 and MD5 hashing algorithms

When storing passwords in database, it is considered a good practice to hash them first. The most common way to do that is to use MD5 or SHA hashing algorithms. Hashing passwords is more secure because after creating a hash from the user’s password theoretically there is not way to get the password back from it. In reality MD5 is more vulnerable to “collision attacks” as it uses 128 bit value while SHA1 uses 160 bits which makes it harder to crack.

The disadvantage of hashing passwords is the fact that if an users forgets his password, we cannot send him a reminder. We will have to reset it first.

Theoretically if someone will steal our database, it is possible to use bruit force attack to find the original passwords by trying different combinations of words and numbers. To prevent that we can add our custom string to the user’s string before hashing. This makes it more difficult to crack the passwords having only database without our application files where the custom string is being stored.

 class Program
    {
        static void Main(string[] args)
        {
            string md5 = CreateMD5Hash("test");
            //result: CY9rzUYh03PK3k6DJie09g==

            string sha1 = CreateSHA1Hash("test");
            //result: qUqP5cyxm6YcTAhz05Hph5gvu9M
        }

        /// <summary>
        /// Creates MD5 hash of text
        /// </summary>
        public static string CreateMD5Hash(string clearText)
        {
            return Convert.ToBase64String(MD5.Create().ComputeHash(UnicodeEncoding.UTF8.GetBytes(clearText)));
        }

        /// <summary>
        /// Creates SHA1 hash of text
        /// </summary>
        public static string CreateSHA1Hash(string clearText)
        {
            return Convert.ToBase64String(SHA1.Create().ComputeHash(UnicodeEncoding.UTF8.GetBytes(clearText))).TrimEnd('=');
        }
    }

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...Loading...

Adaptive Payments with PayPal

When building B2C systems the common scenario is to share the profits among the portal and the business users eg. when renting a house through you website the user pays total amount for the house, lets say 100 USD to the property owner. From that amount the owner will pay share commission to the portal’s website usually a small %.

In order to automate this process we can use PayPal Adaptive payments (chained transaction). The main difference between PayPal chain transaction and parallel transaction is that with the chained transaction the user sees only the total amount that he owns to the house owner. With the parallel transactions the user pays total amount but he sees the list of 2 receivers; the house owner and the portal owner share details.

Although there is a good documentation available on the Paypal website I found it very hard to get a working example of the payment implementation. That’s why I decided to post it here.

Lets start with downloading PayPal SDK. It contains all classes we need to make payment request. I have also included project and SDK at the bottom of this article.

When making a payment request we basically need to create paykey and redirect user to the payment page by passing that key as a parameter.
This simply creates initial payment record on PayPal account. The payment then may be finished or cancelled by the user. We get the paykey after getting response from PayPal with the status “CREATED”.

  if (ap.isSuccess.ToUpper() != "FAILURE")
  {
      if (PResponse.paymentExecStatus == "CREATED")
      {
          return PResponse.payKey;
      }
   }

In the init request we need to include basic parameters such as portal and property owner PayPal accounts, api credentials (sandbox account for testing)

    var OrderID = Guid.NewGuid().ToString();

    var portalPayPalEmail = ConfigurationManager.AppSettings["PORTAL_PAYPAL_EMAIL"];
    payRequest.ipnNotificationUrl = ConfigurationManager.AppSettings["PAYPAL_NOTIFICATION_URL"] + "?custom=" + OrderID; // to be processed later in PayPal-Call-back.ashx handler

    payRequest.cancelUrl = Request.Url.ToString();
    payRequest.returnUrl = Request.Url.ToString();
    payRequest.memo = OrderID;
    payRequest.trackingId = OrderID;

    payRequest.clientDetails = new ClientDetailsType();
    payRequest.clientDetails = ClientInfoUtil.getMyAppDetails();  //helper - gets values from web.config
    payRequest.actionType = "PAY"; // or CREATE
    payRequest.currencyCode = "USD";//set currency to user settings
    payRequest.requestEnvelope = new RequestEnvelope();
    payRequest.requestEnvelope = ClientInfoUtil.getMyAppRequestEnvelope(); //helper - gets values from web.config

This is how the config file should look like (please fill in with your data)

 <appSettings>
    <!-- PayPal configuration settings START-->
    <add key="deviceId" value="testID123"/>
    <add key="ipAddress" value="127.0.0.1"/>
    <add key="TrustAll" value="true"/>
    <add key="ENDPOINT" value="https://svcs.sandbox.paypal.com/"/>
    <add key="PAYPAL_URL" value="https://www.sandbox.paypal.com/"/>
    <add key="PAYPAL_REDIRECT_URL" value="https://www.sandbox.paypal.com/webscr?cmd=_ap-payment&amp;paykey="/>
    <add key="PAYPAL_NOTIFICATION_URL" value="https://your-website-url/PayPal-Call-back.ashx"/>
    <add key="APPLICATION-ID" value="APP-80W284485P5195333"/>
    <add key="API_REQUESTFORMAT" value="SOAP11"/>
    <add key="API_RESPONSEFORMAT" value="SOAP11"/>
    <add key="API_AUTHENTICATION_MODE" value="3TOKEN"/>
    <add key="PORTAL_PAYPAL_EMAIL" value="portal-paypal-email"/>
    <add key="API_USERNAME" value="api-username"/>
    <add key="API_PASSWORD" value="api-password"/>
    <add key="API_SIGNATURE" value="api-signature eg.AFcWxV21C7fd0v3bYYYRCpSSRl31AI0QDNGia62b0stzcLxkJCYRE9JE"/>
    <!-- PayPal configuration settings END-->
  </appSettings>

Next we need to define who will pay the PayPal commission, it can be one of the receivers or sender or all can be paying equally

 payRequest.feesPayer = "EACHRECEIVER"; //SENDER,PRIMARYRECEIVER,SECONDARYONLY

Next step is to create receiver list. It can include up to 6 accounts. In our case we have only portal user and the property owner. The total amount of 100 USD will be split to 80 USD for the property owner and 20 USD for portal (minus PayPal commission taken from both receivers)

    payRequest.receiverList = new Receiver[2];
    //pay the user
    payRequest.receiverList[0] = new Receiver();
    payRequest.receiverList[0].amount = 100;
    payRequest.receiverList[0].primary = IsChainedTransaction;// set to true to switch to chained transaction
    payRequest.receiverList[0].primarySpecified = IsChainedTransaction;// set to true to switch to chained transaction
    payRequest.receiverList[0].paymentType = "SERVICE";
    payRequest.receiverList[0].email = "portal-user-paypal-email";//set user paypal email

    //pay portal share
    payRequest.receiverList[1] = new Receiver();
    payRequest.receiverList[1].amount = 20;
    payRequest.receiverList[1].primary = false;
    payRequest.receiverList[1].primarySpecified = false;
    payRequest.receiverList[1].paymentType = "SERVICE";
    payRequest.receiverList[1].email = portalPayPalEmail;

At the end we need to supply credentials and send payment request.

 AdapativePayments ap = new AdapativePayments();
 ap.APIProfile = ClientInfoUtil.CreateProfile(); //helper - gets values from web.config

 PayResponse PResponse = ap.pay(payRequest);

The last step is to check if payment was successful and process the order in our application. In the web.config we defined PAYPAL_NOTIFICATION_URL as handler page PayPal-Call-back.ashx. So in the handler when we receive an callback we simply validate it by sending back request to PayPal. When the request is validated we can proceed with our order.

 public void ProcessRequest(HttpContext context)
 {
    Request = context.Request;

	//Request["custom"] contains our orderID
    if (IsRequestFromPaypal() && Request["custom"] != null)
    {
        var orderID = Request["custom"];
            
        //check the payment_status is Completed
        //check that orderID has not been previously processed
        //check that receiver_email is your Primary PayPal email
        //check that payment_amount/payment_currency are correct
        //process payment
    }
  }

   //validate request by sending it back to PayPal
   bool IsRequestFromPaypal()
   {
        var validationRequestContent = Request.Form + "&cmd=_notify-validate";
        var validationUrl = System.Configuration.ConfigurationManager.AppSettings["PAYPAL_URL"].TrimEnd('/') + "/cgi-bin/webscr";

        // Create a Web Request:
        var validationRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(validationUrl);
        validationRequest.ContentLength = validationRequestContent.Length;
        validationRequest.ContentType = "application/x-www-form-urlencoded";
        validationRequest.Method = "POST";

        using (var writer = new StreamWriter(validationRequest.GetRequestStream(), System.Text.Encoding.ASCII))
        {
            writer.Write(validationRequestContent);
        }

        // Now send the request and get the response:
        using (var response = validationRequest.GetResponse())
        {
            using (var reader = new StreamReader(response.GetResponseStream()))
            {
                var paypalResponse = reader.ReadToEnd();
                return paypalResponse == "VERIFIED";
            }
        }
    }

I have included working example below so you can use it in your testing. Just fill it in with your data. You also need to be logged in to your sandbox account when testing it.
AdaptivePayments

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...Loading...

Custom code validator using RichTextBox

Knowing how to format text using RichTextBox control lets you build wide range of tools such as code comparers, validators, chat applications etc. In this article I will show you how to build simple code checker/ validator.

code-checker

We start with creating new win form application and class library that we will read our test methods from. We will then compare these functions to our pattern methods.

Lets create some dummy methods now.

 public class TestClass
 {
        /// <summary>
        /// Test summary1
        /// this is dummy method
        /// </summary>
        public static void Test1()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Test summary2
        /// this is dummy method
        /// </summary>
        public static void Test2()
        {
            var test = new List<string>();
            test.Add("test1");
            test.Clear();
        }

        /// <summary>
        /// Test summary3
        /// this is dummy method
        /// </summary>
        public static void Test3()
        {
            var test = new List<string>();
            test.Add("test1");
            test.Add("test2");
            test.Add("test3");
            test.Add("test4 123456789");
            test.Add("test5");
            test.Add("test6");
            test.Clear();
        }
    }

Next, we will read this methods using reflection and then we bind it to the listbox control.

  var testTypes = typeof(TestClass).Assembly.GetTypes()
                   .Where(t => t.Name.StartsWith("Test")).OrderBy(t => t.Name).ToList();

  var testMethods = testTypes.First().GetMethods().Where(m => m.IsPublic && m.IsStatic).ToArray();

   lstTests.Items.AddRange(testMethods.ToArray());
   lstTests.SelectedIndex = 0;

When reading the summary tags we will use function that will parse text in .cs file in a search of summary tags.

  internal static string GetComment(string file, string methodName)
   {
            var commentContent = string.Empty;
            var buffer = string.Empty;

            foreach (var line in File.ReadAllLines(file))
            {
                buffer += line;

                if (line.ToLower().Contains(methodName.ToLower()))
                {
                    var summaryPositionStart = buffer.LastIndexOf("<summary>", StringComparison.OrdinalIgnoreCase);
                    var summaryPositionEnd = buffer.LastIndexOf("</summary>", StringComparison.OrdinalIgnoreCase);
                    if (buffer.Length <= summaryPositionStart || summaryPositionEnd - summaryPositionStart <= 0) { return ""; }

                    return PrepareSummaryString(buffer.Substring(summaryPositionStart, summaryPositionEnd - summaryPositionStart));
                }
            }

      return "";
   }

The final step is to format RichTextBox line by line giving it appropriate color depending on our requirements.

  public static void InsertColorText(string inString, RichTextBox textbox, Color methodColor)
   {
            textbox.Text = "";
            inString = inString.TrimEnd(' ', '\r', '\n');

            var lines = inString.Split('\n');
            var font = new Font("Courier New", 8f, FontStyle.Regular);

            for (var i = 0; i < lines.Length; i++)
            {
                textbox.SelectionFont = font;
                textbox.SelectionColor = methodColor;

                if (i < 2 || i + 1 >= lines.Length)
                {
                    textbox.SelectionColor = Color.Gray;
                    textbox.SelectedText = TrimLeft(lines[i], 2);
                    continue;
                }

                if (lines[i].Contains("throw new NotImplementedException();"))
                {
                    textbox.SelectionColor = Color.Red;
                    textbox.SelectedText = TrimLeft(lines[i], 4);
                    continue;
                }

                //calculate color for the current line
                if (lines[i].Trim().Length > 20)
                {
                    textbox.SelectionColor = Color.Blue;
                    textbox.SelectedText = TrimLeft(lines[i], 4);
                    continue;
                }

                textbox.SelectedText = TrimLeft(lines[i], 4);
            }
            textbox.SelectedText = "\n";
        }
    }

Whatever you want to build, this example shows you basic RichTextBox formatting implementation you can use in your solution. I have included working example below for your testing.
RichTextBox-Formatting

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...Loading...