Thursday, October 18, 2012

How to upload file using Resty.Net?

The bad news

Most of the REST clients comes with a built in mechanism to upload files. I also have plans to add such a feature in Resty.Net very soon, but as of now it doesn't have easy way to upload files.

The good news

If you are following Resty.Net for sometime then you may know that the goal of Resty.Net is to provide a powerful low level api making it just a thin layer above the HttpWebRequest class provided by dotnet, while also giving the highlevel goodness similar to other existing REST client libraries.

Due to its bare to the metal, low level nature, it is already possible to write codes to upload file using those low level features of Resty.Net. Most of the time if anything can be done through HttpWebRequest class, then it may also be possible to do same using Resty.Net. Here is an example of how you'd do it using the HttpWebRequest class http://www.dotnetthoughts.net/how-to-upload-file-using-httpwebrequest-class/

Ok, I got how to do it with HttpWebRequest. Show me how to do it with Resty.Net

Here is how:


string boundary = Guid.NewGuid().ToString();
RestRequest request = new RestRequest(HttpMethod.POST, new RestUri(_MyUri, "/File"));
request.ContentType = ContentType.MultiPartFormData.WithBoundary(boundary);

string[] files = new string[] 
{ 
"example1.jpg",
"example2.png"
};

IDictionary<string, string> formData = new Dictionary<string, string>
{
 {"Name", "nrip"},
 {"EmailAddress", "nrip@abc.com"},
};

StringBuilder sb = new StringBuilder();

foreach (var file in files)
{
 sb.AppendFormat("--{0}", boundary);
 sb.AppendFormat("\r\n");
 sb.AppendFormat("Content-Disposition: form-data; name=\"media\"; filename=\"" + Path.GetFileName(file) + "\"");
 sb.AppendFormat("\r\n");
 sb.AppendFormat("Content-Type:  " + MimeTypes.GetMimeType(Path.GetExtension(file)) ?? ContentType.ApplicationOctetStream.ToString());
 sb.AppendFormat("\r\n");
 sb.AppendFormat("\r\n");
 using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
 {
  byte[] contents = new byte[fs.Length];
  fs.Read(contents, 0, contents.Length);
  sb.Append(Encoding.Default.GetString(contents));
 }
 sb.AppendFormat("\r\n");
}

foreach (var keyvaluepair in formData)
{
 sb.AppendFormat("--{0}", boundary);
 sb.AppendFormat("\r\n");
 sb.AppendFormat("Content-Disposition: form-data; name=\"" + keyvaluepair.Key + "\"");
 sb.AppendFormat("\r\n");
 sb.AppendFormat("\r\n");
 sb.AppendFormat(keyvaluepair.Value);
 sb.AppendFormat("\r\n");
}

sb.AppendFormat("--{0}--", boundary);
byte[] fulldata = Encoding.Default.GetBytes(sb.ToString());

var body = new RestRawRequestBody(fulldata);
request.Body = body;

//Actual posting of body content will occure herer
var response = request.GetResponse();

Most of the part would be very comparable to the original post, constructing the multi-part form data structure. Resty.Net has a Body type called RestRawRequestBody, which takes raw byte array (byte[]) as the body content. Body content are sent to the server, obviously putting them in the Request body. I'll discuss more on other RestBodies available in Resty.Net in future. For now I think the above capability of Resty.Net makes my point clear, the RestRequest class can be utilized to do most of task that can be done through HttpWebRequest. I would dare to put it numerically that 90% of work that can be done using HttpWebRequest can also done using RestRequest of Resty.Net

Wednesday, October 17, 2012

Testing REST clients

Problem

While writing code for Resty.Net I had a problem about how should I deal with the tests. Well I could easily write tests for most of the parts but, I got stock at writing test for the RestRequest class. I thought I could mock RestRequest with a fake implementation. But mocking wouldn't be a solution for my situation. Mocking would have been the perfect solution if I was using Resty.Net in another project, and testing that project. As I'm trying to test if RestRequest itself is implemented correctly or not, mocking RestRequest wasn't the solution.

I thought about mocking the underlying HttpWebRequest, but wasn't quite satisfied with it too.

Search for solution

I did what most of person in the above situation would usually do, I "Googled". After googling for sometimes, changing my keyword combinations and scanning through many pages I finally found a good enough solution at CSharp On The Fritz. Here is the link to the exact post I'm talking about: http://www.csharpfritz.com/post/26765731081/restful-client-unit-testing-with-nancyfx. Yeah, it suggests a neat idea of using embedded NancyFx server and making requests against that server.

