Wednesday, April 3, 2013

Building an eCommerce Site with NopCommerce


Below is a blog entry I wrote for Bayshore Solutions in March, 2013. It contains information about my experience implementing NopCommerce. Hopefully some of the contents provide valuable information for somebody else. Enjoy!

Not long ago, an online store was seen as a means of adding presence to traditional brick-and-mortar stores. According to the National Retail Federation, online shopping makes up to 40% of retail purchases for an average person these days.

Clearly the convenience of eCommerce has been embraced by consumers and the trend is unlikely to change, therefore many retailers are reinventing their business in order to make their products available on the web.

Bayshore Solutions has worked with many retailers to support their eCommerce efforts by building state of the art sites that help businesses expose their products in ways never seen before.
Although there are plenty of tools available to create an on-line store, one of the most common tools used by Bayshore Solutions to develop a custom eCommerce store is NopCommerce.


NopCommerce is an open source shopping cart designed and developed by a group of entrepreneurs from many different countries using state of the art technology; this has transformed NopCommerce into one of the preferred solutions for developing eCommerce sites under the .NET Platform.

NopCommerce offers a quick and effective way to get a store started; installation is a breeze thanks to their web install. NopCommerce has a wealth of features and capabilities out of the box. Below is a summary of some key features:

  • Unlimited Number of products on the catalog
  • Support for categories, subcategories and manufacturers
  • Product Attributes
  • Management of Stock by Attribute
  • Ability to manage discounts by role
  • Tier pricing
  • Customer can enter price
  • Support for downloadable products
  • Anonymous checkout
  • Open ID, Facebook and Twitter Authentication
  • One page checkout
  • Multilingual/Internationalization
  • Multiple Shipment methods and shipment amount calculations
  • Free shipping over $X amount
  • Support for multiple payment methods
  • Extensible interface that allows creating custom plug ins
  • Sales dashboard
  • Import/Export of basic data
  • PDF Invoicing
  • Source code is provided for the entire product. The source code is well organized, documented and it is possible to extend it and modify it to accomplish any task imaginable.

A detailed list of features can be found at: http://www.nopcommerce.com/featurelist.aspx

Despite the fact that NopCommerce offers a great amount of features and functionality, there are multiple challenges to overcome when building an eCommerce site using this tool. Some of the common challenges faced when building a custom NopCommerce site are listed below:

  • Design integration, although the system includes the ability to incorporate new themes; it is always challenging to incorporate layouts that modify the default. Adding custom styles to NopCommerce native controls is not simple; this usually requires a developer in conjunction with a graphic designer.
  • Importing product and attribute data could be complicated when interfacing disconnected systems, for example trying to feed a catalog of existing products from an ERP system to NopCommerce will require a customization in most cases. Assuming that the source of the data will be the ERP system it will be necessary to create a scheduled task that will load the products once or multiple times a day by using an external CSV file or a web feed.
  • Implementing complex shipping, taxes or payment methods could be challenging. Although the framework includes a myriad of shipping, taxes and payment options, customized business rules are difficult to implement. For example taxes can be calculated based on a zip code and percentage, however if the business requires to set a threshold before applying taxes, then a customization to an existing tax calculation plug-ins would have to performed. Consider the following scenario: Charge taxes by zip code but only apply taxes to purchases over $500, although the first part of the requirement is met out of the box, there is no way to set a rule to only charge taxes for purchases over $500.
  • Heavy content sites: Although NopCommerce includes a feature that allows the user to create content and display it, it is not meant to be used on a heavy content site that involves pages, subpages and dynamic navigation. Since the main purpose of NopCommerce is to build a store, content can be included but within its limits. Bayshore Solutions usually approaches this issue by building a content site, with a store domain. Both sites have the same look and feel but when the user clicks on any feature that requires displaying inventory, they are taken to the NopCommerce store.
  • Additional data fields. Because of the number of features in NopCommerce, a common request is the need is to store additional information linked to existing NopCommerce entities in order  to better match the business need being addressed by the site; for example add additional customer information such as: phone numbers, addresses, comments or business related information. Although it would be tempting to add these extra pieces of data to existing NopCommerce entities, it is often easier to create separate objects and layers to hold and manage this data and link them to the default entities; this will allow to better maintain the site and to facilitate a possible future upgrade.



Monday, March 11, 2013

Creating a Generic List of Anonymous Types using Casting by Example

