RestSharp with Async Await

RestSharp is an excellent open source project to use in a Windows Phone app if you want make http calls to a json api. However it doesn’t have any inbuilt support for the async await syntax. Thankfully with C#’s extensions methods we can add this support in our app.

namespace RestSharpEx
{
    public static class RestClientExtensions
    {
      public static Task<IRestResponse> ExecuteTaskAsync(this RestClient @this, RestRequest request)
      {
        if (@this == null)
            throw new NullReferenceException();
     
        var tcs = new TaskCompletionSource<IRestResponse>();
     
        @this.ExecuteAsync(request, (response) =>
        {
            if (response.ErrorException != null)
                tcs.TrySetException(response.ErrorException);
            else
                tcs.TrySetResult(response);
        });
     
        return tcs.Task;
      }
    }
}

This will add a new function to the RestSharp client type called ExecutreTaskAsync. Inside the method it will call the ExecuteAsync function as you normally would, but has also implemented returning a Task and setting it’s results when its complete.

To use the function would be as follows

var client = new RestClient("http://www.YOUR SITE.com/api/");
var request = new RestRequest("Products", Method.GET);
var response = await client.ExecuteTaskAsync(request);

Creating 301 redirects in web.config

For various reasons at times you may need to create a 301 redirect to another URL. This could be as a result of a page moving or you just need to create some friendly URLS.

As a developer you may be tempted to do something like this in code…

private void Page_Load(object sender, System.EventArgs e)
{
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location","http://www.new-url.com");
}

But do you really want your project cluttered up with files who’s only purpose is to redirect to another page!

You may also be tempted to try doing something with .NET’s RouteCollection. This would certainly solve an issue on creating a redirect for anything without a file extension, but there is a better way.

In your web.config file under the configuration node create something like this

  <location path="twitter">
    <system.webServer>
      <httpRedirect enabled="true" destination="http://twitter.com/TwitterName" httpResponseStatus="Permanent" />
    </system.webServer>
  </location>

The location path specifies that path on your site that this redirect will apply to. The destination value in the httpRedirect is where the redirect will go to. As well as setting Permanent for the httpResponseStatus you can also specify Found or Temporary depending on your needs.

ASP.NET Session Timeout

A users session on an ASP.NET site by default will time-out after 20 minutes. This however can be changed through either the web.config file or IIS.

To edit through the web.config file you need to edit the sessionState tag under system.web

<system.web>
  <sessionState timeout="30"></sessionState>
</system.web>

Or through IIS click on your site name and then click Session State under the ASP.NET heading. There will be a field labeled Time-out (in minutes).

The value you enter for time-out must be an integer.

Help it doesn’t seem to work!

If your sessions still seem like there timing out after 20 minutes it could be because your site isn’t very active.

The application pool for your site also has an idle time-out that is set by default to 20 minutes. When the idle time-out is reached it will cause your application pool to recycle and therefore loose any active sessions (that’s assuming you have the session state mode set to In Proc). Therefore it is a good idea to increase this to whatever you have set the session time-out to.

To do this go to your sites application pool in IIS, click advanced settings on the right and then look for the Idle Time-out (minutes) setting and update this to be the same as your session time-out value.

Convert string or int to enum

Enum’s a great, but you may be wondering how you can turn an integer or string value into the corresponding enum. For example you may have an api that’s being sent XML or JSON, and then you need to turn one of the values within that into an enum to set on an object in your code.

Well it’s very simple. If you have a string do this:

YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString);