The solution

Once I got the inspiring idea of using NancyFx for testing, I did what most of the lazy coders would do, i.e I copied the code at http://www.csharpfritz.com/post/26765731081/restful-client-unit-testing-with-nancyfx, and began writing tests. All went quite well for sometime, then as the number of tests increased the tests began to fail. The problem was, the port sometimes didn't get released by a previous tests, while the new test was already running. Now, I had to make changes to the basic code that I had CTRL+Ced and CTRL+Ved.

Here's my solution:

public class NancyHostHelper
{
 protected Uri _uri = new Uri("http://localhost:50001");
 private NancyHost _Nancy;
 private static int port = 50001;

 public Uri Start()
 {
  bool nancyStarted = false;
  // Need to retry in order to ensure that we properly startup after any failures
  for (var i = 0; i < 3; i++)
  {
   _Nancy = new NancyHost(_uri);

   try
   {
    _Nancy.Start();
    nancyStarted = true;
    break;
   }
   catch (HttpListenerException)
   {
    UriBuilder ub = new UriBuilder(_uri);
    ub.Port = ++port;
    _uri = ub.Uri;
   }
   catch
   {
    try
    {
     _Nancy.Stop();
    }
    catch (Exception e)
    {
    }
   }
  }

  if (!nancyStarted)
  {
   //Don't allow to run the tests if Nancy not started.
   throw new Exception();
  }

  return _uri;
 }

 public void Stop()
 {
  try
  {
   _Nancy.Stop();
   _Nancy = null;
  }
  catch { }
 }
}
Well the solution as you can see above is:
  • Increment the port number and,
  • Try restarting the server again, at new incremented port number.

You, can see the practical usage of the above class in the github repository for Resty.Net at https://github.com/nripendra/Resty.Net/blob/master/tests/Resty.Net.Tests/RestRequestTest.cs.

So far its working quite well, I'll keep updating this blog if anything comes up that makes it necessary to make other changes to the above code.

Saturday, October 13, 2012

RestUri in Resty.Net

Uris are very much basic part of the whole REST conceptual model, the Uniform Resource Locator (Uri) points to a unique resource. REST is all about performing operation on those resources. The RestUri class in Resty.Net is divided into mainly two parts:
  1. The Base Uri.
  2. The Resource Uri

The Base Uri:

The base Uri points the server where the REST resources exists. eg: http://localhost/ , https://localhost/ , https://locahost:50001 , etc. 

The Resource Uri:

The resource Uri points to the resource on the server. e.g. /Person, /Person/1, /book etc. The resource uri can be resource template which has variables embedded, e.g. /Person/{id}

API documentation:


Constructors:
  • RestUri(string baseUri)
    • Instantiate a RestUri with the complete url in a single string. 
      • e.g new RestUri("http://example.com/Person/{id}");
  • RestUri(string baseUri, string resourceUri)
    • Instantiate a RestUri with base url set to baseUri and the resource uri template set to resourceUri.
      • e.g. new RestUri("http://example.com","/Person/{id}");
  • RestUri(Uri baseUri, string resourceUri)
  • RestUri(Uri baseUri, Uri resourceUri)

Methods:
  • SetQuery(string name, object value)
    • Set a querystring parameter for the RestUri instance. Returns the current instance of RestUri hence making it possible to chain the methods in fluent manner.
      • e.g. new RestUri("http://example.com","/Person").SetQuery("searchTerm", "bob")
      • => http://example.com/Person?searchTerm=bob
  • SetQuery(object queryParams)
    • Set a querystring parameter for the RestUri instance. Returns the current instance of RestUri hence making it possible to chain the methods in fluent manner.
      • e.g. new RestUri("http://example.com","/Person/{id}").SetQuery(new { searchTerm = "bob"})
      • => http://example.com/Person?searchTerm=bob
  • SetParameter(string name, object value)
    • Set uri template parameter value.
      • e.g. new RestUri("http://example.com","/Person/{id}").SetParameter("id", 1)
      • => http://example.com/Person/1
  • SetParameter(object uriTemplateParams)
    • Set uri template parameter value.
      • e.g. new RestUri("http://example.com","/Person/{id}").SetParameter(new {id = 1})
      • => http://example.com/Person/1

