Dec 15 2009

Setup your solution and project for success by proper naming conventions, namespace configuration and folder structure

Category: ASP.NETryancmartin1976 @ 20:56

First Strategy:

Second Strategy:

Let's say you’re building a web application which connects to a database. This is a very normal and consistent scenario for business developers on a day to day basis. Right off the bat you now have two projects to build within one solution; the UI Layer and the Data Access Layer. I will also add two more projects to this solution, UI Tests and Data Access Tests.

STEP 1

Create the solution and projects

IpswitchftWeb.sln

  1. IpswitchftWeb.csproj (Web Application)
  2. IpswitchftCore.csproj (Data Access)
  3. IpswitchftWebTests.csproj (Web Application Tests)
  4. IpswitchftCoreTests.csproj (Data Access Tests)

STEP 2

Update the assembly and default namespaces

Next you want to update assembly name and default namespace values the properties tab for all four projects within Visual Studio.

  1. Ipswitchft.IpswitchftWeb (Web Application)
  2. Ipswitchft.IpswitchftCore (Data Access)
  3. Ipswitchft.IpswitchftWebTests (Web Application Tests)
  4. Ipswitchft.IpswitchftCoreTests (Data Access Tests)

STEP 3

Add folders to your project that make sense

Open up your IpswitchftCore.csproj and six folders:

  1. Core (root)
  2. Core/DataAccess (interfaces)
  3. Core/DataAccess/Impl (concrete classes)
  4. Core/Domain (data model)
  5. Core/Service (interfaces)
  6. Core/Service/Impl (concrete classes)

STEP 4

Here is an example of requesting data from the data access layer from the service layer that can be called from the web application.

IpswitchftCore/Core/DataAccess/ITestRepository.cs
using StructureMap;
 
namespace Ipswitchft.IpswitchftCore.Core.DataAccess
{
    [PluginFamily("Default")]
    public interface ITestRepository
    {
        string GetData();
    }
}
IpswitchftCore/Core/DataAccess/Impl/TestRepository.cs
using StructureMap;
 
namespace Ipswitchft.IpswitchftCore.Core.DataAccess.Impl
{
    [Pluggable("Default")]
    public class TestRepository : ITestRepository
    {
        public string GetData()
        {
            return "data from a linq object";
        }
    }
}
IpswitchftCore/Core/Service/ITestService.cs
using StructureMap;
 
namespace Ipswitchft.IpswitchftCore.Core.Service
{
    [PluginFamily("Default")]
    public interface ITestService
    {
        string GetTestDataAndValidate();
    }
}
IpswitchftCore/Core/Service/Impl/TestService.cs
using Ipswitchft.IpswitchftCore.Core.DataAccess;
using StructureMap;
 
namespace Ipswitchft.IpswitchftCore.Core.Service.Impl
{
    [Pluggable("Default")]
    public class TestService : ITestService
    {
        private ITestRepository testRepository;
 
        public TestService()
        {
            testRepository = ObjectFactory.GetInstance<ITestRepository>();
        }
 
        public string GetTestDataAndValidate()
        {
            return testRepository.GetData();
        }
    }
}
IpswitchftWeb/TestString.aspx.cs
using System;
using Ipswitchft.IpswitchftWeb.Interface;
using Ipswitchft.IpswitchftWeb.Presenter;
 
namespace Ipswitchft.IpswitchftWeb
{
    public partial class TestString : System.Web.UI.Page, ITestString
    {
        private TestStringPresenter _presenter;
 
        protected override void OnInit(EventArgs e)
        {
            _presenter = new TestStringPresenter();
            _presenter.Init(this);
        }
 
        public void ShowString(string message)
        {
            lblString.Text = message;
        }
    }
}
IpswitchftWeb/Presenter/TestStringPresenter.cs
using Ipswitchft.IpswitchftCore.Core.Service;
using Ipswitchft.IpswitchftWeb.Interface;
using StructureMap;
 
namespace Ipswitchft.IpswitchftWeb.Presenter
{
    public class TestStringPresenter
    {
        private ITestString _view;
        private ITestService _testService;
 
        public void Init(ITestString view)
        {
            _view = view;
            _testService = ObjectFactory.GetInstance<ITestService>();
            _view.ShowString(_testService.GetTestDataAndValidate());
        }
    }
}
IpswitchftWeb/Interface/ITestString.cs
namespace Ipswitchft.IpswitchftWeb.Interface
{
    public interface ITestString
    {
        void ShowString(string message);
    }
}

Tags: , , , , ,

