April 19
Simple REST Client for HTTP Request in C#

I haven’t posted in a while, so I really just wanted to get something up. This simple but useful example wraps the System.Net HttpRequest object in a nice reusable helper class for making RESTful calls to services and feeds.

It’s usage is super simple:

var client = new RestClient("http://api.com/service/method/param");
var response = client.MakeRequest();

Here is the class itself:

using System;
using System.IO;
using System.Net;

namespace HttpUtils
{

public enum HttpVerb
{
GET,
POST,
PUT,
DELETE
}

public class RestClient
{
public string EndPoint { get; set; }
public HttpVerb Method { get; set; }
public string ContentType { get; set; }

public RestClient()
{
EndPoint = "";
Method = HttpVerb.GET;
ContentType = "text/xml";
}
public RestClient(string endpoint)
{
EndPoint = endpoint;
Method = HttpVerb.GET;
ContentType = "text/xml";
}
public RestClient(string endpoint, HttpVerb method)
{
EndPoint = endpoint;
Method = method;
ContentType = "text/xml";
}

public string MakeRequest()
{
return MakeRequest("");
}


public string MakeRequest(string parameters)
{
var request = (HttpWebRequest)WebRequest.Create(EndPoint + parameters);

request.Method = Method.ToString();
request.ContentLength = 0;
request.ContentType = ContentType;

using (var response = (HttpWebResponse)request.GetResponse())
{
var responseValue = string.Empty;

if (response.StatusCode != HttpStatusCode.OK)
{
string message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
throw new ApplicationException(message);
}

// grab the response
using (var responseStream = response.GetResponseStream())
{
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd();
}
}

return responseValue;
}
}

} // class

}

March 27
The Repository Patter for ORMs–EF4, Nhibernate, Subsonic, Ect..

I have decided to make my first post on my new blog about an old favorite. The repository pattern. While the repository pattern is in no way new it has evolved a lot over time. My implementation is no exception. I am a big fan of ORMs but not of tightly coupled dependencies. And so, my implementation aims to decouple my applications from being tied to a particular ORM, while still allowing me to take full advantage of the productivity ORMs offer.

Interface – The key to loosely coupled architecture

This decoupled implementation I am referring too is of course accomplished using an interface. This gives us the ability to change our implementation at any time without affecting the rest of the code base as long as our new implementation adheres to the interface. The key to good interface design it that it should be intuitive and encapsulate the functionality you are looking to publically expose to your application.

public interface IRepository
{
void CommitChanges();
void Delete<T>(Expression<Func<T, bool>> expression) where T : class, new();
void Delete<T>(T item) where T : class, new();
void DeleteAll<T>() where T : class, new();
T Single<T>(Expression<Func<T, bool>> expression) where T : class, new();
T Single<T>(Expression<Func<T, bool>> expression, Expression<Func<T, object>> include) where T : class, new();
T Single<T>(Expression<Func<T, bool>> expression, params Expression<Func<T, object>>[] include) where T : class, new();
IQueryable<T> All<T>() where T : class, new();
IQueryable<T> All<T>(Expression<Func<T, object>> include) where T : class, new();
IQueryable<T> All<T>(params Expression<Func<T, object>>[] include) where T : class, new();
void Add<T>(T item) where T : class, new();
void Add<T>(IEnumerable<T> items) where T : class, new();
void Update<T>(T item) where T : class, new();
}

 

Implementation

Here is an example implementation of the above interface. This implementation is using an Entity Framework 4 generated data model. I could just have easily been a mock for your unit test, of an implementation using another ORM.