Properties:
  • BaseUri
    • Gets the base uri of a request.

Setting multiple querystrings


Fluent style:
new RestUri("http://example.com","/Person")
        .SetQuery("searchTerm", "bob")
        .SetQuery("page",1)
        .SetQuery("perpage", 10);
=> http://example.com/Person?searchTerm=bob&page=1&perpage=10

Anonymous style:
new RestUri("http://example.com","/Person")
        .SetQuery(new {searchTerm = "bob", page= 1,perpage=10});
=> http://example.com/Person?searchTerm=bob&page=1&perpage=10

Setting multiple template parameters


Fluent style:
new RestUri("http://example.com","/Person/{searchTemr}/{page}/{perpage}")
        .SetParameter("searchTerm","bob")
        .SetParameter("page", 1)
        .SetParameter("perpage", 10);
=> http://example.com/Person/bob/1/10

Anonymous style:
new RestUri("http://example.com","/Person/{searchTemr}/{page}/{perpage}")
        .SetParameter(new{searchTerm = "bob", page= 1,perpage=10});
=> http://example.com/Person/bob/1/10

How RestUri sits together with RestRequest?

RestUri restUri = new RestUri("http://example.com","/Person/{searchTemr}/{page}/{perpage}").SetParameter(new{searchTerm = "bob", page= 1,perpage=10});
RestRequest request = new RestRequest(HttpMethod.Get, restUri);

Monday, October 8, 2012

Introducing Resty.Net

Well it's been very long since I last blogged, I was waiting to stumble some new experience worth sharing. Today I'd like to introduce my first ever open source project Resty.Net hosted in github.

So what is Resty.Net?

Resty.Net is a simple bare to metal REST/HTTP client for .net framework written in c#. It serves as a very thin layer above the HttpWebRequest object and exposes most of the properties available in HttpWebRequest.

Why another Rest client?

It's true that there are many rest clients for dotnet framework. I have used the HttpClient from microsoft, I have also used another mature and inspirational and superb Restsharp library. I have liked both of them quite well. But I needed something quite lightweight, and something that gave me more control over the underlying HttpWebRequest. In fact I wanted to use HttpWebRequest directly but with all the strongly typed supports and the API goodness that HttpClient and RestSharp provided. So, the result is Resty.Net.

Well I had been planning for an open-source project for a long time, but the dream hadn't materialized till now, so when I created this rest client, I thought about open sourcing it.

Some examples.

RestRequest request = new RestRequest(HttpMethod.GET, new RestUri("http://example.com/api", "/Person/{id}").SetParameter("id", "1"));

request.AddHeader(new { header = "value" });
request.AddHeader("header2", "value");

using (RestResponse response = request.GetResponse())
{
  var contentStream = response.Body.ReadAsStream();
  var contentByteArray = response.Body.ReadAsByteArray();
  string contentString = response.Body.ReadAsString();
}

//strongly typed response
RestRequest request2 = new RestRequest(HttpMethod.GET, new RestUri("http://example.com/api", "/Person/{id}").SetParameter("id", "2"));

request.AddHeader(new { header = "value" });
request.AddHeader("header2", "value");

using (RestResponse<person> response = request.GetResponse<person>())
{
  var person = response.Data;
  var email = person.Email;
}

I think the API itself is quite clear, create a RestRequest instance and call it's GetResponse method to send the request to server and get the response from server. RestRequest constructor takes two arguments:
  • The HttpMethod
  • The RestUri.
These two are very important and most basic concepts in Rest apis. To send the content to server (e.g. inPOST method) the Body property must be set. Next thing is to call GetResponse method, which will return an instance of RestResponse. GetResponse also has a strongly typed overload, which will return strongly typed RestResponse and that's it.

Give me Restsharp like RestClient.

If you prefer a RestSharpis api more, then RestInvoker class under Rest.Net.Extras namespace is just the thing for you.
using Rest.Net.Extras;
.
.
.
RestInvoker invoker = new RestInvoker();
RestResponse response invoker.Get(new RestUri("http://example.com/api", "/Person/{id}").SetParameter("id", "2"));

Where is my Fluent API?