Dec 15 2009

Add Log4net .dll to your projects for easy logging and optimal error handling

Category: ASP.NETryancmartin1976 @ 20:55

First Strategy:

Second Strategy:

Building your own logging framework can be time consuming and a waste of time because log4net already did it for you.

STEP 1

Download the dll and config from there site: http://logging.apache.org/log4net/download.html

STEP 2

Drop the dll and the config file into your bin directory and add a reference to the dll from Visual Studio project.

STEP 3

Add a Log directory under your root directory

STEP 4

Add this code, preferably to your Data Access or Service layer and name it Log.cs:

using System;
using System.Collections.Generic;
using System.IO;
using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Layout;
 
public static class Log
{
    private static Dictionary<Type, ILog> _loggers = new Dictionary<Type, ILog>();
    private static bool _logInitialized = false;
    private static object _lock = new object();
 
    public static string SerializeException(Exception e)
    {
        return SerializeException(e, string.Empty);
    }
 
    private static string SerializeException(Exception e, string exceptionMessage)
    {
        if (e == null) return string.Empty;
 
        exceptionMessage = string.Format(
            "{0}{1}{2}\n{3}",
            exceptionMessage,
            (exceptionMessage == string.Empty) ? string.Empty : "\n\n",
            e.Message,
            e.StackTrace);
 
        if (e.InnerException != null)
            exceptionMessage = SerializeException(e.InnerException, exceptionMessage);
 
        return exceptionMessage;
    }
 
    private static ILog getLogger(Type source)
    {
        lock (_lock)
        {
            if (_loggers.ContainsKey(source))
            {
                return _loggers[source];
            }
 
            ILog logger = LogManager.GetLogger(source);
            _loggers.Add(source, logger);
            return logger;
        }
    }
 
    public static void Debug(object source, object message)
    {
        Debug(source.GetType(), message);
    }
 
    public static void Debug(Type source, object message)
    {
        getLogger(source).Debug(message);
    }
 
    public static void Info(object source, object message)
    {
        Info(source.GetType(), message);
    }
 
    public static void Info(Type source, object message)
    {
        getLogger(source).Info(message);
    }
 
    public static void Warn(object source, object message)
    {
        Warn(source.GetType(), message);
    }
 
    public static void Warn(Type source, object message)
    {
        getLogger(source).Warn(message);
    }
 
    public static void Error(object source, object message)
    {
        Error(source.GetType(), message);
    }
 
    public static void Error(Type source, object message)
    {
        getLogger(source).Error(message);
    }
 
    public static void Fatal(object source, object message)
    {
        Fatal(source.GetType(), message);
    }
 
    public static void Fatal(Type source, object message)
    {
        getLogger(source).Fatal(message);
    }
 
    public static void Debug(object source, object message, Exception exception)
    {
        Debug(source.GetType(), message, exception);
    }
 
    public static void Debug(Type source, object message, Exception exception)
    {
        getLogger(source).Debug(message, exception);
    }
 
    public static void Info(object source, object message, Exception exception)
    {
        Info(source.GetType(), message, exception);
    }
 
    public static void Info(Type source, object message, Exception exception)
    {
        getLogger(source).Info(message, exception);
    }
 
    public static void Warn(object source, object message, Exception exception)
    {
        Warn(source.GetType(), message, exception);
    }
 
    public static void Warn(Type source, object message, Exception exception)
    {
        getLogger(source).Warn(message, exception);
    }
 
    public static void Error(object source, object message, Exception exception)
    {
        Error(source.GetType(), message, exception);
    }
 
    public static void Error(Type source, object message, Exception exception)
    {
        getLogger(source).Error(message, exception);
    }
 
    public static void Fatal(object source, object message, Exception exception)
    {
        Fatal(source.GetType(), message, exception);
    }
 
    public static void Fatal(Type source, object message, Exception exception)
    {
        getLogger(source).Fatal(message, exception);
    }
 
    private static void initialize()
    {
        string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log4Net.config");
        if (!File.Exists(logFilePath))
            logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"bin\Log4Net.config");
 
        XmlConfigurator.ConfigureAndWatch(new FileInfo(logFilePath));
    }
 
    public static void EnsureInitialized()
    {
        if (!_logInitialized)
        {
            initialize();
            _logInitialized = true;
        }
    }
}

STEP 5

Add a global.asax file and add this code to it

protected void Application_Start(object sender, EventArgs e)
        {
            Log.EnsureInitialized();
        }

STEP 6

Invoke an error and log it!