Consider the following scenario. You have two lists of data which are the result of separate queries. The select in the queries is identical and you want to merge the lists into a generic anonymous list to display the results in a control.

The code below receives a pipe delimited string, the string contains keywords. The code loops the string array and executes two separate queries against separate fields (coded this way for the purpose of this example) the biggest obstacle would be how to combine the results of the queries into a single list.

In order to merge the lists into one, it is possible to use a technique called Casting by Example, by creating an anonymous type that matches the intended select, it will be possible to cast this type into an array and then into a list. See below:

var result = new {Id = 1, CriteriaId = 0, MarketName = string.Empty};
var results = (new[] {result}).ToList();
Here is the complete code for your review:
var keywords = p.Split('|');
if (keywords.Length == 0)
    return;
           
var result = new {Id = 1, CriteriaId = 0, MarketName = string.Empty};
var results = (new[] {result}).ToList();
                
using (var ctxt = new MarketSearchDataContext())
{                
  foreach (var keyword in keywords)
  {
   var nameResults = ctxt.Markets.Where(m => m.MarketName.ToLower()
       .Contains(keyword.ToLower().Trim()))
       .Select(m => new {Id = m.Id, CriteriaId = 0, MarketName = m.MarketName})
       .ToList();

   var detailResults = ctxt.Markets.Where(m => m.HTML
       .Contains(keyword.ToLower().Trim()))
       .Select(m => new { Id = m.Id, CriteriaId = 0, MarketName = m.MarketName })
       .ToList();
   if (nameResults.Count > 0)
       results.AddRange(nameResults);

   if (detailResults.Count > 0)
        results.AddRange(detailResults);
}

//Raw results from the list - Duplicates will exist
results.RemoveAt(0); //Cast by Example row
var cleanResults = results.Distinct();

BindResultsGrid(cleanResults);

Monday, August 6, 2012

Web Browsing with Windows 8 and IE10


Web Browsing with Windows 8  and IE10

The upcoming release of Windows 8 will ship with version 10 of Internet Explorer and feature a newly designed Operating System interface named Metro. Metro is similar to the Windows Phone interface currently used by Microsoft on smart phones. Its main goal is to improve touch screen navigation along with traditional mouse and keyboard input for an immersive web browsing experience. Metro is a tile-based interface, each tile represents an application, web page or social media feed. A metro application typically runs in full-screen mode and utilizes a new set of runtime libraries or HTML markup to construct the UI.

IE10 plays an important role in Windows 8 since it interacts with the Metro interface and can also be run in the traditional Windows Desktop view, both modes use the same rendering engine. IE10 will not support plug-ins or ActiveX components but will include a version of Adobe Flash Player that has been improved for use with a touch screen interface.

The rendering engine in IE10 contains many improvements and support for HTML5 and CSS3. Examples of the multiple rendering engine enhancements are: Touch sensitive areas on a page react based on touch or mouse navigation, the ability to adapt website layouts to any device and multiple styling enhancements such a text-shadow and built-in support for OpenType  fonts.
A preview of some of these features can be seen at http://ie.microsoft.com/testdrive/.

When IE10 starts, it runs in full screen mode, swiping the screen reveals the top navigation section which contains a  list of active websites and the footer which contains the navigation controls such the back, address bar, refresh, tools, pin and forward controls. Right click options are limited on IE10, for example there are no options to view the image source or size, holding a finger on a link will only allow to copy and paste it but additional options that exist in IE9 such as view Encoding have been removed.

In IE10 websites can be pinned. This means that the sites will be added as tiles to the desktop. An existing site, when pinned will display on the desktop as a tile using a generic color and IE logo. It is expected that sites will add additional programming to supply a customized icon and description when pinned, an alternative is to supply a metro App to wrap the site content in the same way smart phone and table Apps do. Sites that supply an App are marked with a plus sign in the footer, which allows the developers to redirect the web site to the Microsoft Store to download or purchase the corresponding App for their device. The goal is to create integrated web sites that can be used across all platforms.

Initial tests by Ziff Davis labs indicate that IE’s performance is better than Chrome and FireFox in some areas but not really fit for sites that make extensive use of JavaScript. It is expected that performance will be improved on the final version.

Conclusion: IE10 has been labeled as “the best version of Internet Explorer yet”. The interface enhancements allows the user  to fully experience the content of a website. Web designers that plan on taking full advantage of the Metro version of IE need to keep in consideration that there is no browser interface therefore the site will behave as a standalone App in the same way that is done in mobile devices such as tablets and smart phones, fortunately with support for HTML5 and CSS3 the browser should support all modern design elements. IE10 has been promised to run on Windows 7, Windows 8, Windows Server 2008 R2 and Windows Server 2012 and has been should be available in August 2012.

Monday, May 14, 2012

Implementing a JSON Feed with ASP.Net

Obtaining data from an external web site using a JSON (JavaScript Object Notation) feed is a relatively simple process.

JSON represents data structures using a JavaScript object notation which is human readable. It provides some advantages over XML because it is easier to obtain data from multilevel (nested) structures.

Below is an example of a JSON feed implementation to a service that provides quotes for precious metals at: http://drayah.no.de/metals/latest
The objective is to get the feed from the site in order to  obtain the price of Gold.

Step 1. Create a Class for JSON Feed 


You may want to use the JsonCSharp tool that helps you create a class based on the output from the feed. Check it out at  http://json2csharp.com/ 


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace JSONFeed
    {
        public class Gold
            {
            public double quote { get; set; }
            public double quoteKg { get; set; }
            }

        public class Silver
            {
            public double quote { get; set; }
            public double quoteKg { get; set; }
            }

        public class Platinum
            {
            public double quote { get; set; }
            public double quoteKg { get; set; }
            }

        public class Palladium
            {
            public double quote { get; set; }
            public double quoteKg { get; set; }
            }

        public class Metals
            {
            public Gold gold { get; set; }
            public Silver silver { get; set; }
            public Platinum platinum { get; set; }
            public Palladium palladium { get; set; }
            }

    }

Step 2. Creating a Method to invoke the Feed



using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Web.Configuration;

namespace JSONFeed
    {
    public class GetFeed
        {

        public double GoldPrice()
            {
            try
                {

                //Get Precious Metals Pricess from Drayah feed 
                //http://drayah.no.de/metals/latest

                string url = "http://drayah.no.de/metals/latest";
                WebRequest request = WebRequest.Create(url);
                WebResponse ws = request.GetResponse();

                //Used http://json2csharp.com/ to auto-generate C# Class
                //for the Json feed.
                //DataContractJsonSerializer will Serialize based on another
                //class named Metals
                DataContractJsonSerializer jsonSerializer =
                             new DataContractJsonSerializer(typeof(Metals));
                Metals _metals =
                   (Metals)jsonSerializer.ReadObject(ws.GetResponseStream());

                if (_metals.gold.quote > 0)
                    return _metals.gold.quote;
                else
                    return 0;

                }
             //Add your exception code here.
            catch (Exception ex)
                {
                return 0;
                }
            }

        }
    }


Step 3. Test Class to run and test the feed

If you believe in using Visual Studio Automated Testing Classes, use the below.


using JSONFeed;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;

namespace JSONFeed.Test
{
        
    [TestClass()]
    public class GetFeedTest
        {

        private TestContext testContextInstance;

        ///


        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///

        public TestContext TestContext
            {
            get
                {
                return testContextInstance;
                }
            set
                {
                testContextInstance = value;
                }
            }

        #endregion


        [TestMethod()]
        public void GoldPriceTest()
            {
            GetFeed target = new GetFeed();
            double actual;

            actual = target.GoldPrice();
            Assert.AreNotEqual(0, actual);
           
            }
        }
}

The GoldPrice() Method, invokes the jsonSerializer which will try to match the output of the feed with the appropriate class which in this case is the class named Metals. The data will be filled into the corresponding subclass. If the data contains multiple rows of information, it needs to be defined as a list so the serializer knows that multiple rows are affected.

Below is a screenshot of the output after it's been serialized.



Hope this helps,
Happy coding.






Wednesday, January 18, 2012

Make your voice heard!

As some of you may already know, some sites are going dark for a day.
SOPA and PIPA have the potential to affect all of those that make a living out of the internet, Google’s got a petition going and I figured that I would pass it along.

Do with it what you will: https://www.google.com/landing/takeaction/

Blacked out sites:


Sites that aren’t going dark, but still raising awareness:


Information about SOPA and PIPA: https://www.google.com/landing/takeaction/sopa-pipa/
Nice Blog:
http://www.bayshoresolutions.com/blog/emarketing/stop-sopa-and-pipa-make-your-voice-heard/

Make your voice heard!