The RestRequestBuilder class under Rest.Net.Extras gives you a way to build RestRequest with fluent API.
using Rest.Net.Extras;
.
.
.
RestRequest request = RestRequestBuilder.CreateRequest(HttpMethod.Get, new RestUri("http://example.com/api", "/Person/{id}").SetParameter("id", "2"))
        .WithHeader("accept","application/json")
        .WithHeader("header2","value")
        .WithCookie("cookie1","value");

Where to get it?

Of course in GitHub https://github.com/nripendra/Resty.Net, you can fork it or just clone it locally, and if feeling generous you can also contribute to the project.

I have also uploaded a prelease nuget package at http://nuget.org/packages/Resty.Net/1.0.1-beta.
Since, I have designeted it as a prerelease, -pre flag must be included in nuget install-package command.
Install-Package Resty.Net -Pre

"Include Prelease" dropdown options must be selected when using Nuget package manage GUI or even searching package in nuget.org.

Finally

I have tried to follow principles like DRY, and open-close as far as I understood them. It is by no means complete product and likely to change a lot. I'll try to find time for posting more Resty.Net features in future, and also keep on improving it.

Friday, May 27, 2011

Fluent Validation remote validation

Recently I was looking for a way to do remote validation with FluentValidation, for an asp.net mvc 3 application. But looking at this discussion I think there is no official way to do this right now. Although Jeremy does seem to have plan for this.

http://fluentvalidation.codeplex.com/discussions/258348


So, I had to create my own remote validator extension to FluentValidation. For those who cannot wait for the official remote validation for fluent validation. Here's how I did it.

//Create a validator, that does nothing on the server side.
public class RemoteValidator : PropertyValidator
{
  public string Url { get; private set; }
  public string HttpMethod { get; private set; }
  public string AdditionalFields { get; private set; }

  public RemoteValidator(string errorMessage, 
                         string action, 
                         string controller, 
                         HttpVerbs HttpVerb = HttpVerbs.Get, 
                         string additionalFields = "")
        : base(errorMessage)
  {
    var httpContext = HttpContext.Current;

    if (httpContext == null)
    {
      var request = new HttpRequest("/", "http://ubasolutions.com", "");
      var response = new HttpResponse(new StringWriter());
      httpContext = new HttpContext(request, response);
    }

    var httpContextBase = new HttpContextWrapper(httpContext);
    var routeData = new RouteData();
    var requestContext = new RequestContext(httpContextBase, routeData);

    var helper = new UrlHelper(requestContext);

    Url = helper.Action(action, controller);
    HttpMethod = HttpVerb.ToString();
    AdditionalFields = additionalFields;
  }

  protected override bool IsValid(PropertyValidatorContext context)
  {
    //This is not a server side validation rule. So, should not effect at the server side.
    return true;
  }
}

//Create a MVC wrapper for the validator.
public class RemoteFluentValidationPropertyValidator : 
                 FluentValidationPropertyValidator
{
  private RemoteValidator RemoteValidator
  {
    get { return (RemoteValidator)Validator; }
  }

  public RemoteFluentValidationPropertyValidator(ModelMetadata metadata, 
                                                 ControllerContext controllerContext, 
                                                 PropertyRule propertyDescription, 
                                                 IPropertyValidator validator)
        : base(metadata, controllerContext, propertyDescription, validator)
  {
    ShouldValidate = false;
  }

  public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
  {
    if (!ShouldGenerateClientSideRules()) yield break;

    var formatter = new MessageFormatter().AppendPropertyName(Rule.PropertyDescription);
    string message = formatter.BuildMessage(RemoteValidator.ErrorMessageSource.GetString());

    //This is the rule that asp.net mvc 3, uses for Remote attribute. 
    yield return new ModelClientValidationRemoteRule(message, RemoteValidator.Url, RemoteValidator.HttpMethod, RemoteValidator.AdditionalFields);
  }
}

Thats all. Now you'll have to register the Validator inside the applicaition_start in the global.asax file.

           //Note that I'm using NinjectValidatorFactory for injecting Fluent validation into the modelbinders. So, this configuration may differ a little on every system.
            FluentValidationModelValidationFactory validationFactory = (metadata, context, rule, validator) => new RemoteFluentValidationPropertyValidator(metadata, context, rule, validator);

            FluentValidationModelValidatorProvider.Configure(x => x.Add(typeof(RemoteValidator), validationFactory));

            NinjectValidatorFactory ninjectValidatorFactory = new NinjectValidatorFactory(kernel);
            var validationProvider = new FluentValidationModelValidatorProvider(ninjectValidatorFactory);
            validationProvider.Add(typeof(RemoteValidator), validationFactory);
            ModelValidatorProviders.Providers.Add(validationProvider);
            
            DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
            kernel.Load<FluentValidatorModule>();



