Friday, June 1, 2012

SquareSpace - Create your own website

I've created a few sites now with SquareSpace, and it is soooo much better than trying to host your site with a different host.  If you need to do your own site, especially if it is a brochure type website, I'd highly recommend SquareSpace.

Monday, February 6, 2012

4 Must-Know Websites for Android PhoneGap Development

Site Function
http://phonegap.com/ Open Source Mobile Framework - bridging native with Javascript
http://www.sencha.com/products/touch/ Mobile JavaScript Framework
http://www.mobiledevelopersolutions.com/home/announce-1/mds11eclipsepluginforphonegaponandroidreleasestoday-jquerymobileandsenchatouchadded Eclipse Plugin that creates PhoneGap app with jQuery mobile and Sencha
http://jqtouch.com/ Mobile JavaScript Framework – similar to Sencha

Tuesday, January 10, 2012

Add an ‘Active’ Filter to Your QueryExpression

Here’s a generic snippet of code to add a QueryExpression ‘Active’ filter (or another specified).  It will work on almost any CRM Entity.

private void AddActiveCondition(QueryExpression query, string stateCode= "Active")
{
ConditionExpression condition1
= new ConditionExpression();
condition1.AttributeName
= "statecode";
condition1.Operator
= ConditionOperator.Equal;
condition1.Values.Add(stateCode);
if(query.Criteria == null)
query.Criteria
= new FilterExpression { FilterOperator = LogicalOperator.And };
query.Criteria.Conditions.Add(condition1);
}

System.Security.SecurityException in CRM Plugin

I recently got the following error when trying to call the Bing Maps rest endpoint in a CRM 2011 plug-in. Since I wasn’t able to reproduce this in my test code, I did a search, and found out that calls to HttpUtility are not allowed in the sandbox environment for plug-ins for CRM Online.
I had the following piece of code:
HttpUtility.UrlEncode(...)
I changed it to:
Uri.EscapeUriString(...)
This resolved the issue, and now I am geocoding with no problems.

Tuesday, October 11, 2011

Generic IEqualityComparer - Comparing all properties on the object

public class GenericEqualityComparer : IEqualityComparer
{
private List _PropertyInfos = new List();

///
/// Creates a new instance of PropertyComparer.
///

/// The name of the property on type T
/// to perform the comparison on.
public GenericEqualityComparer()
{
var props = typeof(T).GetProperties(BindingFlags.GetProperty BindingFlags.Instance BindingFlags.Public);
_PropertyInfos.AddRange(props);
}

#region IEqualityComparer Members

public bool Equals(T x, T y)
{
foreach (var propertyInfo in _PropertyInfos)
{
//get the current value of the comparison property of x and of y
object xValue = propertyInfo.GetValue(x, null);
object yValue = propertyInfo.GetValue(y, null);

//if the xValue is null then we consider them equal if and only if yValue is null
if (xValue == null)
{
if (yValue != null)
return false;
}

if (!xValue.Equals(yValue))
return false;
}
return true;
}

public int GetHashCode(T obj)
{
List
`object`
values = new List();
foreach (var propertyInfo in _PropertyInfos)
{
//get the current value of the comparison property of x and of y
object xValue = propertyInfo.GetValue(obj, null);
values.Add(xValue);
}
return HashCodeBuilder.Hash(values.ToList());
}

#endregion
}

public static class HashCodeBuilder
{
public static int Hash(params object[] args)
{
if (args == null)
{
return 0;
}

int num = 42;

unchecked
{
foreach (var item in args)
{
if (ReferenceEquals(item, null))
{ }
else if (item.GetType().IsArray)
{
foreach (var subItem in (IEnumerable)item)
{
num = num * 37 + Hash(subItem);
}
}
else
{
num = num * 37 + item.GetHashCode();
}
}
}

return num;
}
}

Thursday, June 3, 2010

The Most Helpful Web Page For Custom Website ISV Deployment for CRM 4.0

I have been extending CRM 4.0 for quite a while now, and it wasn't until recently that I had to do a custom ASPX page that would run in the context of the current user using IFD authentication. I knew I had to use the CrmAuthenticationToken.ExtractCrmAuthenticationToken(Context, orgName) method, but I didn't understand how the site needs to be set up in IIS.


