Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added some capabilities to your library #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 29 additions & 26 deletions DynamicRest.sln
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamicRest", "DynamicRest\DynamicRest.csproj", "{6761F94D-EFCD-49C7-9E8E-ECBCA014FF63}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "Samples\Samples.csproj", "{6761F94D-EFCD-49C7-9E8E-ECBCA014FF64}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF63}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF63}.Release|Any CPU.Build.0 = Release|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF64}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamicRest", "DynamicRest\DynamicRest.csproj", "{6761F94D-EFCD-49C7-9E8E-ECBCA014FF63}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "Samples\Samples.csproj", "{6761F94D-EFCD-49C7-9E8E-ECBCA014FF64}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF63}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF63}.Release|Any CPU.Build.0 = Release|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6761F94D-EFCD-49C7-9E8E-ECBCA014FF64}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Samples\Samples.csproj
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
7 changes: 1 addition & 6 deletions DynamicRest/DynamicRest.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand Down Expand Up @@ -30,18 +30,13 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml" />
</ItemGroup>
Expand Down
107 changes: 102 additions & 5 deletions DynamicRest/RestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,71 @@ public sealed class RestClient : DynamicObject {
private string _operationGroup;
private Dictionary<string, object> _parameters;
private ICredentials _credentials;
private Tuple<string,string> _basicAuth;
private List<string> _operationsWhichPost;

public RestClient(string uriFormat, RestService service) {
_uriFormat = uriFormat;
_service = service;
}

private RestClient(string uriFormat, RestService service, string operationGroup, Dictionary<string, object> inheritedParameters)
public RestClient(string uriFormat, RestService service, List<string> postOperations)
: this(uriFormat, service) {
_operationsWhichPost = postOperations;
}

private RestClient(string uriFormat, RestService service, string operationGroup,
Dictionary<string, object> inheritedParameters)
: this(uriFormat, service) {
_operationGroup = operationGroup;
_parameters = inheritedParameters;
}

private RestClient(string uriFormat, RestService service, string operationGroup,
Dictionary<string, object> inheritedParameters, List<string> postOperations)
: this(uriFormat, service, operationGroup, inheritedParameters) {
_operationsWhichPost = postOperations;
}

private HttpWebRequest CreateRequest(string operationName, JsonObject parameters) {
Uri requestUri = CreateRequestUri(operationName, parameters);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(requestUri);
Uri requestUri;
HttpWebRequest webRequest;

if(null != _operationsWhichPost && _operationsWhichPost.Contains(operationName))
{
// POST operations don't take their parameters on the querystring
requestUri = CreateRequestUri(operationName, new JsonObject());
} else {
requestUri = CreateRequestUri(operationName, parameters);
}

webRequest = (HttpWebRequest)WebRequest.Create(requestUri);

if (_credentials != null) {
webRequest.Credentials = _credentials;
}

if(_basicAuth != null) {
string authInfo = _basicAuth.Item1 + ":" + _basicAuth.Item2;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
webRequest.Headers["Authorization"] = "Basic " + authInfo;
}

if(null != _operationsWhichPost && _operationsWhichPost.Contains(operationName))
{
// format as a POST request
byte[] body = Encoding.UTF8.GetBytes(CreatePostBody(parameters));
webRequest.Method = "POST";
webRequest.ContentLength = body.Length;
webRequest.ContentType = "application/x-www-form-urlencoded";

// send up the body
using (var requestStream = webRequest.GetRequestStream())
{
requestStream.Write( body, 0, body.Length );
}
}

return webRequest;
}

Expand Down Expand Up @@ -138,6 +183,43 @@ private Uri CreateRequestUri(string operationName, JsonObject parameters) {
return uri;
}

private string CreatePostBody(JsonObject parameters) {
StringBuilder bodyBuilder = new StringBuilder();

if (parameters != null) {
foreach (KeyValuePair<string, object> param in (IDictionary<string, object>)parameters) {
string name = param.Key;
object value = param.Value;

if (value is Delegate) {
// Ignore callbacks in the async scenario.
continue;
}

if (value is JsonObject) {
// Nested object... use name.subName=value format.

foreach (KeyValuePair<string, object> nestedParam in (IDictionary<string, object>)value) {
bodyBuilder.AppendFormat("&{0}.{1}={2}",
name, nestedParam.Key,
FormatUriParameter(nestedParam.Value));
}

continue;
}

bodyBuilder.AppendFormat("&{0}={1}", name, FormatUriParameter(value));
}
}

// ignore the leading "&"
try {
bodyBuilder.Remove(0, 1);
} catch(ArgumentOutOfRangeException) { }

return bodyBuilder.ToString();
}

private string FormatUriParameter(object value) {
if (value is IEnumerable<string>) {
return String.Join("+", (IEnumerable<string>)value);
Expand Down Expand Up @@ -267,8 +349,15 @@ public override bool TryGetMember(GetMemberBinder binder, out object result) {
operationGroup = _operationGroup + "." + operationGroup;
}

RestClient operationGroupClient =
new RestClient(_uriFormat, _service, operationGroup, _parameters);
RestClient operationGroupClient;
if(null != _operationsWhichPost)
{
operationGroupClient =
new RestClient(_uriFormat, _service, operationGroup, _parameters, _operationsWhichPost);
} else {
operationGroupClient =
new RestClient(_uriFormat, _service, operationGroup, _parameters);
}

result = operationGroupClient;
return true;
Expand Down Expand Up @@ -313,6 +402,14 @@ public RestClient WithCredentials(ICredentials credentials) {
return this;
}

// 2011-05-14 Matt Cooper
// Add a WithBasicAuth method to support Untappd
public RestClient WithBasicAuth(string Username, string Password) {
_basicAuth = new Tuple<string, string>(Username, Password);
return this;
}
// end changes

public RestClient WithUriTransformer(IRestUriTransformer uriTransformer) {
if (uriTransformer == null) {
throw new ArgumentNullException("uriTransformer");
Expand Down
6 changes: 6 additions & 0 deletions Samples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ public static void Main(string[] args) {
Console.WriteLine("Google Search Sample");
Console.WriteLine(HeaderBar);
GoogleSearchSample.Run();
Console.WriteLine(Separator);

// Untappd Checkin
Console.WriteLine("Untappd Checkin Sample");
Console.WriteLine(HeaderBar);
UntappdSample.Run();
Console.WriteLine(Separator);

Console.ReadLine();
Expand Down
5 changes: 2 additions & 3 deletions Samples/Samples.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand Down Expand Up @@ -34,11 +34,9 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml" />
</ItemGroup>
Expand All @@ -54,6 +52,7 @@
<Compile Include="BingSearchSample.cs" />
<Compile Include="JsonSample.cs" />
<Compile Include="FlickrSample.cs" />
<Compile Include="UntappdSample.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DynamicRest\DynamicRest.csproj">
Expand Down
5 changes: 5 additions & 0 deletions Samples/Services.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,10 @@ internal static class Services {
public const string BingApiKey = "???";

public const string GoogleSearchUri = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0";

public const string UntappdUri = "http://api.untappd.com/v3/{operation}?key={apiKey}";
public const string UntappdApiKey = "???";
public const string UntappdCheckinAs = "???";
public const string UntappdCheckinAsPassword = "???";
}
}
51 changes: 51 additions & 0 deletions Samples/UntappdSample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// UntappdSample.cs
// DynamicRest provides REST service access using C# 4.0 dynamic programming.
// The latest information and code for the project can be found at
// https://github.com/NikhilK/dynamicrest
//
// This project is licensed under the BSD license. See the License.txt file for
// more information.
//

using System;
using DynamicRest;
using System.Collections.Generic;
using System.Text;

namespace Application {

internal static class UntappdSample {

public static void Run() {
List<string> PostOps = new List<string>()
{
"checkin_test",
};
dynamic untappd = new RestClient(Services.UntappdUri, RestService.Json, PostOps);
untappd.apiKey = Services.UntappdApiKey;
untappd = untappd.WithBasicAuth(Services.UntappdCheckinAs, MD5(Services.UntappdCheckinAsPassword));

Console.WriteLine("Checking in");

dynamic checkinOptions = new JsonObject();
checkinOptions.gmt_offset = -8;
checkinOptions.bid = 1;

dynamic checkin = untappd.checkin_test(checkinOptions);
Console.WriteLine(string.Format("That was checkin ID #{0}",checkin.Result.checkin_details.checkin_id));
}

private static string MD5(string Input)
{
// from http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx
System.Security.Cryptography.MD5 Md5Hasher = System.Security.Cryptography.MD5.Create();
byte[] data = Md5Hasher.ComputeHash(Encoding.Default.GetBytes(Input));
StringBuilder sb = new StringBuilder();
foreach(byte b in data)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
}
}