How to apply the validation Rule?

Ok, now we will be setting rules for validation.
RuleFor(x => x.UserName).NotEmpty().SetValidator(new RemoteValidator("user name already exists", "ValidateUserName", "Account", System.Web.Mvc.HttpVerbs.Post));

Well, that was quite simple wasn't it?

Here is the code for ValidateUserName Action inside Account controller
        public ActionResult ValidateUserName(string username)
        {
            var user = UserRepository.FindSingleByUsername(username);
            if (user == null)
                return Json(true, JsonRequestBehavior.AllowGet);
            return Json("Username already exists", JsonRequestBehavior.AllowGet);
        }

Thats it folks. Your remote validation is ready to go.

N.B.
You can see that this is just a wrapper around Asp.net mvc's Remote Attribute, and works more or less on same way the Remote attribute would work.

Asp.net mvc 3 unobtrusive validation fires validation on every keyup event. So, I had to change jquery.validate.unobtrusive.js to fire validation only on blur events. I still could not find a reliable way to do this only on the elements with remote validation, since they(microsoft) are doing validation at the form level instead of element level. To be able to set individual settings, a massive rewrite of jquery.validate.unobtrusive.js may be required.

Update May 11, 2012

For all those looking for the change in the way unobtrusive validator works, I will point you to this stack overflow question: http://stackoverflow.com/questions/4798855/mvc-3-specifying-validation-trigger-for-remote-validation

I used the technique mentioned in this answer: http://stackoverflow.com/a/4836653

Thursday, April 21, 2011

Pluggable/Hookable C++ class

disclaimer
C++ gurus please don't shoot me if you find this one offensive.

I was trying to get a pluggable/hookable class that could let access to it's private members to other class which can hook into it. Found a nice enough way to do so using a template method at stack overflow.

http://stackoverflow.com/questions/424104/can-i-access-private-members-from-outside-the-class-without-using-friends

My requirements:
I'm working with the TTF file parser. The basic operations that I know of right now are:
1. read the file.
2. pack the read files into a valid TTF file.

The classes that represent the TTF table should be able to provide a way to other classes to hook into it and change it's state. This is because the font can require many unpredictable transformations. For example transform TTF font to other formats such as SVG, WOFF etc.

The way we would like to transform the font is quite unpredictable.

If anyone knows a better solution, you are always welcome.

Improvements
One area that I think we can improve the implementation is to have a constraint on the template method. So, that only a class inheriting some specific class can hook into the method.

Further note:
It also shows that you should be careful while designing your classes. You may unwittingly open a back door to the class, that may cause a havoc.

I'll try to post example codes in future.

Monday, March 14, 2011

Enums with string values

Many times I've wanted to have enums, that can be represented in both numeric(integer) form and string form. The problem with ToString method is that it is sometimes in not human friendly. For example if I've an enum called "Language" and "ZnCH" as one of its values. Now, lets suppose we want to show users the list of languages available in the site. Using in-built ToString method will just show "ZnCH", while we may be wanting then to see "Simplified Chinese".

Without boring you further let's see how to implement it. We will use System.ComponentModel.DescriptionAttribute to store the string value, and extension method to retrieve the string value. Here's the code
using System;
using System.ComponentModel;

public enum Language : int
{
  [Description("English")]
  EnUS = 1,
  [Description("Simplified chinese")]
  ZhCN = 2
}

public static class EnumExtensions
{
  public static string ToString(this Enum enumInput, bool showFromDescription)
  {
    if (showFromDescription)
    {
      DescriptionAttribute[] descAttributes = (DescriptionAttribute[])enumInput.GetType().GetField(enumInput.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
      if (descAttributes.Length > 0)
      {
        if (!string.IsNullOrWhiteSpace(descAttributes[0].Description))
        {
          return descAttributes[0].Description;
        }
      }
    }
    return enumInput.ToString();
  }
}

public class Program
{
  public static void Main(params string[] args)
  {
    Language lang = Language.ZhCN;
    Console.WriteLine(lang.ToString(true));//outputs "Simplified Chinese"
  }
}