public class Repository : IRepository
{
ObjectContext _context;
public Repository(ObjectContext context) {
_context = context;
}
public void CommitChanges() {
_context.SaveChanges();
}
public void Delete<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T: class, new() {
var query = All<T>().Where(expression);
foreach (var item in query) {
Delete(item);
}
}
public void Delete<T>(T item) where T: class, new() {
_context.DeleteObject(item);
}
public void DeleteAll<T>() where T: class, new() {
var query = All<T>();
foreach (var item in query) {
Delete(item);
}
}
public void Dispose() {
_context.Dispose();
}
public T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T: class, new() {
return All<T>().FirstOrDefault(expression);
}
public T Single<T>(Expression<Func<T, bool>> expression, Expression<Func<T, object>> include) where T : class, new() {
return All<T>(include).FirstOrDefault(expression);
}
public T Single<T>(Expression<Func<T, bool>> expression, params Expression<Func<T, object>>[] include) where T : class, new() {
return All<T>(include).FirstOrDefault(expression);
}
public IQueryable<T> All<T>() where T: class, new() {
return _context.CreateQuery<T>(GetSetName<T>()).AsQueryable();
}
public IQueryable<T> All<T>(Expression<Func<T, object>> include) where T : class, new() {
return _context.CreateQuery<T>(GetSetName<T>()).Include<T>(include).AsQueryable();
}
public IQueryable<T> All<T>(params Expression<Func<T, object>>[] include) where T : class, new() {
return _context.CreateQuery<T>(GetSetName<T>()).Include<T>(include).AsQueryable();
}
public void Add<T>(T item) where T: class, new() {
_context.AddObject(GetSetName<T>(),item);
}
public void Add<T>(IEnumerable<T> items) where T: class, new() {
foreach (var item in items) {
Add(item);
}
}
public void Update<T>(T item) where T: class, new() {
throw new NotImplementedException("Not Required");
}
string GetSetName<T>() {
var entitySetProperty =
_context.GetType().GetProperties()
.Single(p => p.PropertyType.IsGenericType && typeof(IQueryable<>)
.MakeGenericType(typeof(T)).IsAssignableFrom(p.PropertyType));

return entitySetProperty.Name;
}
}

 

Include Helper Extensions

Entity Frameworks Include extension method uses strings which I am not a big fan of so I wrote these helpers that enable me to use expressions instead to specify the child object I want to include in my results. This may seem trivial but stop and think. Over time all of those string are compounding liabilities that are slowly but surely degrading the maintainability of your application. Down the road long if someone changes the name of a type you will have runtime error instead of compile time errors when you use strings. This is why my interface used expression to define includes instead of strings. If the name of a type is changed this implementation will ensure you are notified of the errors at compile time.

public static class IncludeExtensions
{
public static ObjectQuery<T> Include<T>(this ObjectQuery<T> query, Expression<Func<T, object>> path)
{
// Retrieve member path:
List<PropertyInfo> members = new List<PropertyInfo>();
CollectRelationalMembers(path, members);

// Build string path:
StringBuilder sb = new StringBuilder();
string separator = "";
foreach (MemberInfo member in members)
{
sb.Append(separator);
sb.Append(member.Name);
separator = ".";
}
return query.Include(sb.ToString());
}

public static ObjectQuery<T> Include<T>(this ObjectQuery<T> query, params Expression<Func<T, object>>[] paths)
{
foreach (var path in paths)
{
// Retrieve member path:
List<PropertyInfo> members = new List<PropertyInfo>();
CollectRelationalMembers(path, members);

// Build string path:
StringBuilder sb = new StringBuilder();
string separator = "";
foreach (MemberInfo member in members)
{
sb.Append(separator);
sb.Append(member.Name);
separator = ".";
}

query.Include(sb.ToString());
}
return query;
}

private static void CollectRelationalMembers(Expression exp, IList<PropertyInfo> members)
{
if (exp.NodeType == ExpressionType.Lambda)
{
// At root, explore body:
CollectRelationalMembers(((LambdaExpression)exp).Body, members);
}
else if (exp.NodeType == ExpressionType.MemberAccess)
{
MemberExpression mexp = (MemberExpression)exp;
CollectRelationalMembers(mexp.Expression, members);
members.Add((PropertyInfo)mexp.Member);
}
else if (exp.NodeType == ExpressionType.Call)
{
MethodCallExpression cexp = (MethodCallExpression)exp;

if (cexp.Method.IsStatic == false)
throw new InvalidOperationException("Invalid type of expression.");

foreach (var arg in cexp.Arguments)
CollectRelationalMembers(arg, members);
}
else if (exp.NodeType == ExpressionType.Parameter)
{
// Reached the toplevel:
return;
}
else
{
throw new InvalidOperationException("Invalid type of expression.");
}
}
}

 

Conclusions

This is one example of the  repository pattern. There are many like it but this one is mine.

March 27
Delete SharePoint 2010 Timer Job Cache with PowerShell

If you have ever written a custom timer job in SharePoint 2010 you have probably already devised something along these lines, if not you have come to the right place.