Here's the key: If you want to do this, you DON'T make a new website or virtual directory. You just put the aspx files and the bin folder in the ISV folder of the root of the CRM website.


I figured this out by finding an amazing web page from Microsoft that answered all my questions. Here it is:


http://msdn.microsoft.com/en-us/library/dd548493.aspx


Important things to note:

  • You can put dll's in the bin folder in the application's folder in the ISV folder of the root of the website if you have installed Rollup Update 2
  • You must do all of your configuration in other ways from the web.config
  • If you are using a web application project, you must explicitly reference the dll in the @Assembly page directive in your aspx pages.

I hope this saves you some pain and time.

Wednesday, February 10, 2010

C# Flags Enumeration Helper

Working in the confines of .NET 2.0 (no extension methods), I was in dire need of a helper that would assist in the checking and manipulating of flags enumerations. Over the years that I have used them, I've been bitten enough times using the wrong operators and having to deal with other people maintaining my code that used these enumerations that I finally wrote an enum helper.

This helper covers the setting, checking, and evaluating the flags that have been set on the enum. I wanted to share it with y'all to save you a little of the grief that I have borne. Here it is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace TestFlags
{
class Program
{
[Flags]
public enum Flags
{
None = 0,
First = 1,
Second = 2,
Third = 4
}
static void Main(string[] args)
{
var flag = Flags.None;

Debug.Assert(Enum.EnumHasFlag(flag, Flags.Second));
Debug.Assert(Enum.EnumHasFlag(flag, Flags.Third));

List allFlags = Enum.GetFlagEnumList(flag);
foreach (var allFlag in allFlags)
{
Console.WriteLine(allFlag);
}

Console.ReadKey();
}
}

///
/// Assists with enum operations
///
/// The type of the enum.
public static class Enum where TEnum : struct
{
///
/// Adds the specified flag to an enum.
///
/// The append to.
/// To append.
public static void AddFlagToEnum(ref TEnum appendTo, TEnum toAppend)
{
int appendToInt = Convert.ToInt32(appendTo);
int toAppendInt = Convert.ToInt32(toAppend);

appendTo = (TEnum)(object)(toAppendInt | appendToInt);
}

///
/// Determines whether the enum has a certain flag
///
/// The flags enum value to check to see if it contains the checkAgainst value.
/// The flags enum value to check against.
/// whether the enum contains a certain flag
public static bool EnumHasFlag(TEnum toCheck, TEnum checkAgainst)
{
int checkAgainstInt = Convert.ToInt32(checkAgainst);
int toCheckInt = Convert.ToInt32(toCheck);
return (checkAgainstInt & toCheckInt) == checkAgainstInt;
}

///
/// Gets the flag enum list.
///
/// The flags.
/// The list of enum values contained in the flag
public static List GetFlagEnumList(TEnum flags)
{
List result = new List();
var enumValues = (TEnum[])Enum.GetValues(typeof(TEnum));
foreach (var enumValue in enumValues)
{
if (Convert.ToInt32(enumValue) != 0 && EnumHasFlag(flags, enumValue))
{
result.Add(enumValue);
}
}
return result;
}
}
}

Friday, July 17, 2009

.NET Runtime version 2.0.50727.3053 - Fatal Execution Engine Error – VS 2008 Crashing with Web Site Project

Visual Studio 2008 Development Team Edition kept crashing when opening a certain solution.  I looked in the event viewer and saw this:

temp

I tried unloading and reloading each project in the solution individually to see which project was causing the problem.

After a while of Googling, I found others who had unistalled ReSharper and had success.  That didn’t work for me.  After a little bit more searching, I found someone who had success unistalling PowerCommands for Visual Studio.

That worked for me.  Hope that helps someone reduce brain damage from bashing their head against the wall.

Happy Coding!

Thursday, July 16, 2009

Triple DES Encryption implementation compatible between Java and .NET!