public string GetTestDataAndValidate()
        {
            try
            {
                string returnData = testRepository.GetData();
                if (string.IsNullOrEmpty(returnData))
                    Log.Warn(this, "there should be data coming back");
                else if (returnData.Contains("error"))
                    Log.Error(this, returnData);
                return returnData;
            }
            catch (Exception ex)
            {
                Log.Fatal(this, ex.InnerException);
                return "";
            }
        }

STEP 7

That's it! Done! Go see the error log results for yourself. If everything was configured correctly you should have an error log in your Logs directory under the root directory in your web application.

You should play around with the Log4Net.config file until you get the results your looking for.

<?xml version="1.0" encoding="utf-8"?>
<log4net debug="false">
  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <file type="log4net.Util.PatternString" value="Logs/log.xml" />
    <appendToFile value="true" />
    <datePattern value="yyyyMMdd" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="1000KB" />
    <layout type="log4net.Layout.XmlLayoutSchemaLog4j">
      <locationInfo value="true" />
    </layout>
  </appender>
  <root>
    <level value="DEBUG" />
    <appender-ref ref="RollingFileAppender" />
  </root>
  <logger name="StructureMap" additivity="false">
    <level value="WARN"/>
    <appender-ref ref="OutputDebugStringAppender" />
    <appender-ref ref="ConsoleAppender" />
  </logger>
  <logger name="NHibernate" additivity="false">
    <level value="INFO"/>
    <appender-ref ref="AspNetTraceAppender" />
  </logger>
</log4net>

Tags: , , , , ,

Dec 15 2009

Add Google Analytics to your website

First Stategy:

Second Strategy:

STEP 1

Create a Google Analytics account. This is a very easy process if you already have a Gmail account. After you fill out a few fields copy your tracking code from Google Analytics account profile by doing this:

To access your tracking code from within your Google Analytics account:

  • Log in to Google Analytics at http://www.google.com/analytics
  • From the Overview page, select the account that has the profile for the tracking code you're looking for, as the code is profile-specific.
  • Select the profile from the accounts Overview page.
  • From that profile's Actions column, click Edit
  • At the top right of the 'Main Website Profile Information' box, click Check Status
  • Your tracking code can be copied and pasted from the text box in the Instructions for adding tracking section

STEP 2

Copy your tracking code into your asp.net master page if you have one at the bottom of the page right before tag. If you do not have a master page you must add this code to every page at the bottom before the closing body tag.

Tags: , , , ,

Dec 15 2009

Add an iPhone & iTouch icon to your website

First Stategy:

Second Strategy:

Create an iPhone and iTouch icon for your website in two minutes

This might be one of the easiest tutorials, exercises or to-do’s on this site.

STEP 1

First create a 75 pixel by 75 pixel in png format if you haven’t done so already. Make sure this icon matched the images you want to portray for your website.

STEP 2

Rename the image apple-touch-icon.png

STEP 3

Upload the image to the root directory of your website

That’s it, for now on when anyone goes to your site on an iPhone or iTouch and bookmarks it, they will see your newly created icon on the device desktop.

Tags: , ,

Dec 15 2009

Redirect users to another page or sub domain when they come to your site from a mobile devices

First Stategy:

Second Strategy:

Redirecting users based on their browser to a mobile subdomain

Put this in the head of your web page

<script language="javascript" type="text/javascript">
function browserCheck() {
    var agt = navigator.userAgent.toLowerCase();
    if (agt.indexOf("windows ce") != -1) return true;
    if (agt.indexOf("palmsource") != -1) return true;
    if (agt.indexOf("palmos") != -1) return true;
    if (agt.indexOf("midp-") != -1) return true;
    if (agt.indexOf("portalmmm") != -1) return true;
    if (agt.indexOf("symbian os") != -1) return true;
    if (agt.indexOf("up.browser") != -1) return true;
    if (agt.indexOf("mobilephone") != -1) return true;
    if (agt.indexOf("nokia") != -1) return true;
    if (agt.indexOf("docomo") != -1) return true;
    if (agt.indexOf("blackberry") != -1) return true;
    if (agt.indexOf("iphone") != -1) return true;
    if (agt.indexOf("ipod") != -1) return true;
    if (agt.indexOf("itouch") != -1) return true;
    else return false;
}
 
var browserName = browserCheck()
if (browserName) {
    document.location = "http://mobile.secondstrategy.com";
} else if (screen.width <= 699) {
    document.location = "http://mobile.secondstrategy.com";
}
</script>

Tags: , , , ,