or if you have an int do this (you could also just do the first example with a ToString() on the end.

YourEnum foo = (YourEnum)yourInt;

Converting users from Membership to SimpleMembership

In ASP.NET 2 Microsoft introduced the Membership provider. By many accounts it is not perfect, but as a one size fits all solution it’s not bad. Plus it had a major advantage that a lot of other people would also be using it, so if you wanted to grab a forum solution to stick on your site, chances were it would use the same Membership provider.

Now though there is a second Membership provider from Microsoft called SimpleMembership. It simplifies a lot of things that weren’t needed with the original Membership provider and also introduces support for working with OAuth providers. Not only that but if you create the MVC 4 project from the default template that is what your solution will be set up to use.

The problem however is Membership and SimpleMembership are not compatible. They store their information in separate tables and if you do try to copy all the users from one to the other, you will soon discover the hashing algorithm used on the password is different. You probably also had all your passwords one way hashed so you can’t even generate the new ones.

There is a solution however. Paul Brown has written a nice bit of code to update the MVC 4 account controller so that when your users log in they will first be authorised against SimpleMembership, if that fails it will then authorise against the original Membership and if that succeeds it will generate the new password in SimpleMembership using the one just provided by the user.

Over time as your users log in the will be slowly migrated over. The second time the log in the SimpleMembership will authorise them and the extra code won’t even be hit.

http://pretzelsteelersfan.blogspot.co.uk/2012/11/migrating-legacy-apps-to-new.html

Back to basics string vs StringBuilder

This is simple stuff but is something I see people easily miss by just not thinking about it.

A string is an immutable object, which means once created it can not be altered. So if you want to do a replace or append some more text to the end a new object will be created.

A StringBuilder however is a buffer of characters that can be altered without the need for a new object to be created.

In the majority of situations a string is a perfectly reasonable choice and creating an extra 1 or 2 objects when you appened a couple of other strings isn’t going to make a significant impact on the performance of your program. But what happens when you are using strings in a loop.

A few weeks ago one of my developers had written some code that went through a loop building up some text. It looked a little like this:

string foo = "";

foreach (string baa in someSortOfList)
{
    foo += " Value for " + baa + " is: ";

    var aValue = from x in anotherList
                 where x.name == baa
                 select x;

    foo += aValue.FirstOrDefault().value;
}

Everything worked apart from the fact it took 30seconds to execute!

He was searching through convinced that the linq expressions in the middle was what was taking the time, and was at the point of deciding it could not go any faster without a new approach.

I pointed out not only had he used strings rather than a StringBuilder, but the loop also created around 10 string objects within it. The loop which repeated a couple thousand times was therefore creating 20000 objects that weren’t needed. After we switched froms strings to a StringBuilders the loop executed in milliseconds.

So remember when your trying to work out why your code may be slow, remember the basic stuff.

.Net Tip: Default Button for Enter Key

I don’t know if I should be happy to now know about this, or just conserned that it’s taken me this long to discover. But one issue that surfaces time and time again when programming in ASP.NET, is that issue that pressing enter/return in a text feild doesn’t always do what you want it to do. 

On a normal website you can have many forms each with their own submit button which becomes the default action when pressing return on one of the forms feilds. However in ASP.NET Web Forms there is only ever one form on a page, but there could be 10 different buttons each needing to be the default action for a particular text box. 

The solution as it turns out is very simple and you have two options both introduced in .NET 2.0 (yes that’s how old it is!) 

1. Default button for the form. If your page has more than one button, but there is only one that you want to fire when you hit enter then in the code behind you can just type… 

Form.DefaultButton = Button1

or it can also be specified in your aspx file 

 
<form runat="server" defaultbutton="Button1">

2. If you need to be more specific a panel can also have a default button… 

Panel1.DefaultButton = Button1

or again is can be specified in your aspx file

<asp:Panel runat="server" DefaultButton="Button1">

Custom Validator Error from Server Side

The built in ASP.NET validators are amazing as we all know. You just drag them on the page, tell them what control to validate, give them a summary control to list the errors and they do it. But what if there’s something you need to add server side? Such as something that needs to check with the database before saving. You already have your validation summary control, so it would be nice to re-user that and have everything automatically looking the same. But it would appear there’s no easy way of doing it built in, so here’s an easy way of doing it… 

Creating a Custom Validation Error

First your going to need a class with some static class’s that you can pass your error message to. Here I have two functions one for simply adding the error to the page and the other for adding the error to the page with a specific validation group. I am using a CustomValidator object to make this all work, another option is to implement IValidator but it’s actually more effort than’s needed. The other section to note is that I’m setting the Error.Text to a non breaking space (this is what would normally go next to the form field you’re validating). This is because if you don’t then it will default to the ErrorMessage which we only want to go into the summary. If you try setting it to a normal space it will still also default to the summary text.

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

/// <summary>
/// Summary description for Validator
/// </summary>
public class ValidationError
{

    public static void Display(string Message)
    {
        Display(Message, "");
    }

  public static void Display(string Message, string ValidationGroup)
    {
  CustomValidator Error = new CustomValidator();
        Error.IsValid = false;
        Error.ErrorMessage = Message;
        Error.ValidationGroup = ValidationGroup;
        Error.Text = "&nbsp;";

  Page currentPage = HttpContext.Current.Handler as Page;
        currentPage.Validators.Add(Error);
    }
}

Now to trigger the error you just need to called the function as below:

ValidationError.Display("Useful error message", "ValidationGroupName");

Creating Events in ASP.NET

Creating your own events on your own controls is something that is essential if you want you web app to work well and also provide you with reusable controls. It’s easy to skip past the problem and find another way to get your code to do what you want it to do and detect the change another way. But you end up with much nicer code if your controls can have proper events for a piece of action, and you web page can have proper event handlers on each. Not only that but the code you need to write in generally a copy and past job and not that hard.

The Code

While it’s not that hard, the amount of code that is needed is quite a lot more than you may expect. Fortunately though it’s code you going to just re-use again and again changing small bits as needed.

    //1 - Event args (use default, but eventually pass in data through here)
    public class SaveCompleteEventArgs : EventArgs
    {
        public SaveCompleteEventArgs(int inDataValue)
        {
            this.DataValue = inDataValue;
        } //end of con

        public readonly int DataValue;
    }



    //2 - define delegate
    public delegate void SaveCompleteEventHandler(object sender, SaveCompleteEventArgs e);

    //3 - define the event itself
    public event SaveCompleteEventHandler SaveComplete;

    //4 - the protected virtual method to notify registered objects of the request
    //	virtual so that it can be overridden.
    protected virtual void OnSaveComplete(SaveCompleteEventArgs e)
    {
        //if the UpdateData event is empty, then a delegate has not been added to it yet.
        if (SaveComplete != null)
        {
            //event exists, call it:
            SaveComplete(this, e);
        } //end of if
    }

    //5 - method that translates the input into the desired event
    public void TriggeringMethod(int strData)
    {

        // get new event args
        //EventArgs e = new EventArgs();
        SaveCompleteEventArgs e = new SaveCompleteEventArgs(strData);

        // call the virtual method
        OnSaveComplete(e);
    }

LINQ to SQL Inserts and Deletes

Inserting and Deleting records in a database using LINQ to SQL is just as easy as selecting information. What’s not so easy is actually finding out how to do it. There are lots of excellent blog posts around such as this one by Scott Guthrie http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx, however most of them we’re all written for the Beta version of LINQ to SQL which let you do a .Add() or .Remove() on your table, which was  changed on the final release. 

So to insert do something like this: 

DataClassesDataContext dataContext = new DataClassesDataContext(); 

//Create my new Movie record
Movie movie = new Movie();
movie.Name = "Tim's movie"; 

//Insert the movie into the data context
dataContext.Movies.InsertOnSubmit(movie); 

//Submit the change to the database
dataContext.SubmitChanges();

And to delete do something like this:

DataClassesDataContext dataContext = new DataClassesDataContext();

var movies = from m in dataContext.Movies
                  where m.Name == "Tim's movie"
                  select m;

dataContext.Movies.DeleteAllOnSubmit(movies);

dataContext.SubmitChanges();