One problem that I have had to solve in the past was making encryption between Java and .NET possible.  Specifically, I was charged to read an encrypted query string parameter from a Java system in my ASP.NET application.  After a few iterations of incompatible implementations, I created an implementation in both .NET (c#) and Java to ensure compatibility.

Since this caused me so much pain, I thought I would share my implementation with you in hopes that it will work for you as well.

Let me know if you have any questions or want to provide a decrypt implementation for the java class.

DOWNLOAD C# CLASS FILE

DOWNLOAD JAVA CLASS FILE

 

.NET (C#) Implementation

/// <summary>
/// Encryption utility class that implements Triple DES algorithm
/// </summary>
public class TripleDESImplementation
{
    //Encryption Key
    private byte[] EncryptionKey { get; set; }
    // The Initialization Vector for the DES encryption routine
    private byte[] IV { get; set; }

    /// <summary>
    /// Constructor for TripleDESImplementation class
    /// </summary>
    /// <param name="encryptionKey">The 24-byte encryption key (24 character ASCII)</param>
    /// <param name="IV">The 8-byte DES encryption initialization vector (8 characters ASCII)</param>
    public TripleDESImplementation(string encryptionKey, string IV)
    {
        if (string.IsNullOrEmpty(encryptionKey))
        {
            throw new ArgumentNullException("'encryptionKey' parameter cannot be null.", "encryptionKey");
        }
        if (string.IsNullOrEmpty(IV))
        {
            throw new ArgumentException("'IV' parameter cannot be null or empty.", "IV");
        }

        EncryptionKey = Encoding.ASCII.GetBytes(encryptionKey);
        // Ensures length of 24 for encryption key
        Trace.Assert(EncryptionKey.Length == 24, "Encryption key must be exactly 24 characters of ASCII text (24 bytes)");

        this.IV = Encoding.ASCII.GetBytes(IV);
        // Ensures length of 8 for init. vector
        Trace.Assert(IV.Length == 8, "Init. vector must be exactly 8 characters of ASCII text (8 bytes)");
    }

    /// <summary>
    /// Encrypts a text block
    /// </summary>
    public string Encrypt(string textToEncrypt)
    {
        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        tdes.Key = EncryptionKey;
        tdes.IV = IV;

        byte[] buffer = Encoding.ASCII.GetBytes(textToEncrypt);
        return Convert.ToBase64String(tdes.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length));
    }

    /// <summary>
    /// Decrypts an encrypted text block
    /// </summary>
    public string Decrypt(string textToDecrypt)
    {
        byte[] buffer = Convert.FromBase64String(textToDecrypt);

        TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
        des.Key = EncryptionKey;
        des.IV = IV;

        return Encoding.ASCII.GetString(des.CreateDecryptor().TransformFinalBlock(buffer, 0, buffer.Length));
    }
}

Java Implementation

public class TripleDesImplementation {
    private String key;
    private String initializationVector;
    public TripleDesImplementation(String key, String initializationVector)
    {
        this.key = key;
        this.initializationVector = initializationVector;
    }

    public String encryptText(String plainText) throws Exception{
    //----  Use specified 3DES key and IV from other source --------------
      byte[] plaintext = plainText.getBytes();
      byte[] tdesKeyData = key.getBytes();

      byte[] myIV = initializationVector.getBytes();

      Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
      SecretKeySpec    myKey = new SecretKeySpec(tdesKeyData, "DESede");
      IvParameterSpec ivspec = new IvParameterSpec(myIV);

      c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
      byte[] cipherText = c3des.doFinal(plaintext);

      return Base64Coder.encodeString(new String(cipherText));
    }
}

Wednesday, July 8, 2009

Managing Session State – Using A Strongly Typed Session Store

Download the example VS 2008 solution here.

As an ASP.NET developer, I’ve found myself in situations where I’ve needed to manage state for the current use by using Session.  I know that there are other ways to keep track of a user’s state aside from Session, and that the use of Session should be very used with discretion. The point of this post is not to say that any time you need to keep track of state in your web application that you should use Session, but rather to present one way of effectively managing this if you ever find that Session is something that you want or need to use.

In my experience, I’ve seen many issues with developers using Session ineffectively and dangerously.  Here are some common follies of using (or misusing) Session:  assuming that something is in Session when it may or may not be, mistyping of the string literal when placing something in or retrieving it from Session (e.g. Session[“UserId”] and Session[“UserID”] are not referencing the same thing), and accidentally having the same Session variable mean two different things.

I created a pattern in the form of a SessionRepository class that will hopefully alleviate some of these issues that are commonly found throughout ASP.NET projects.

This is an example SessionRepository property:

image

This is an example snippet of code that you write while using the SessionRepository:

 image

This gives us a uniform way of setting and getting things from the session without as much work that has to be done with casting and null checking.  It also gives uniform way of removing from the session.  We also are able to easily find all references to a given session variable without having to search our entire solution for strings.  We can just right click on the property and click ‘Find All References,’ and we’re done.

I’ve included a link to an example VS 2008 Web Application project that uses this pattern.  Refer to the SessionState folder within the project.  Hopefully this will prevent some of the head banging that I’ve experienced while working with Session.  Happy Coding!

image

Download it here.

Tuesday, July 29, 2008

Managing Your Different Environments Using External Configuration Files

Download Example Solution: Click Here

One thing that I have found as I have worked for my current employer and worked on a large-scale web application is that configuration files can get hairy.  This has proven to be especially true as we have managed the different configurations for our different environments (development, integration, staging and production).

Our web.config files have grown to about 1000 lines, which becomes a bear when you have to make sure that 4 of those files are in sync.

 

External Config Files To The Rescue

Recently I stumbled upon the beauty of external configuration files, which has made me realize that I can isolate the configuration settings that change and only worry about managing those changes in each of the configuration files and not the entire set of configuration settings.

You may put all of your external configuration files in the root folder along with your web.config, but I'm warning you that this can get ugly in a hurry the more environments you have and as the sections of the configuration file you are breaking out.  I recommend making a sub-folder that will hold all of your external config files and reference them by prefixing the configSource with your sub-folder (e.g. configSource="Config\ConnectionStrings.config").  You may then use folders to organize the different types of configuration settings as well.

 

image

 

Keep in mind as you use external config files that you have to have a separate configuration file for each section of the configuration file that you break out.  You also can only specify an external config file at certain levels of the configuration file.  For example, you can't specify an external configuration file for the entire System.ServiceModel section of your config file.  However, you can specify an external config file at the client level under the System.ServiceModel section.

image

Download

Download the example project to see how you might us these external configuration files:

Click Here

Monday, July 28, 2008

When In Doubt, Regen The Proxies

As I've worked with web services, mainly WCF services, I've run into some really funky problems as I've consumed services that have made me want to rip my hair out.  Hopefully this little bit of advice will help many developers keep more of their hair intact.

Update your service reference before getting too far into trying to diagnose the problem:

image

This is often required when a namespace changes in the service code even if none of the method signatures have changed.  This has usually been the case when the service is mysteriously returning null when you know it shouldn't.

Cheers!

Tuesday, July 8, 2008

A Count Down Asp.NET User Control

Download Example Here:

Count Down Test Web Application

Recently at work, I did some work on our website that would alert our users that the website would be going down soon.  The customer wanted "count down" functionality that would give users an idea of how long they have until the site goes down as the time to take the website down approaches.

image

I figured there would be someone who had already done this sort of thing, so I went to Google.  I found an article by Robert Hashemian at http://www.hashemian.com/tools/javascript-countdown.htm that explains how you would create a count down timer with JavaScript.  His example was pretty slick, but I wanted to create a user control in .NET that I could just set the time of when the timer should expire and forget about all the JavaScript under the covers.  So I did just that.

At first I tried to use Mr. Hashemian's way of setting the ending time in the JavaScript and figuring out how much time was left there, but the problem I found was that the time was dependant on the browser's time, so I decided to change the way the initial number of seconds is determined.  Instead of setting the time in JavaScript, I decided to count how many seconds were left until the target time and just set the number of seconds in JavaScript, so the functionality wouldn't be disrupted by time zone differences.

Anyway, after some work, all I had to do was put the user control tag in my page and set the time in the code behind like so:


            this.countDown1.TimeToEnd = DateTime.Now.AddHours(1.02);

            this.countDown2.TimeToEnd = new DateTime(2050, 1, 1);

I've created a sample web app that uses this control shown in the examples above.

Download Here:

Count Down Test Web Application

Wednesday, June 25, 2008

Running Batch Jobs In An ASP.NET Web Application Using Application State

Download Example Files:

Sample Run Job Web Application

 

Recently while doing work for a client, I came across the need to run a job (batch) within the application while giving the user that ability to monitor the progress of the job and also being able to track how much time was remaining until the completion of the job.

Along with the aforementioned specs, the requirements were as follows:  they needed a web page that they could go to in order to start the job, they needed the website to be able to alert them if another job was being run, they needed to be able to cancel the job at any time.

I assume that this is a common need for businesses and would like to share a simple example that illustrates how one might go about solving such a problem.

image

How I Did It

Since I didn't want to create a database or something similar to handle such a task due to the overhead that it takes to create a database, I decided to store information about my 'job' in the Application State object (which is essentially a HashTable) due to the fact that Application State object could be accessed and modified across the entire application.  This way, anyone, regardless of who started a job, would be able to access the information regarding the job.

The meat of my solution lies in two things: The BatchRun class that I created (Figure 1), and the use of a special property that accesses the Applicaiton State object within my page (Figure 2).

 


 

    [Serializable]

    public class BatchRun

    {

        #region Constructors

 

        public BatchRun()

        {

        }

 

        public BatchRun(int totalNumberOfItems)

        {

            TotalNumberOfItems = totalNumberOfItems;

        }

 

        #endregion

 

        #region Properties

 

        public DateTime? LastUpdatedTime { get; set; }

        public DateTime? StartTime { get; set; }

        public int TotalNumberOfItems { get; set; }

        public int ItemsCompleted { get; private set; }

        public bool ShouldStop { get; set; }

 

        public bool HasNotBegun

        {

            get

            {

                return StartTime == null;

            }

        }

 

        public bool IsCompletedOrExpired

        {

            get

            {

                return PercentDone == 100 || ShouldStop || (LastUpdatedTime != null && LastUpdatedTime.Value < DateTime.Now.AddMinutes(-Settings.Default.StalledMinuteWait));

            }

        }

 

        public int PercentDone

        {

            get

            {

                if (TotalNumberOfItems == 0)

                    return 0;

                return (int)(100 * ((double)ItemsCompleted / (double)TotalNumberOfItems));

            }

        }

 

        private TimeSpan? TotalTime

        {

            get

            {

                if (StartTime == null)

                    return null;

                return DateTime.Now - StartTime.Value;

            }

        }

 

        public TimeSpan EstimatedTimeRemaining

        {

            get

            {

                if (ItemsCompleted == 0 || TotalTime == null)

                    return default(TimeSpan);

                return TimeSpan.FromSeconds(

                (int)((TotalTime.Value.TotalSeconds / ItemsCompleted) * (TotalNumberOfItems - ItemsCompleted)));

            }

        }

        #endregion

 

        #region Public Methods

        public void Start()

        {

            if (TotalNumberOfItems == 0)

            {

                throw new ArgumentException("Total Number of Items not set!", "TotalNumberOfItems");

            }

            StartTime = DateTime.Now;

            LastUpdatedTime = DateTime.Now;

        }

 

        public bool IncrementItemsCompleted()

        {

            if (ItemsCompleted < TotalNumberOfItems)

            {

                LastUpdatedTime = DateTime.Now;

                return (++ItemsCompleted == TotalNumberOfItems);

            }

            return true;

        }

        #endregion

    }

Figure 1

 

 


        protected BatchRun CurrentBatchRun

        {

            get { return (BatchRun)this.Application["CurrentBatchRun"]; }

            set { this.Application["CurrentBatchRun"] = value; }

        }

Figure 2

 

The BatchRun class keeps all of the information that you need to derive what percent of the job is complete as well as how much time is left.  As you can see, I've included some intelligent properties within the BatchRun class to make these calculations easier and uniform.

The special application state property allows you to just access and modify the information about the job without having to be thinking about where you are storing this data.

The rest of the solution is just hooking into this information to let the user know what the status of the job is.

Here's the entire code behind file for the batch run example web page (please note that not everything I've done here is optimal, but is merely to give an example of how one would accomplish such a task):

 