I totally shot myself in the foot last night trying to figure out why the heck my code was not updated when I redeployed my WSP containing a custom timer job over and over yet the changes were not being reflected when I attached to the timer job process to debug. I finally rebooted my machine out of pure frustration and boom my code updated. That was when it hit me. SharePoint was caching the assemblies required to run the timer job for performance reasons.

While I’m sure these are ways to configure SharePoint so that is does not cache these assemblies I think it makes more since to just clear the cache and then redeploy your package.

The PowerShell example below does just that following these 4 steps:

  1. 1) Shut down the Timer Job service
  2. 2) Delete temp configuration located at "C$\ProgramData\Microsoft\SharePoint\Config”
  3. 3) Clear the SharePoint Timer Job cache which sits in the %ALLUSERSPROFILE%\Microsoft\SharePoint\Config\{guid} directory.
  4. 4) Restart Timer Job Service

 

Here is the script. You will have to modify the $servers variable accordingly for your environment.

# configuration
$servers = "localhost", "server2", "server3"
$deletePath = "C$\ProgramData\Microsoft\SharePoint\Config"
$path = "\\$server\$deletePath"
$folders = [System.IO.Directory]::GetDirectories($path)


# loop through each server
foreach ($server in $servers)
{
Write-Host ""
Write-Host "//////////////////////////////////////////////////"
Write-Host "/ PROCESSING $server /////////////////////////////"
Write-Host "//////////////////////////////////////////////////"


# stop timer job service
Get-WmiObject -computer $server Win32_Service -filter "Name='SPTimerV4'" | Stop-Service
Write-Host "SPTimerV4 STOPED on: $server"


# delete temp config
foreach($folder in $folders)
{
Remove-Item $folder\* -Recurse -Force
Write-Host "$folder REMOVED on: $server"
}


# remove timer job cache
$configDb = Get-SPDatabase | ? {$_.TypeName -eq "Configuration Database"}
$guid = $configDb.Id
Remove-Item "$env:AllUsersProfile\Microsoft\SharePoint\Config\$guid\*.xml"
Set-Content "$env:AllUsersProfile\Microsoft\SharePoint\Config\$guid\cache.ini" "1"
Write-Host "Timer Job Cache REMOVED on: $server"


# start timer job service
Get-WmiObject -computer $server Win32_Service -filter "Name='SPTimerV4'" | Start-Service
Write-Host "SPTimerV4 STARTED on: $server"
Write-Host "///////////////////////////////////////////////////"
Write-Host ""
}


Write-Host ""
Write-Host "//////////////////////////////////////////////////"
Write-Host "/ DONE ///////////////////////////////////////////"
Write-Host "//////////////////////////////////////////////////"

March 21
Copy Console Output to a File – C#

 

I recently was charged with the task of copying all of of the console output for from a console application to a log file. It turns out there is a very easy way to accomplish this task using lof4net.

Here is step by step instruction.

    1. 1) Create a new console application in Visual Studio

    2. We should all know how to do this one. File > New > Project

 

2) Add a reference to log4net

    1. You can add the reference to your project with Nuget (preferred method), or download the assembly from the log4net site (here).

 

3) Add an Application Configuration file to you’re your Console Application project

Right click the project and select add new item, then select Application Configuration File

 

4) Add log4net Configuration

past this into your newly created app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.SimpleLayout" />
</appender>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
</configuration>

 

5) Add this code to your Console Apps Program.cs file

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

namespace LogTest
{
class Program
{
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));

log.Info("beginning loop");

for (int c = 0; c < 100; ++c)
{
log.DebugFormat("iteration #{0}", c);
}

log.Info("loop has completed");

Console.ReadLine();
}
}
}

 

6 Run the console app

Your should see the out put displayed in the console and if you check the programs Bin > Debug folder you will see the consoles output duplicated in a log file.

March 19
Can’t find Master Page under Site Actions >Site Settings > Look and Feel

You must be a Site Collection Administrator.

1) Go to: Site Actions > Site Settings

2) Under Site Collection Administration click Site Collection Features

3) Find the SharePoint Server Publishing Infrastructure feature and activate it

4) Go back to Site Settings

5) Under Site Settings click Manage Site Features

6) Find the SharePoint Server Publishing Feature and activate it as well.

7) Go back to Site Setting and you should now have the Master Page option under Look and Feel