using System;

using System.Threading;

 

namespace RunJobWebsite

{

    public partial class _Default : System.Web.UI.Page

    {

        protected BatchRun CurrentBatchRun

        {

            get { return (BatchRun)this.Application["CurrentBatchRun"]; }

            set { this.Application["CurrentBatchRun"] = value; }

        }

 

        protected void Page_Load(object sender, EventArgs e)

        {

            if (!IsPostBack)

            {

                this.txtStartDate.Text = DateTime.Today.AddMonths(-1).ToShortDateString();

                this.txtEndDate.Text = DateTime.Today.ToShortDateString();

            }

        }

 

        protected void btnRunBatch_Click(object sender, EventArgs e)

        {

            SetBatchParameterTableVisibility(false);

 

            if (!CurrentBatchInProgress())

            {

                this.lblPercentage.Text = "0";

                this.lblTimeRemaining.Text = "Unknown";

                CurrentBatchRun = new BatchRun();

                var ts = new ThreadStart(RunBatch);

                var thread = new Thread(ts);

                thread.Start();

            }

            else

            {

                ShowAlert("Statement Batch Already In Progress");

            }

            timerBatchRun.Enabled = true;

        }

 

        private void RunBatch()

        {

            DateTime startDate = DateTime.Parse(this.txtStartDate.Text);

            DateTime endDate = DateTime.Parse(this.txtEndDate.Text);

 

            var tempDate = startDate;

            int i = 0;

            while (tempDate < endDate)

            {

                i++;

                tempDate = tempDate.AddHours(1);

            }

 

            CurrentBatchRun.TotalNumberOfItems = i;

            CurrentBatchRun.Start();

 

            tempDate = startDate;

            while (tempDate < endDate)

            {

                DoSomething(new Random().Next(1, 5));

                tempDate = tempDate.AddHours(1);

                if (CurrentBatchRun == null || CurrentBatchRun.ShouldStop)

                {

                    break;

                }

                CurrentBatchRun.IncrementItemsCompleted();

            }

        }

 

        private void DoSomething(int seconds)

        {

            Thread.Sleep(seconds * 1000);

        }

 

        private void SetBatchParameterTableVisibility(bool visible)

        {

            this.tblBatchParameters.Visible = visible;

            this.tblBatchProgress.Visible = !visible;

        }

 

        private bool CurrentBatchInProgress()

        {

            var batchRun = CurrentBatchRun;

            if (batchRun == null || batchRun.HasNotBegun)

            {

                return false;

            }

            return !batchRun.IsCompletedOrExpired;

        }

 

        protected void timerBatchRun_Tick(object sender, EventArgs e)

        {

            BatchRun currentBatch = CurrentBatchRun;

            if (currentBatch != null && currentBatch.HasNotBegun)

            {

                return;

            }

            if (currentBatch == null)

            {

                SetBatchParameterTableVisibility(true);

                return;

            }

            if (currentBatch.IsCompletedOrExpired)

            {

                if (currentBatch.ShouldStop)

                {

                    ShowAlert(String.Format("Statement Run Completed at {0}, but was cancelled.", currentBatch.LastUpdatedTime));

                }

                else

                {

                    ShowAlert(String.Format("Statement Run Completed at {0}.", currentBatch.LastUpdatedTime));

                }

                timerBatchRun.Enabled = false;

                SetBatchParameterTableVisibility(true);

            }

            else

            {

                this.lblPercentage.Text = currentBatch.PercentDone.ToString();

                this.lblTimeRemaining.Text = String.Format("{0:f2}", currentBatch.EstimatedTimeRemaining.TotalMinutes);

            }

        }

 

        private void ShowAlert(string alert)

        {

            Response.Write("<script>alert('" + alert + "')</script>");

        }

        protected void btnStop_Click(object sender, EventArgs e)

        {

            ShowAlert("Batch Run Stopped");

            if (CurrentBatchRun != null)

            {

                CurrentBatchRun.ShouldStop = true;

                this.timerBatchRun.Enabled = false;

                SetBatchParameterTableVisibility(true);

            }

        }

 

 

    }

}

 

Download Example Files:

Sample Run Job Web Application