From 182b025129f0ccb72f9a1f17c631f13d3e77aae0 Mon Sep 17 00:00:00 2001 From: david grupp Date: Fri, 3 Oct 2014 18:23:23 -0500 Subject: [PATCH 01/10] merged --- .../Authenticators/HttpBasicAuthenticator.cs | 50 + .../Authenticators/IAuthenticator.cs | 23 + .../Authenticators/NtlmAuthenticator.cs | 65 + .../OAuth/Extensions/CollectionExtensions.cs | 110 + .../OAuth/Extensions/OAuthExtensions.cs | 36 + .../OAuth/Extensions/StringExtensions.cs | 113 + .../OAuth/Extensions/TimeExtensions.cs | 28 + .../Authenticators/OAuth/HttpPostParameter.cs | 42 + .../OAuth/HttpPostParameterType.cs | 13 + .../OAuth/OAuthParameterHandling.cs | 13 + .../OAuth/OAuthSignatureMethod.cs | 14 + .../OAuth/OAuthSignatureTreatment.cs | 13 + .../Authenticators/OAuth/OAuthTools.cs | 341 +++ .../Authenticators/OAuth/OAuthType.cs | 15 + .../Authenticators/OAuth/OAuthWebQueryInfo.cs | 29 + .../Authenticators/OAuth/OAuthWorkflow.cs | 408 ++++ .../Authenticators/OAuth/WebPair.cs | 14 + .../Authenticators/OAuth/WebPairCollection.cs | 192 ++ .../Authenticators/OAuth/WebParameter.cs | 21 + .../OAuth/WebParameterCollection.cs | 37 + .../Authenticators/OAuth1Authenticator.cs | 263 +++ .../Authenticators/OAuth2Authenticator.cs | 120 + .../Authenticators/SimpleAuthenticator.cs | 39 + .../Deserializers/DeserializeAsAttribute.cs | 38 + .../Deserializers/DotNetXmlDeserializer.cs | 47 + .../Deserializers/IDeserializer.cs | 26 + .../Deserializers/JsonDeserializer.cs | 298 +++ .../Deserializers/XmlAttributeDeserializer.cs | 49 + .../Deserializers/XmlDeserializer.cs | 466 ++++ Backup/RestSharp.Silverlight/Enum.cs | 82 + .../Extensions/MiscExtensions.cs | 128 + .../Extensions/ReflectionExtensions.cs | 114 + .../Extensions/ResponseExtensions.cs | 30 + .../Extensions/StringExtensions.cs | 396 ++++ .../Extensions/XmlExtensions.cs | 41 + Backup/RestSharp.Silverlight/FileParameter.cs | 69 + Backup/RestSharp.Silverlight/Http.Async.cs | 460 ++++ Backup/RestSharp.Silverlight/Http.cs | 454 ++++ Backup/RestSharp.Silverlight/HttpCookie.cs | 67 + Backup/RestSharp.Silverlight/HttpFile.cs | 33 + Backup/RestSharp.Silverlight/HttpHeader.cs | 17 + Backup/RestSharp.Silverlight/HttpParameter.cs | 22 + Backup/RestSharp.Silverlight/HttpResponse.cs | 122 + Backup/RestSharp.Silverlight/IHttp.cs | 92 + Backup/RestSharp.Silverlight/IHttpFactory.cs | 15 + Backup/RestSharp.Silverlight/IHttpResponse.cs | 83 + Backup/RestSharp.Silverlight/IRestClient.cs | 222 ++ Backup/RestSharp.Silverlight/IRestRequest.cs | 251 ++ Backup/RestSharp.Silverlight/IRestResponse.cs | 104 + Backup/RestSharp.Silverlight/Parameter.cs | 45 + .../Properties/AssemblyInfo.cs | 16 + .../RestSharp.Silverlight/RestClient.Async.cs | 397 ++++ Backup/RestSharp.Silverlight/RestClient.cs | 533 +++++ .../RestClientExtensions.cs | 333 +++ Backup/RestSharp.Silverlight/RestRequest.cs | 501 ++++ .../RestRequestAsyncHandle.cs | 25 + Backup/RestSharp.Silverlight/RestResponse.cs | 174 ++ .../RestResponseCookie.cs | 64 + .../RestSharp.Silverlight.csproj | 288 +++ .../Serializers/DotNetXmlSerializer.cs | 89 + .../Serializers/ISerializer.cs | 27 + .../Serializers/JsonSerializer.cs | 46 + .../Serializers/SerializeAsAttribute.cs | 92 + .../Serializers/XmlSerializer.cs | 245 ++ .../SharedAssemblyInfo.cs | 37 + Backup/RestSharp.Silverlight/SimpleJson.cs | 2094 +++++++++++++++++ .../Validation/Require.cs | 37 + .../Validation/Validate.cs | 52 + Backup/RestSharp.Silverlight/packages.config | 3 + Backup/RestSharp.sln | 123 + .../RestSharp.Silverlight.csproj | 7 +- RestSharp.sln | 32 +- RestSharp/Http.Async.cs | 826 +++---- RestSharp/Http.Sync.cs | 558 ++--- RestSharp/Http.cs | 6 +- RestSharp/IHttp.cs | 4 +- RestSharp/RestClient.Async.cs | 32 +- RestSharp/RestClient.Sync.cs | 32 +- RestSharp/RestRequest.cs | 22 + 79 files changed, 11720 insertions(+), 745 deletions(-) create mode 100644 Backup/RestSharp.Silverlight/Authenticators/HttpBasicAuthenticator.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/IAuthenticator.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/NtlmAuthenticator.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/CollectionExtensions.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/OAuthExtensions.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/StringExtensions.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/TimeExtensions.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/HttpPostParameter.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/HttpPostParameterType.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthParameterHandling.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthSignatureMethod.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthSignatureTreatment.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthTools.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthType.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthWebQueryInfo.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthWorkflow.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/WebPair.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/WebPairCollection.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/WebParameter.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth/WebParameterCollection.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth1Authenticator.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/OAuth2Authenticator.cs create mode 100644 Backup/RestSharp.Silverlight/Authenticators/SimpleAuthenticator.cs create mode 100644 Backup/RestSharp.Silverlight/Deserializers/DeserializeAsAttribute.cs create mode 100644 Backup/RestSharp.Silverlight/Deserializers/DotNetXmlDeserializer.cs create mode 100644 Backup/RestSharp.Silverlight/Deserializers/IDeserializer.cs create mode 100644 Backup/RestSharp.Silverlight/Deserializers/JsonDeserializer.cs create mode 100644 Backup/RestSharp.Silverlight/Deserializers/XmlAttributeDeserializer.cs create mode 100644 Backup/RestSharp.Silverlight/Deserializers/XmlDeserializer.cs create mode 100644 Backup/RestSharp.Silverlight/Enum.cs create mode 100644 Backup/RestSharp.Silverlight/Extensions/MiscExtensions.cs create mode 100644 Backup/RestSharp.Silverlight/Extensions/ReflectionExtensions.cs create mode 100644 Backup/RestSharp.Silverlight/Extensions/ResponseExtensions.cs create mode 100644 Backup/RestSharp.Silverlight/Extensions/StringExtensions.cs create mode 100644 Backup/RestSharp.Silverlight/Extensions/XmlExtensions.cs create mode 100644 Backup/RestSharp.Silverlight/FileParameter.cs create mode 100644 Backup/RestSharp.Silverlight/Http.Async.cs create mode 100644 Backup/RestSharp.Silverlight/Http.cs create mode 100644 Backup/RestSharp.Silverlight/HttpCookie.cs create mode 100644 Backup/RestSharp.Silverlight/HttpFile.cs create mode 100644 Backup/RestSharp.Silverlight/HttpHeader.cs create mode 100644 Backup/RestSharp.Silverlight/HttpParameter.cs create mode 100644 Backup/RestSharp.Silverlight/HttpResponse.cs create mode 100644 Backup/RestSharp.Silverlight/IHttp.cs create mode 100644 Backup/RestSharp.Silverlight/IHttpFactory.cs create mode 100644 Backup/RestSharp.Silverlight/IHttpResponse.cs create mode 100644 Backup/RestSharp.Silverlight/IRestClient.cs create mode 100644 Backup/RestSharp.Silverlight/IRestRequest.cs create mode 100644 Backup/RestSharp.Silverlight/IRestResponse.cs create mode 100644 Backup/RestSharp.Silverlight/Parameter.cs create mode 100644 Backup/RestSharp.Silverlight/Properties/AssemblyInfo.cs create mode 100644 Backup/RestSharp.Silverlight/RestClient.Async.cs create mode 100644 Backup/RestSharp.Silverlight/RestClient.cs create mode 100644 Backup/RestSharp.Silverlight/RestClientExtensions.cs create mode 100644 Backup/RestSharp.Silverlight/RestRequest.cs create mode 100644 Backup/RestSharp.Silverlight/RestRequestAsyncHandle.cs create mode 100644 Backup/RestSharp.Silverlight/RestResponse.cs create mode 100644 Backup/RestSharp.Silverlight/RestResponseCookie.cs create mode 100644 Backup/RestSharp.Silverlight/RestSharp.Silverlight.csproj create mode 100644 Backup/RestSharp.Silverlight/Serializers/DotNetXmlSerializer.cs create mode 100644 Backup/RestSharp.Silverlight/Serializers/ISerializer.cs create mode 100644 Backup/RestSharp.Silverlight/Serializers/JsonSerializer.cs create mode 100644 Backup/RestSharp.Silverlight/Serializers/SerializeAsAttribute.cs create mode 100644 Backup/RestSharp.Silverlight/Serializers/XmlSerializer.cs create mode 100644 Backup/RestSharp.Silverlight/SharedAssemblyInfo.cs create mode 100644 Backup/RestSharp.Silverlight/SimpleJson.cs create mode 100644 Backup/RestSharp.Silverlight/Validation/Require.cs create mode 100644 Backup/RestSharp.Silverlight/Validation/Validate.cs create mode 100644 Backup/RestSharp.Silverlight/packages.config create mode 100644 Backup/RestSharp.sln diff --git a/Backup/RestSharp.Silverlight/Authenticators/HttpBasicAuthenticator.cs b/Backup/RestSharp.Silverlight/Authenticators/HttpBasicAuthenticator.cs new file mode 100644 index 000000000..272faba16 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/HttpBasicAuthenticator.cs @@ -0,0 +1,50 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Linq; +using System.Text; + +namespace RestSharp +{ + public class HttpBasicAuthenticator : IAuthenticator + { + private readonly string _username; + private readonly string _password; + + public HttpBasicAuthenticator(string username, string password) { + _password = password; + _username = username; + } + + public void Authenticate(IRestClient client, IRestRequest request) { + // NetworkCredentials always makes two trips, even if with PreAuthenticate, + // it is also unsafe for many partial trust scenarios + // request.Credentials = Credentials; + // thanks TweetSharp! + + // request.Credentials = new NetworkCredential(_username, _password); + + // only add the Authorization parameter if it hasn't been added by a previous Execute + if (!request.Parameters.Any(p => p.Name.Equals("Authorization", StringComparison.OrdinalIgnoreCase))) + { + var token = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", _username, _password))); + var authHeader = string.Format("Basic {0}", token); + request.AddParameter("Authorization", authHeader, ParameterType.HttpHeader); + } + } + } +} diff --git a/Backup/RestSharp.Silverlight/Authenticators/IAuthenticator.cs b/Backup/RestSharp.Silverlight/Authenticators/IAuthenticator.cs new file mode 100644 index 000000000..3e340131f --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/IAuthenticator.cs @@ -0,0 +1,23 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace RestSharp +{ + public interface IAuthenticator + { + void Authenticate(IRestClient client, IRestRequest request); + } +} diff --git a/Backup/RestSharp.Silverlight/Authenticators/NtlmAuthenticator.cs b/Backup/RestSharp.Silverlight/Authenticators/NtlmAuthenticator.cs new file mode 100644 index 000000000..6474ab4b7 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/NtlmAuthenticator.cs @@ -0,0 +1,65 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Net; + +#if FRAMEWORK + +namespace RestSharp +{ + /// + /// Tries to Authenticate with the credentials of the currently logged in user, or impersonate a user + /// + public class NtlmAuthenticator : IAuthenticator + { + private readonly ICredentials credentials; + + /// + /// Authenticate with the credentials of the currently logged in user + /// + public NtlmAuthenticator() + : this(CredentialCache.DefaultCredentials) + { + } + + /// + /// Authenticate by impersonation + /// + /// + /// + public NtlmAuthenticator(string username, string password) : this(new NetworkCredential(username, password)) + { + } + + /// + /// Authenticate by impersonation, using an existing ICredentials instance + /// + /// + public NtlmAuthenticator(ICredentials credentials) + { + if (credentials == null) throw new ArgumentNullException("credentials"); + this.credentials = credentials; + } + + public void Authenticate(IRestClient client, IRestRequest request) + { + request.Credentials = credentials; + } + } +} + +#endif \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/CollectionExtensions.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/CollectionExtensions.cs new file mode 100644 index 000000000..9efadeb89 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/CollectionExtensions.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; + +namespace RestSharp.Authenticators.OAuth.Extensions +{ + internal static class CollectionExtensions + { + public static IEnumerable AsEnumerable(this T item) + { + return new[] {item}; + } + + public static IEnumerable And(this T item, T other) + { + return new[] {item, other}; + } + + public static IEnumerable And(this IEnumerable items, T item) + { + foreach (var i in items) + { + yield return i; + } + + yield return item; + } + + public static K TryWithKey(this IDictionary dictionary, T key) + { + return dictionary.ContainsKey(key) ? dictionary[key] : default(K); + } + + public static IEnumerable ToEnumerable(this object[] items) where T : class + { + foreach (var item in items) + { + var record = item as T; + yield return record; + } + } + + public static void ForEach(this IEnumerable items, Action action) + { + foreach (var item in items) + { + action(item); + } + } + +#if !WINDOWS_PHONE && !SILVERLIGHT && !PocketPC + + public static void AddRange(this IDictionary collection, NameValueCollection range) + { + foreach (var key in range.AllKeys) + { + collection.Add(key, range[key]); + } + } + + public static string ToQueryString(this NameValueCollection collection) + { + var sb = new StringBuilder(); + if (collection.Count > 0) + { + sb.Append("?"); + } + + var count = 0; + foreach (var key in collection.AllKeys) + { + sb.AppendFormat("{0}={1}", key, collection[key].UrlEncode()); + count++; + + if (count >= collection.Count) + { + continue; + } + sb.Append("&"); + } + return sb.ToString(); + } + +#endif + + public static string Concatenate(this WebParameterCollection collection, string separator, string spacer) + { + var sb = new StringBuilder(); + + var total = collection.Count; + var count = 0; + + foreach (var item in collection) + { + sb.Append(item.Name); + sb.Append(separator); + sb.Append(item.Value); + + count++; + if (count < total) + { + sb.Append(spacer); + } + } + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/OAuthExtensions.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/OAuthExtensions.cs new file mode 100644 index 000000000..f87c2609a --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/OAuthExtensions.cs @@ -0,0 +1,36 @@ +using System; +using System.Security.Cryptography; +using System.Text; + +namespace RestSharp.Authenticators.OAuth.Extensions +{ + internal static class OAuthExtensions + { + public static string ToRequestValue(this OAuthSignatureMethod signatureMethod) + { + var value = signatureMethod.ToString().ToUpper(); + var shaIndex = value.IndexOf("SHA1"); + return shaIndex > -1 ? value.Insert(shaIndex, "-") : value; + } + + public static OAuthSignatureMethod FromRequestValue(this string signatureMethod) + { + switch (signatureMethod) + { + case "HMAC-SHA1": + return OAuthSignatureMethod.HmacSha1; + case "RSA-SHA1": + return OAuthSignatureMethod.RsaSha1; + default: + return OAuthSignatureMethod.PlainText; + } + } + + public static string HashWith(this string input, HashAlgorithm algorithm) + { + var data = Encoding.UTF8.GetBytes(input); + var hash = algorithm.ComputeHash(data); + return Convert.ToBase64String(hash); + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/StringExtensions.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/StringExtensions.cs new file mode 100644 index 000000000..4dd7ae3f9 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/StringExtensions.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace RestSharp.Authenticators.OAuth.Extensions +{ + internal static class StringExtensions + { + public static bool IsNullOrBlank(this string value) + { + return String.IsNullOrEmpty(value) || + (!String.IsNullOrEmpty(value) && value.Trim() == String.Empty); + } + + public static bool EqualsIgnoreCase(this string left, string right) + { + return String.Compare(left, right, StringComparison.OrdinalIgnoreCase) == 0; + } + + public static bool EqualsAny(this string input, params string[] args) + { + return args.Aggregate(false, (current, arg) => current | input.Equals(arg)); + } + + public static string FormatWith(this string format, params object[] args) + { + return String.Format(format, args); + } + + public static string FormatWithInvariantCulture(this string format, params object[] args) + { + return String.Format(CultureInfo.InvariantCulture, format, args); + } + + public static string Then(this string input, string value) + { + return String.Concat(input, value); + } + + public static string UrlEncode(this string value) + { + // [DC] This is more correct than HttpUtility; it escapes spaces as %20, not + + return Uri.EscapeDataString(value); + } + + public static string UrlDecode(this string value) + { + return Uri.UnescapeDataString(value); + } + + public static Uri AsUri(this string value) + { + return new Uri(value); + } + + public static string ToBase64String(this byte[] input) + { + return Convert.ToBase64String(input); + } + + public static byte[] GetBytes(this string input) + { + return Encoding.UTF8.GetBytes(input); + } + + public static string PercentEncode(this string s) + { + var bytes = s.GetBytes(); + var sb = new StringBuilder(); + foreach (var b in bytes) + { + // [DC]: Support proper encoding of special characters (\n\r\t\b) + if ((b > 7 && b < 11) || b == 13) + { + sb.Append(string.Format("%0{0:X}", b)); + } + else + { + sb.Append(string.Format("%{0:X}", b)); + } + } + return sb.ToString(); + } + + public static IDictionary ParseQueryString(this string query) + { + // [DC]: This method does not URL decode, and cannot handle decoded input + if (query.StartsWith("?")) query = query.Substring(1); + + if (query.Equals(string.Empty)) + { + return new Dictionary(); + } + + var parts = query.Split(new[] {'&'}); + + return parts.Select( + part => part.Split(new[] {'='})).ToDictionary( + pair => pair[0], pair => pair[1] + ); + } + + private const RegexOptions Options = +#if !WINDOWS_PHONE && !SILVERLIGHT && !PocketPC + RegexOptions.Compiled | RegexOptions.IgnoreCase; +#else + RegexOptions.IgnoreCase; +#endif + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/TimeExtensions.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/TimeExtensions.cs new file mode 100644 index 000000000..1c06cc81e --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/Extensions/TimeExtensions.cs @@ -0,0 +1,28 @@ +using System; + +namespace RestSharp.Authenticators.OAuth.Extensions +{ + internal static class TimeExtensions + { + public static DateTime FromNow(this TimeSpan value) + { + return new DateTime((DateTime.Now + value).Ticks); + } + + public static DateTime FromUnixTime(this long seconds) + { + var time = new DateTime(1970, 1, 1); + time = time.AddSeconds(seconds); + + return time.ToLocalTime(); + } + + public static long ToUnixTime(this DateTime dateTime) + { + var timeSpan = (dateTime - new DateTime(1970, 1, 1)); + var timestamp = (long) timeSpan.TotalSeconds; + + return timestamp; + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/HttpPostParameter.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/HttpPostParameter.cs new file mode 100644 index 000000000..0c930b18c --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/HttpPostParameter.cs @@ -0,0 +1,42 @@ +using System.IO; + +namespace RestSharp.Authenticators.OAuth +{ + internal class HttpPostParameter : WebParameter + { + public HttpPostParameter(string name, string value) : base(name, value) + { + } + + public virtual HttpPostParameterType Type { get; private set; } + public virtual string FileName { get; private set; } + public virtual string FilePath { get; private set; } + public virtual Stream FileStream { get; set; } + public virtual string ContentType { get; private set; } + + public static HttpPostParameter CreateFile(string name, string fileName, string filePath, string contentType) + { + var parameter = new HttpPostParameter(name, string.Empty) + { + Type = HttpPostParameterType.File, + FileName = fileName, + FilePath = filePath, + ContentType = contentType, + }; + return parameter; + } + + public static HttpPostParameter CreateFile(string name, string fileName, Stream fileStream, string contentType) + { + var parameter = new HttpPostParameter(name, string.Empty) + { + Type = HttpPostParameterType.File, + FileName = fileName, + FileStream = fileStream, + ContentType = contentType, + }; + + return parameter; + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/HttpPostParameterType.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/HttpPostParameterType.cs new file mode 100644 index 000000000..7dbce9a92 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/HttpPostParameterType.cs @@ -0,0 +1,13 @@ +using System; + +namespace RestSharp.Authenticators.OAuth +{ +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + [Serializable] +#endif + internal enum HttpPostParameterType + { + Field, + File + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthParameterHandling.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthParameterHandling.cs new file mode 100644 index 000000000..3a7428c9a --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthParameterHandling.cs @@ -0,0 +1,13 @@ +using System; + +namespace RestSharp.Authenticators.OAuth +{ +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + [Serializable] +#endif + public enum OAuthParameterHandling + { + HttpAuthorizationHeader, + UrlOrPostParameters + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthSignatureMethod.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthSignatureMethod.cs new file mode 100644 index 000000000..47d9266f1 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthSignatureMethod.cs @@ -0,0 +1,14 @@ +using System; + +namespace RestSharp.Authenticators.OAuth +{ +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + [Serializable] +#endif + public enum OAuthSignatureMethod + { + HmacSha1, + PlainText, + RsaSha1 + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthSignatureTreatment.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthSignatureTreatment.cs new file mode 100644 index 000000000..3253a75ae --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthSignatureTreatment.cs @@ -0,0 +1,13 @@ +using System; + +namespace RestSharp.Authenticators.OAuth +{ +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + [Serializable] +#endif + public enum OAuthSignatureTreatment + { + Escaped, + Unescaped + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthTools.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthTools.cs new file mode 100644 index 000000000..0c6b421c3 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthTools.cs @@ -0,0 +1,341 @@ +using System; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using RestSharp.Authenticators.OAuth.Extensions; + +namespace RestSharp.Authenticators.OAuth +{ +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + [Serializable] +#endif + internal static class OAuthTools + { + private const string AlphaNumeric = Upper + Lower + Digit; + private const string Digit = "1234567890"; + private const string Lower = "abcdefghijklmnopqrstuvwxyz"; + private const string Unreserved = AlphaNumeric + "-._~"; + private const string Upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + private static readonly Random _random; + private static readonly object _randomLock = new object(); + +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); +#endif + + static OAuthTools() + { +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + var bytes = new byte[4]; + _rng.GetNonZeroBytes(bytes); + _random = new Random(BitConverter.ToInt32(bytes, 0)); +#else + _random = new Random(); +#endif + } + + /// + /// All text parameters are UTF-8 encoded (per section 5.1). + /// + /// + private static readonly Encoding _encoding = Encoding.UTF8; + + /// + /// Generates a random 16-byte lowercase alphanumeric string. + /// + /// + /// + public static string GetNonce() + { + const string chars = (Lower + Digit); + + var nonce = new char[16]; + lock (_randomLock) + { + for (var i = 0; i < nonce.Length; i++) + { + nonce[i] = chars[_random.Next(0, chars.Length)]; + } + } + return new string(nonce); + } + + /// + /// Generates a timestamp based on the current elapsed seconds since '01/01/1970 0000 GMT" + /// + /// + /// + public static string GetTimestamp() + { + return GetTimestamp(DateTime.UtcNow); + } + + /// + /// Generates a timestamp based on the elapsed seconds of a given time since '01/01/1970 0000 GMT" + /// + /// + /// A specified point in time. + /// + public static string GetTimestamp(DateTime dateTime) + { + var timestamp = dateTime.ToUnixTime(); + return timestamp.ToString(); + } + + /// + /// The set of characters that are unreserved in RFC 2396 but are NOT unreserved in RFC 3986. + /// + /// + private static readonly string[] UriRfc3986CharsToEscape = new[] { "!", "*", "'", "(", ")" }; + + private static readonly string[] UriRfc3968EscapedHex = new[] {"%21", "%2A", "%27", "%28", "%29"}; + + /// + /// URL encodes a string based on section 5.1 of the OAuth spec. + /// Namely, percent encoding with [RFC3986], avoiding unreserved characters, + /// upper-casing hexadecimal characters, and UTF-8 encoding for text value pairs. + /// + /// The value to escape. + /// The escaped value. + /// + /// The method is supposed to take on + /// RFC 3986 behavior if certain elements are present in a .config file. Even if this + /// actually worked (which in my experiments it doesn't), we can't rely on every + /// host actually having this configuration element present. + /// + /// + /// + public static string UrlEncodeRelaxed(string value) + { + // Start with RFC 2396 escaping by calling the .NET method to do the work. + // This MAY sometimes exhibit RFC 3986 behavior (according to the documentation). + // If it does, the escaping we do that follows it will be a no-op since the + // characters we search for to replace can't possibly exist in the string. + StringBuilder escaped = new StringBuilder(Uri.EscapeDataString(value)); + + // Upgrade the escaping to RFC 3986, if necessary. + for (int i = 0; i < UriRfc3986CharsToEscape.Length; i++) + { + string t = UriRfc3986CharsToEscape[i]; + escaped.Replace(t, UriRfc3968EscapedHex[i]); + } + + // Return the fully-RFC3986-escaped string. + return escaped.ToString(); + } + + /// + /// URL encodes a string based on section 5.1 of the OAuth spec. + /// Namely, percent encoding with [RFC3986], avoiding unreserved characters, + /// upper-casing hexadecimal characters, and UTF-8 encoding for text value pairs. + /// + /// + /// + public static string UrlEncodeStrict(string value) + { + // [JD]: We need to escape the apostrophe as well or the signature will fail + var original = value; + var ret = original.Where( + c => !Unreserved.Contains(c) && c != '%').Aggregate( + value, (current, c) => current.Replace( + c.ToString(), c.ToString().PercentEncode() + )); + + return ret.Replace("%%", "%25%"); // Revisit to encode actual %'s + } + + /// + /// Sorts a collection of key-value pairs by name, and then value if equal, + /// concatenating them into a single string. This string should be encoded + /// prior to, or after normalization is run. + /// + /// + /// + /// + public static string NormalizeRequestParameters(WebParameterCollection parameters) + { + var copy = SortParametersExcludingSignature(parameters); + var concatenated = copy.Concatenate("=", "&"); + return concatenated; + } + + /// + /// Sorts a by name, and then value if equal. + /// + /// A collection of parameters to sort + /// A sorted parameter collection + public static WebParameterCollection SortParametersExcludingSignature(WebParameterCollection parameters) + { + var copy = new WebParameterCollection(parameters); + var exclusions = copy.Where(n => n.Name.EqualsIgnoreCase("oauth_signature")); + + copy.RemoveAll(exclusions); + copy.ForEach(p => { p.Name = UrlEncodeStrict(p.Name); p.Value = UrlEncodeStrict(p.Value); }); + copy.Sort( + (x, y) => + string.CompareOrdinal(x.Name, y.Name) != 0 + ? string.CompareOrdinal(x.Name, y.Name) + : string.CompareOrdinal(x.Value, y.Value)); + return copy; + } + + /// + /// Creates a request URL suitable for making OAuth requests. + /// Resulting URLs must exclude port 80 or port 443 when accompanied by HTTP and HTTPS, respectively. + /// Resulting URLs must be lower case. + /// + /// + /// The original request URL + /// + public static string ConstructRequestUrl(Uri url) + { + if (url == null) + { + throw new ArgumentNullException("url"); + } + + var sb = new StringBuilder(); + + var requestUrl = "{0}://{1}".FormatWith(url.Scheme, url.Host); + var qualified = ":{0}".FormatWith(url.Port); + var basic = url.Scheme == "http" && url.Port == 80; + var secure = url.Scheme == "https" && url.Port == 443; + + sb.Append(requestUrl); + sb.Append(!basic && !secure ? qualified : ""); + sb.Append(url.AbsolutePath); + + return sb.ToString(); //.ToLower(); + } + + /// + /// Creates a request elements concatentation value to send with a request. + /// This is also known as the signature base. + /// + /// + /// + /// The request's HTTP method type + /// The request URL + /// The request's parameters + /// A signature base string + public static string ConcatenateRequestElements(string method, string url, WebParameterCollection parameters) + { + var sb = new StringBuilder(); + + // Separating &'s are not URL encoded + var requestMethod = method.ToUpper().Then("&"); + var requestUrl = UrlEncodeRelaxed(ConstructRequestUrl(url.AsUri())).Then("&"); + var requestParameters = UrlEncodeRelaxed(NormalizeRequestParameters(parameters)); + + sb.Append(requestMethod); + sb.Append(requestUrl); + sb.Append(requestParameters); + + return sb.ToString(); + } + + /// + /// Creates a signature value given a signature base and the consumer secret. + /// This method is used when the token secret is currently unknown. + /// + /// + /// The hashing method + /// The signature base + /// The consumer key + /// + public static string GetSignature(OAuthSignatureMethod signatureMethod, string signatureBase, string consumerSecret) + { + return GetSignature(signatureMethod, OAuthSignatureTreatment.Escaped, signatureBase, consumerSecret, null); + } + + /// + /// Creates a signature value given a signature base and the consumer secret. + /// This method is used when the token secret is currently unknown. + /// + /// + /// The hashing method + /// The treatment to use on a signature value + /// The signature base + /// The consumer key + /// + public static string GetSignature(OAuthSignatureMethod signatureMethod, OAuthSignatureTreatment signatureTreatment, string signatureBase, string consumerSecret) + { + return GetSignature(signatureMethod, signatureTreatment, signatureBase, consumerSecret, null); + } + + /// + /// Creates a signature value given a signature base and the consumer secret and a known token secret. + /// + /// + /// The hashing method + /// The signature base + /// The consumer secret + /// The token secret + /// + public static string GetSignature(OAuthSignatureMethod signatureMethod, string signatureBase, string consumerSecret, string tokenSecret) + { + return GetSignature(signatureMethod, OAuthSignatureTreatment.Escaped, consumerSecret, tokenSecret); + } + + /// + /// Creates a signature value given a signature base and the consumer secret and a known token secret. + /// + /// + /// The hashing method + /// The treatment to use on a signature value + /// The signature base + /// The consumer secret + /// The token secret + /// + public static string GetSignature(OAuthSignatureMethod signatureMethod, + OAuthSignatureTreatment signatureTreatment, + string signatureBase, + string consumerSecret, + string tokenSecret) + { + if (tokenSecret.IsNullOrBlank()) + { + tokenSecret = String.Empty; + } + + consumerSecret = UrlEncodeRelaxed(consumerSecret); + tokenSecret = UrlEncodeRelaxed(tokenSecret); + + string signature; + switch (signatureMethod) + { +#if !PocketPC + case OAuthSignatureMethod.HmacSha1: + { + var crypto = new HMACSHA1(); + var key = "{0}&{1}".FormatWith(consumerSecret, tokenSecret); + + crypto.Key = _encoding.GetBytes(key); + signature = signatureBase.HashWith(crypto); + + break; + } +#endif + case OAuthSignatureMethod.PlainText: + { + signature = "{0}&{1}".FormatWith(consumerSecret, tokenSecret); + + break; + } + default: +#if PocketPC + throw new NotImplementedException("Only PlainText is currently supported."); +#else + throw new NotImplementedException("Only HMAC-SHA1 is currently supported."); +#endif + } + + var result = signatureTreatment == OAuthSignatureTreatment.Escaped + ? UrlEncodeRelaxed(signature) + : signature; + + return result; + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthType.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthType.cs new file mode 100644 index 000000000..96b05d624 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthType.cs @@ -0,0 +1,15 @@ +using System; + +namespace RestSharp.Authenticators.OAuth +{ +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + [Serializable] +#endif + public enum OAuthType + { + RequestToken, + AccessToken, + ProtectedResource, + ClientAuthentication + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthWebQueryInfo.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthWebQueryInfo.cs new file mode 100644 index 000000000..f1156f4ae --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthWebQueryInfo.cs @@ -0,0 +1,29 @@ +using System; + +namespace RestSharp.Authenticators.OAuth +{ +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + [Serializable] +#endif + public class OAuthWebQueryInfo + { + public virtual string ConsumerKey { get; set; } + public virtual string Token { get; set; } + public virtual string Nonce { get; set; } + public virtual string Timestamp { get; set; } + public virtual string SignatureMethod { get; set; } + public virtual string Signature { get; set; } + public virtual string Version { get; set; } + public virtual string Callback { get; set; } + public virtual string Verifier { get; set; } + public virtual string ClientMode { get; set; } + public virtual string ClientUsername { get; set; } + public virtual string ClientPassword { get; set; } + public virtual string UserAgent { get; set; } + public virtual string WebMethod { get; set; } + public virtual OAuthParameterHandling ParameterHandling { get; set; } + public virtual OAuthSignatureTreatment SignatureTreatment { get; set; } + internal virtual string ConsumerSecret { get; set; } + internal virtual string TokenSecret { get; set; } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthWorkflow.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthWorkflow.cs new file mode 100644 index 000000000..183974b9f --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/OAuthWorkflow.cs @@ -0,0 +1,408 @@ +using System; +using System.Collections.Generic; +using RestSharp.Authenticators.OAuth.Extensions; +#if !WINDOWS_PHONE && !SILVERLIGHT && !PocketPC +using RestSharp.Contrib; +#endif + +namespace RestSharp.Authenticators.OAuth +{ + /// + /// A class to encapsulate OAuth authentication flow. + /// + /// + internal class OAuthWorkflow + { + public virtual string Version { get; set; } + public virtual string ConsumerKey { get; set; } + public virtual string ConsumerSecret { get; set; } + public virtual string Token { get; set; } + public virtual string TokenSecret { get; set; } + public virtual string CallbackUrl { get; set; } + public virtual string Verifier { get; set; } + public virtual string SessionHandle { get; set; } + + public virtual OAuthSignatureMethod SignatureMethod { get; set; } + public virtual OAuthSignatureTreatment SignatureTreatment { get; set; } + public virtual OAuthParameterHandling ParameterHandling { get; set; } + + public virtual string ClientUsername { get; set; } + public virtual string ClientPassword { get; set; } + + /// + public virtual string RequestTokenUrl { get; set; } + + /// + public virtual string AccessTokenUrl { get; set; } + + /// + public virtual string AuthorizationUrl { get; set; } + + /// + /// Generates a instance to pass to an + /// for the purpose of requesting an + /// unauthorized request token. + /// + /// The HTTP method for the intended request + /// + /// + public OAuthWebQueryInfo BuildRequestTokenInfo(string method) + { + return BuildRequestTokenInfo(method, null); + } + + /// + /// Generates a instance to pass to an + /// for the purpose of requesting an + /// unauthorized request token. + /// + /// The HTTP method for the intended request + /// Any existing, non-OAuth query parameters desired in the request + /// + /// + public virtual OAuthWebQueryInfo BuildRequestTokenInfo(string method, WebParameterCollection parameters) + { + ValidateTokenRequestState(); + + if (parameters == null) + { + parameters = new WebParameterCollection(); + } + + var timestamp = OAuthTools.GetTimestamp(); + var nonce = OAuthTools.GetNonce(); + + AddAuthParameters(parameters, timestamp, nonce); + + var signatureBase = OAuthTools.ConcatenateRequestElements(method, RequestTokenUrl, parameters); + var signature = OAuthTools.GetSignature(SignatureMethod, SignatureTreatment, signatureBase, ConsumerSecret); + + var info = new OAuthWebQueryInfo + { + WebMethod = method, + ParameterHandling = ParameterHandling, + ConsumerKey = ConsumerKey, + SignatureMethod = SignatureMethod.ToRequestValue(), + SignatureTreatment = SignatureTreatment, + Signature = signature, + Timestamp = timestamp, + Nonce = nonce, + Version = Version ?? "1.0", + Callback = OAuthTools.UrlEncodeRelaxed(CallbackUrl ?? ""), + TokenSecret = TokenSecret, + ConsumerSecret = ConsumerSecret + }; + + return info; + } + + /// + /// Generates a instance to pass to an + /// for the purpose of exchanging a request token + /// for an access token authorized by the user at the Service Provider site. + /// + /// The HTTP method for the intended request + /// + public virtual OAuthWebQueryInfo BuildAccessTokenInfo(string method) + { + return BuildAccessTokenInfo(method, null); + } + + /// + /// Generates a instance to pass to an + /// for the purpose of exchanging a request token + /// for an access token authorized by the user at the Service Provider site. + /// + /// The HTTP method for the intended request + /// + /// Any existing, non-OAuth query parameters desired in the request + public virtual OAuthWebQueryInfo BuildAccessTokenInfo(string method, WebParameterCollection parameters) + { + ValidateAccessRequestState(); + + if (parameters == null) + { + parameters = new WebParameterCollection(); + } + + var uri = new Uri(AccessTokenUrl); + var timestamp = OAuthTools.GetTimestamp(); + var nonce = OAuthTools.GetNonce(); + + AddAuthParameters(parameters, timestamp, nonce); + + var signatureBase = OAuthTools.ConcatenateRequestElements(method, uri.ToString(), parameters); + var signature = OAuthTools.GetSignature(SignatureMethod, SignatureTreatment, signatureBase, ConsumerSecret, TokenSecret); + + var info = new OAuthWebQueryInfo + { + WebMethod = method, + ParameterHandling = ParameterHandling, + ConsumerKey = ConsumerKey, + Token = Token, + SignatureMethod = SignatureMethod.ToRequestValue(), + SignatureTreatment = SignatureTreatment, + Signature = signature, + Timestamp = timestamp, + Nonce = nonce, + Version = Version ?? "1.0", + Verifier = Verifier, + Callback = CallbackUrl, + TokenSecret = TokenSecret, + ConsumerSecret = ConsumerSecret, + }; + + return info; + } + + /// + /// Generates a instance to pass to an + /// for the purpose of exchanging user credentials + /// for an access token authorized by the user at the Service Provider site. + /// + /// The HTTP method for the intended request + /// + /// Any existing, non-OAuth query parameters desired in the request + public virtual OAuthWebQueryInfo BuildClientAuthAccessTokenInfo(string method, WebParameterCollection parameters) + { + ValidateClientAuthAccessRequestState(); + + if (parameters == null) + { + parameters = new WebParameterCollection(); + } + + var uri = new Uri(AccessTokenUrl); + var timestamp = OAuthTools.GetTimestamp(); + var nonce = OAuthTools.GetNonce(); + + AddXAuthParameters(parameters, timestamp, nonce); + + var signatureBase = OAuthTools.ConcatenateRequestElements(method, uri.ToString(), parameters); + var signature = OAuthTools.GetSignature(SignatureMethod, SignatureTreatment, signatureBase, ConsumerSecret); + + var info = new OAuthWebQueryInfo + { + WebMethod = method, + ParameterHandling = ParameterHandling, + ClientMode = "client_auth", + ClientUsername = ClientUsername, + ClientPassword = ClientPassword, + ConsumerKey = ConsumerKey, + SignatureMethod = SignatureMethod.ToRequestValue(), + SignatureTreatment = SignatureTreatment, + Signature = signature, + Timestamp = timestamp, + Nonce = nonce, + Version = Version ?? "1.0", + TokenSecret = TokenSecret, + ConsumerSecret = ConsumerSecret + }; + + return info; + } + + public virtual OAuthWebQueryInfo BuildProtectedResourceInfo(string method, WebParameterCollection parameters, string url) + { + ValidateProtectedResourceState(); + + if (parameters == null) + { + parameters = new WebParameterCollection(); + } + + // Include url parameters in query pool + var uri = new Uri(url); +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + var urlParameters = HttpUtility.ParseQueryString(uri.Query); +#else + var urlParameters = uri.Query.ParseQueryString(); +#endif + +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + foreach (var parameter in urlParameters.AllKeys) +#else + foreach (var parameter in urlParameters.Keys) +#endif + { +#if PocketPC + switch (method.ToUpper()) +#else + switch (method.ToUpperInvariant()) +#endif + { + case "POST": + parameters.Add(new HttpPostParameter(parameter, urlParameters[parameter])); + break; + default: + parameters.Add(parameter, urlParameters[parameter]); + break; + } + } + + var timestamp = OAuthTools.GetTimestamp(); + var nonce = OAuthTools.GetNonce(); + + AddAuthParameters(parameters, timestamp, nonce); + + var signatureBase = OAuthTools.ConcatenateRequestElements(method, url, parameters); + + var signature = OAuthTools.GetSignature( + SignatureMethod, SignatureTreatment, signatureBase, ConsumerSecret, TokenSecret + ); + + var info = new OAuthWebQueryInfo + { + WebMethod = method, + ParameterHandling = ParameterHandling, + ConsumerKey = ConsumerKey, + Token = Token, + SignatureMethod = SignatureMethod.ToRequestValue(), + SignatureTreatment = SignatureTreatment, + Signature = signature, + Timestamp = timestamp, + Nonce = nonce, + Version = Version ?? "1.0", + Callback = CallbackUrl, + ConsumerSecret = ConsumerSecret, + TokenSecret = TokenSecret + }; + + return info; + } + + private void ValidateTokenRequestState() + { + if (RequestTokenUrl.IsNullOrBlank()) + { + throw new ArgumentException("You must specify a request token URL"); + } + + if (ConsumerKey.IsNullOrBlank()) + { + throw new ArgumentException("You must specify a consumer key"); + } + + if (ConsumerSecret.IsNullOrBlank()) + { + throw new ArgumentException("You must specify a consumer secret"); + } + } + + private void ValidateAccessRequestState() + { + if (AccessTokenUrl.IsNullOrBlank()) + { + throw new ArgumentException("You must specify an access token URL"); + } + + if (ConsumerKey.IsNullOrBlank()) + { + throw new ArgumentException("You must specify a consumer key"); + } + + if (ConsumerSecret.IsNullOrBlank()) + { + throw new ArgumentException("You must specify a consumer secret"); + } + + if (Token.IsNullOrBlank()) + { + throw new ArgumentException("You must specify a token"); + } + } + + private void ValidateClientAuthAccessRequestState() + { + if (AccessTokenUrl.IsNullOrBlank()) + { + throw new ArgumentException("You must specify an access token URL"); + } + + if (ConsumerKey.IsNullOrBlank()) + { + throw new ArgumentException("You must specify a consumer key"); + } + + if (ConsumerSecret.IsNullOrBlank()) + { + throw new ArgumentException("You must specify a consumer secret"); + } + + if (ClientUsername.IsNullOrBlank() || ClientPassword.IsNullOrBlank()) + { + throw new ArgumentException("You must specify user credentials"); + } + } + + private void ValidateProtectedResourceState() + { + if (ConsumerKey.IsNullOrBlank()) + { + throw new ArgumentException("You must specify a consumer key"); + } + + if (ConsumerSecret.IsNullOrBlank()) + { + throw new ArgumentException("You must specify a consumer secret"); + } + } + + private void AddAuthParameters(ICollection parameters, string timestamp, string nonce) + { + var authParameters = new WebParameterCollection + { + new WebPair("oauth_consumer_key", ConsumerKey), + new WebPair("oauth_nonce", nonce), + new WebPair("oauth_signature_method", SignatureMethod.ToRequestValue()), + new WebPair("oauth_timestamp", timestamp), + new WebPair("oauth_version", Version ?? "1.0") + }; + + if (!Token.IsNullOrBlank()) + { + authParameters.Add(new WebPair("oauth_token", Token)); + } + + if (!CallbackUrl.IsNullOrBlank()) + { + authParameters.Add(new WebPair("oauth_callback", CallbackUrl)); + } + + if (!Verifier.IsNullOrBlank()) + { + authParameters.Add(new WebPair("oauth_verifier", Verifier)); + } + + if (!SessionHandle.IsNullOrBlank()) + { + authParameters.Add(new WebPair("oauth_session_handle", SessionHandle)); + } + + foreach (var authParameter in authParameters) + { + parameters.Add(authParameter); + } + } + + private void AddXAuthParameters(ICollection parameters, string timestamp, string nonce) + { + var authParameters = new WebParameterCollection + { + new WebPair("x_auth_username", ClientUsername), + new WebPair("x_auth_password", ClientPassword), + new WebPair("x_auth_mode", "client_auth"), + new WebPair("oauth_consumer_key", ConsumerKey), + new WebPair("oauth_signature_method", SignatureMethod.ToRequestValue()), + new WebPair("oauth_timestamp", timestamp), + new WebPair("oauth_nonce", nonce), + new WebPair("oauth_version", Version ?? "1.0") + }; + + foreach (var authParameter in authParameters) + { + parameters.Add(authParameter); + } + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebPair.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebPair.cs new file mode 100644 index 000000000..4ecc9c42b --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebPair.cs @@ -0,0 +1,14 @@ +namespace RestSharp.Authenticators.OAuth +{ + internal class WebPair + { + public WebPair(string name, string value) + { + Name = name; + Value = value; + } + + public string Value { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebPairCollection.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebPairCollection.cs new file mode 100644 index 000000000..db9c7157b --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebPairCollection.cs @@ -0,0 +1,192 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; + +namespace RestSharp.Authenticators.OAuth +{ + internal class WebPairCollection : IList + { + private IList _parameters; + + public virtual WebPair this[string name] + { + get { return this.SingleOrDefault(p => p.Name.Equals(name)); } + } + + public virtual IEnumerable Names + { + get { return _parameters.Select(p => p.Name); } + } + + public virtual IEnumerable Values + { + get { return _parameters.Select(p => p.Value); } + } + + public WebPairCollection(IEnumerable parameters) + { + _parameters = new List(parameters); + } + +#if !WINDOWS_PHONE && !SILVERLIGHT && !PocketPC + public WebPairCollection(NameValueCollection collection) : this() + { + AddCollection(collection); + } + + public virtual void AddRange(NameValueCollection collection) + { + AddCollection(collection); + } + + private void AddCollection(NameValueCollection collection) + { + var parameters = collection.AllKeys.Select(key => new WebPair(key, collection[key])); + foreach (var parameter in parameters) + { + _parameters.Add(parameter); + } + } +#endif + + public WebPairCollection(IDictionary collection) : this() + { + AddCollection(collection); + } + + public void AddCollection(IDictionary collection) + { + foreach (var key in collection.Keys) + { + var parameter = new WebPair(key, collection[key]); + _parameters.Add(parameter); + } + } + + public WebPairCollection() + { + _parameters = new List(0); + } + + public WebPairCollection(int capacity) + { + _parameters = new List(capacity); + } + + private void AddCollection(IEnumerable collection) + { + foreach (var parameter in collection) + { + var pair = new WebPair(parameter.Name, parameter.Value); + _parameters.Add(pair); + } + } + + public virtual void AddRange(WebPairCollection collection) + { + AddCollection(collection); + } + + public virtual void AddRange(IEnumerable collection) + { + AddCollection(collection); + } + + public virtual void Sort(Comparison comparison) + { + var sorted = new List(_parameters); + sorted.Sort(comparison); + _parameters = sorted; + } + + public virtual bool RemoveAll(IEnumerable parameters) + { + var success = true; + var array = parameters.ToArray(); + for (var p = 0; p < array.Length; p++) + { + var parameter = array[p]; + success &= _parameters.Remove(parameter); + } + return success && array.Length > 0; + } + + public virtual void Add(string name, string value) + { + var pair = new WebPair(name, value); + _parameters.Add(pair); + } + + #region IList Members + + public virtual IEnumerator GetEnumerator() + { + return _parameters.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public virtual void Add(WebPair parameter) + { + _parameters.Add(parameter); + } + + public virtual void Clear() + { + _parameters.Clear(); + } + + public virtual bool Contains(WebPair parameter) + { + return _parameters.Contains(parameter); + } + + public virtual void CopyTo(WebPair[] parameters, int arrayIndex) + { + _parameters.CopyTo(parameters, arrayIndex); + } + + public virtual bool Remove(WebPair parameter) + { + return _parameters.Remove(parameter); + } + + public virtual int Count + { + get { return _parameters.Count; } + } + + public virtual bool IsReadOnly + { + get { return _parameters.IsReadOnly; } + } + + public virtual int IndexOf(WebPair parameter) + { + return _parameters.IndexOf(parameter); + } + + public virtual void Insert(int index, WebPair parameter) + { + _parameters.Insert(index, parameter); + } + + public virtual void RemoveAt(int index) + { + _parameters.RemoveAt(index); + } + + public virtual WebPair this[int index] + { + get { return _parameters[index]; } + set { _parameters[index] = value; } + } + + #endregion + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebParameter.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebParameter.cs new file mode 100644 index 000000000..5f46c794e --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebParameter.cs @@ -0,0 +1,21 @@ +#if !Smartphone +using System; +using System.Diagnostics; + +#endif + +namespace RestSharp.Authenticators.OAuth +{ +#if !Smartphone && !PocketPC + [DebuggerDisplay("{Name}:{Value}")] +#endif +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + [Serializable] +#endif + internal class WebParameter : WebPair + { + public WebParameter(string name, string value) : base(name, value) + { + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebParameterCollection.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebParameterCollection.cs new file mode 100644 index 000000000..1da58f01d --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth/WebParameterCollection.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.Collections.Specialized; + +namespace RestSharp.Authenticators.OAuth +{ + internal class WebParameterCollection : WebPairCollection + { + public WebParameterCollection(IEnumerable parameters) + : base(parameters) + { + } + +#if !WINDOWS_PHONE && !SILVERLIGHT && !PocketPC + public WebParameterCollection(NameValueCollection collection) : base(collection) + { + } +#endif + + public WebParameterCollection() + { + } + + public WebParameterCollection(int capacity) : base(capacity) + { + } + + public WebParameterCollection(IDictionary collection) : base(collection) + { + } + + public override void Add(string name, string value) + { + var parameter = new WebParameter(name, value); + base.Add(parameter); + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth1Authenticator.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth1Authenticator.cs new file mode 100644 index 000000000..bdde9c08c --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth1Authenticator.cs @@ -0,0 +1,263 @@ +using System; +using System.Linq; +using System.Text; +using RestSharp.Authenticators.OAuth; +using RestSharp.Authenticators.OAuth.Extensions; + +#if WINDOWS_PHONE +using System.Net; +#elif SILVERLIGHT +using System.Windows.Browser; +#else +using RestSharp.Contrib; +#endif + + +namespace RestSharp.Authenticators +{ + /// + public class OAuth1Authenticator : IAuthenticator + { + public virtual string Realm { get; set; } + public virtual OAuthParameterHandling ParameterHandling { get; set; } + public virtual OAuthSignatureMethod SignatureMethod { get; set; } + public virtual OAuthSignatureTreatment SignatureTreatment { get; set; } + + internal virtual OAuthType Type { get; set; } + internal virtual string ConsumerKey { get; set; } + internal virtual string ConsumerSecret { get; set; } + internal virtual string Token { get; set; } + internal virtual string TokenSecret { get; set; } + internal virtual string Verifier { get; set; } + internal virtual string Version { get; set; } + internal virtual string CallbackUrl { get; set; } + internal virtual string SessionHandle { get; set; } + internal virtual string ClientUsername { get; set; } + internal virtual string ClientPassword { get; set; } + + public static OAuth1Authenticator ForRequestToken(string consumerKey, string consumerSecret) + { + var authenticator = new OAuth1Authenticator + { + ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, + SignatureMethod = OAuthSignatureMethod.HmacSha1, + SignatureTreatment = OAuthSignatureTreatment.Escaped, + ConsumerKey = consumerKey, + ConsumerSecret = consumerSecret, + Type = OAuthType.RequestToken + }; + return authenticator; + } + + public static OAuth1Authenticator ForRequestToken(string consumerKey, string consumerSecret, string callbackUrl) + { + var authenticator = ForRequestToken(consumerKey, consumerSecret); + authenticator.CallbackUrl = callbackUrl; + return authenticator; + } + + public static OAuth1Authenticator ForAccessToken(string consumerKey, string consumerSecret, string token, string tokenSecret) + { + var authenticator = new OAuth1Authenticator + { + ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, + SignatureMethod = OAuthSignatureMethod.HmacSha1, + SignatureTreatment = OAuthSignatureTreatment.Escaped, + ConsumerKey = consumerKey, + ConsumerSecret = consumerSecret, + Token = token, + TokenSecret = tokenSecret, + Type = OAuthType.AccessToken + }; + return authenticator; + } + + public static OAuth1Authenticator ForAccessToken(string consumerKey, string consumerSecret, string token, string tokenSecret, string verifier) + { + var authenticator = ForAccessToken(consumerKey, consumerSecret, token, tokenSecret); + authenticator.Verifier = verifier; + return authenticator; + } + + public static OAuth1Authenticator ForAccessTokenRefresh(string consumerKey, string consumerSecret, string token, string tokenSecret, string sessionHandle) + { + var authenticator = ForAccessToken(consumerKey, consumerSecret, token, tokenSecret); + authenticator.SessionHandle = sessionHandle; + return authenticator; + } + + public static OAuth1Authenticator ForAccessTokenRefresh(string consumerKey, string consumerSecret, string token, string tokenSecret, string verifier, string sessionHandle) + { + var authenticator = ForAccessToken(consumerKey, consumerSecret, token, tokenSecret); + authenticator.SessionHandle = sessionHandle; + authenticator.Verifier = verifier; + return authenticator; + } + + public static OAuth1Authenticator ForClientAuthentication(string consumerKey, string consumerSecret, string username, string password) + { + var authenticator = new OAuth1Authenticator + { + ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, + SignatureMethod = OAuthSignatureMethod.HmacSha1, + SignatureTreatment = OAuthSignatureTreatment.Escaped, + ConsumerKey = consumerKey, + ConsumerSecret = consumerSecret, + ClientUsername = username, + ClientPassword = password, + Type = OAuthType.ClientAuthentication + }; + return authenticator; + } + + public static OAuth1Authenticator ForProtectedResource(string consumerKey, string consumerSecret, string accessToken, string accessTokenSecret) + { + var authenticator = new OAuth1Authenticator + { + Type = OAuthType.ProtectedResource, + ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, + SignatureMethod = OAuthSignatureMethod.HmacSha1, + SignatureTreatment = OAuthSignatureTreatment.Escaped, + ConsumerKey = consumerKey, + ConsumerSecret = consumerSecret, + Token = accessToken, + TokenSecret = accessTokenSecret + }; + return authenticator; + } + + public void Authenticate(IRestClient client, IRestRequest request) + { + var workflow = new OAuthWorkflow + { + ConsumerKey = ConsumerKey, + ConsumerSecret = ConsumerSecret, + ParameterHandling = ParameterHandling, + SignatureMethod = SignatureMethod, + SignatureTreatment = SignatureTreatment, + Verifier = Verifier, + Version = Version, + CallbackUrl = CallbackUrl, + SessionHandle = SessionHandle, + Token = Token, + TokenSecret = TokenSecret, + ClientUsername = ClientUsername, + ClientPassword = ClientPassword + }; + + AddOAuthData(client, request, workflow); + } + + private void AddOAuthData(IRestClient client, IRestRequest request, OAuthWorkflow workflow) + { + var url = client.BuildUri(request).ToString(); + var queryStringStart = url.IndexOf('?'); + if (queryStringStart != -1) + url = url.Substring(0, queryStringStart); + + OAuthWebQueryInfo oauth; +#if PocketPC + var method = request.Method.ToString().ToUpper(); +#else + var method = request.Method.ToString().ToUpperInvariant(); +#endif + + var parameters = new WebParameterCollection(); + + // include all GET and POST parameters before generating the signature + // according to the RFC 5849 - The OAuth 1.0 Protocol + // http://tools.ietf.org/html/rfc5849#section-3.4.1 + // if this change causes trouble we need to introduce a flag indicating the specific OAuth implementation level, + // or implement a seperate class for each OAuth version + if (!request.AlwaysMultipartFormData && !request.Files.Any()) + { + foreach (var p in client.DefaultParameters.Where(p => p.Type == ParameterType.GetOrPost)) + { + parameters.Add(new WebPair(p.Name, p.Value.ToString())); + } + foreach (var p in request.Parameters.Where(p => p.Type == ParameterType.GetOrPost)) + { + parameters.Add(new WebPair(p.Name, p.Value.ToString())); + } + } + else + { + // if we are sending a multipart request, only the "oauth_" parameters should be included in the signature + foreach ( + var p in client.DefaultParameters.Where(p => p.Type == ParameterType.GetOrPost && p.Name.StartsWith("oauth_"))) + { + parameters.Add(new WebPair(p.Name, p.Value.ToString())); + } + foreach (var p in request.Parameters.Where(p => p.Type == ParameterType.GetOrPost && p.Name.StartsWith("oauth_"))) + { + parameters.Add(new WebPair(p.Name, p.Value.ToString())); + } + } + + switch (Type) + { + case OAuthType.RequestToken: + workflow.RequestTokenUrl = url; + oauth = workflow.BuildRequestTokenInfo(method, parameters); + break; + case OAuthType.AccessToken: + workflow.AccessTokenUrl = url; + oauth = workflow.BuildAccessTokenInfo(method, parameters); + break; + case OAuthType.ClientAuthentication: + workflow.AccessTokenUrl = url; + oauth = workflow.BuildClientAuthAccessTokenInfo(method, parameters); + break; + case OAuthType.ProtectedResource: + oauth = workflow.BuildProtectedResourceInfo(method, parameters, url); + break; + default: + throw new ArgumentOutOfRangeException(); + } + + switch (ParameterHandling) + { + case OAuthParameterHandling.HttpAuthorizationHeader: + parameters.Add("oauth_signature", oauth.Signature); + request.AddHeader("Authorization", GetAuthorizationHeader(parameters)); + break; + case OAuthParameterHandling.UrlOrPostParameters: + parameters.Add("oauth_signature", oauth.Signature); + foreach (var parameter in parameters.Where(parameter => !parameter.Name.IsNullOrBlank() && (parameter.Name.StartsWith("oauth_") || parameter.Name.StartsWith("x_auth_")))) + { + request.AddParameter(parameter.Name, HttpUtility.UrlDecode(parameter.Value)); + } + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private string GetAuthorizationHeader(WebPairCollection parameters) + { + var sb = new StringBuilder("OAuth "); + if (!Realm.IsNullOrBlank()) + { + sb.Append("realm=\"{0}\",".FormatWith(OAuthTools.UrlEncodeRelaxed(Realm))); + } + + parameters.Sort((l, r) => l.Name.CompareTo(r.Name)); + + var parameterCount = 0; + var oathParameters = parameters.Where(parameter => + !parameter.Name.IsNullOrBlank() && + !parameter.Value.IsNullOrBlank() && + (parameter.Name.StartsWith("oauth_") || parameter.Name.StartsWith("x_auth_")) + ).ToList(); + foreach (var parameter in oathParameters) + { + parameterCount++; + var format = parameterCount < oathParameters.Count ? "{0}=\"{1}\"," : "{0}=\"{1}\""; + sb.Append(format.FormatWith(parameter.Name, parameter.Value)); + } + + var authorization = sb.ToString(); + return authorization; + } + } +} diff --git a/Backup/RestSharp.Silverlight/Authenticators/OAuth2Authenticator.cs b/Backup/RestSharp.Silverlight/Authenticators/OAuth2Authenticator.cs new file mode 100644 index 000000000..7fd457929 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/OAuth2Authenticator.cs @@ -0,0 +1,120 @@ +using System; +using System.Linq; + +namespace RestSharp +{ + /// + /// Base class for OAuth 2 Authenticators. + /// + /// + /// Since there are many ways to authenticate in OAuth2, + /// this is used as a base class to differentiate between + /// other authenticators. + /// + /// Any other OAuth2 authenticators must derive from this + /// abstract class. + /// + public abstract class OAuth2Authenticator : IAuthenticator + { + /// + /// Access token to be used when authenticating. + /// + private readonly string _accessToken; + + /// + /// Initializes a new instance of the class. + /// + /// + /// The access token. + /// + public OAuth2Authenticator(string accessToken) + { + _accessToken = accessToken; + } + + /// + /// Gets the access token. + /// + public string AccessToken + { + get { return _accessToken; } + } + + public abstract void Authenticate(IRestClient client, IRestRequest request); + } + + /// + /// The OAuth 2 authenticator using URI query parameter. + /// + /// + /// Based on http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-5.1.2 + /// + public class OAuth2UriQueryParameterAuthenticator : OAuth2Authenticator + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The access token. + /// + public OAuth2UriQueryParameterAuthenticator(string accessToken) + : base(accessToken) + { + } + + public override void Authenticate(IRestClient client, IRestRequest request) + { + request.AddParameter("oauth_token", AccessToken, ParameterType.GetOrPost); + } + } + + /// + /// The OAuth 2 authenticator using the authorization request header field. + /// + /// + /// Based on http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-5.1.1 + /// + public class OAuth2AuthorizationRequestHeaderAuthenticator : OAuth2Authenticator + { + /// + /// Stores the Authorization header value as "[tokenType] accessToken". used for performance. + /// + private readonly string _authorizationValue; + + /// + /// Initializes a new instance of the class. + /// + /// + /// The access token. + /// + public OAuth2AuthorizationRequestHeaderAuthenticator(string accessToken) + : this(accessToken, "OAuth") + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The access token. + /// + /// + /// The token type. + /// + public OAuth2AuthorizationRequestHeaderAuthenticator(string accessToken, string tokenType) + : base(accessToken) + { + // Conatenate during constructor so that it is only done once. can improve performance. + _authorizationValue = tokenType + " " + accessToken; + } + + public override void Authenticate(IRestClient client, IRestRequest request) + { + // only add the Authorization parameter if it hasn't been added. + if (!request.Parameters.Any(p => p.Name.Equals("Authorization", StringComparison.OrdinalIgnoreCase))) + { + request.AddParameter("Authorization", _authorizationValue, ParameterType.HttpHeader); + } + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Authenticators/SimpleAuthenticator.cs b/Backup/RestSharp.Silverlight/Authenticators/SimpleAuthenticator.cs new file mode 100644 index 000000000..1a89399e2 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Authenticators/SimpleAuthenticator.cs @@ -0,0 +1,39 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace RestSharp +{ + public class SimpleAuthenticator : IAuthenticator + { + private readonly string _usernameKey; + private readonly string _username; + private readonly string _passwordKey; + private readonly string _password; + + public SimpleAuthenticator(string usernameKey, string username, string passwordKey, string password) { + _usernameKey = usernameKey; + _username = username; + _passwordKey = passwordKey; + _password = password; + } + + public void Authenticate(IRestClient client, IRestRequest request) + { + request.AddParameter(_usernameKey, _username); + request.AddParameter(_passwordKey, _password); + } + } +} diff --git a/Backup/RestSharp.Silverlight/Deserializers/DeserializeAsAttribute.cs b/Backup/RestSharp.Silverlight/Deserializers/DeserializeAsAttribute.cs new file mode 100644 index 000000000..390996105 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Deserializers/DeserializeAsAttribute.cs @@ -0,0 +1,38 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; + +namespace RestSharp.Deserializers +{ + /// + /// Allows control how class and property names and values are deserialized by XmlAttributeDeserializer + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] + public sealed class DeserializeAsAttribute : Attribute + { + /// + /// The name to use for the serialized element + /// + public string Name { get; set; } + + /// + /// Sets if the property to Deserialize is an Attribute or Element (Default: false) + /// + public bool Attribute { get; set; } + } + +} diff --git a/Backup/RestSharp.Silverlight/Deserializers/DotNetXmlDeserializer.cs b/Backup/RestSharp.Silverlight/Deserializers/DotNetXmlDeserializer.cs new file mode 100644 index 000000000..fbfc46deb --- /dev/null +++ b/Backup/RestSharp.Silverlight/Deserializers/DotNetXmlDeserializer.cs @@ -0,0 +1,47 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System.IO; +using System.Text; + +namespace RestSharp.Deserializers +{ + /// + /// Wrapper for System.Xml.Serialization.XmlSerializer. + /// + public class DotNetXmlDeserializer : IDeserializer + { + public string DateFormat { get; set; } + + public string Namespace { get; set; } + + public string RootElement { get; set; } + + public T Deserialize(IRestResponse response) + { + if (string.IsNullOrEmpty(response.Content)) + { + return default(T); + } + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(response.Content))) + { + var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); + return (T)serializer.Deserialize(stream); + } + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Deserializers/IDeserializer.cs b/Backup/RestSharp.Silverlight/Deserializers/IDeserializer.cs new file mode 100644 index 000000000..844c30d6c --- /dev/null +++ b/Backup/RestSharp.Silverlight/Deserializers/IDeserializer.cs @@ -0,0 +1,26 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace RestSharp.Deserializers +{ + public interface IDeserializer + { + T Deserialize(IRestResponse response); + string RootElement { get; set; } + string Namespace { get; set; } + string DateFormat { get; set; } + } +} diff --git a/Backup/RestSharp.Silverlight/Deserializers/JsonDeserializer.cs b/Backup/RestSharp.Silverlight/Deserializers/JsonDeserializer.cs new file mode 100644 index 000000000..06fd1d66f --- /dev/null +++ b/Backup/RestSharp.Silverlight/Deserializers/JsonDeserializer.cs @@ -0,0 +1,298 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using RestSharp.Extensions; + +namespace RestSharp.Deserializers +{ + public class JsonDeserializer : IDeserializer + { + public string RootElement { get; set; } + public string Namespace { get; set; } + public string DateFormat { get; set; } + public CultureInfo Culture { get; set; } + + public JsonDeserializer() + { + Culture = CultureInfo.InvariantCulture; + } + + public T Deserialize(IRestResponse response) + { + var target = Activator.CreateInstance(); + + if (target is IList) + { + var objType = target.GetType(); + + if (RootElement.HasValue()) + { + var root = FindRoot(response.Content); + target = (T)BuildList(objType, root); + } + else + { + var data = SimpleJson.DeserializeObject(response.Content); + target = (T)BuildList(objType, data); + } + } + else if (target is IDictionary) + { + var root = FindRoot(response.Content); + target = (T)BuildDictionary(target.GetType(), root); + } + else + { + var root = FindRoot(response.Content); + Map(target, (IDictionary)root); + } + + return target; + } + + private object FindRoot(string content) + { + var data = (IDictionary)SimpleJson.DeserializeObject(content); + if (RootElement.HasValue() && data.ContainsKey(RootElement)) + { + return data[RootElement]; + } + return data; + } + + private void Map(object target, IDictionary data) + { + var objType = target.GetType(); + var props = objType.GetProperties().Where(p => p.CanWrite).ToList(); + + foreach (var prop in props) + { + var type = prop.PropertyType; + + string name = String.Empty; + + var attributes = prop.GetCustomAttributes(typeof(DeserializeAsAttribute), false); + if (attributes.Length > 0) + { + var attribute = (DeserializeAsAttribute)attributes[0]; + name = attribute.Name; + } + else + { + name = prop.Name; + } + + var parts = name.Split('.'); + var currentData = data; + object value = null; + for (var i = 0; i < parts.Length; ++i) + { + var actualName = parts[i].GetNameVariants(Culture).FirstOrDefault(currentData.ContainsKey); + if (actualName == null) break; + if(i == parts.Length - 1) value = currentData[actualName]; + else currentData = (IDictionary)currentData[actualName]; + } + + if(value != null) prop.SetValue(target, ConvertValue(type, value), null); + } + } + + private IDictionary BuildDictionary(Type type, object parent) + { + var dict = (IDictionary)Activator.CreateInstance(type); + var valueType = type.GetGenericArguments()[1]; + foreach (var child in (IDictionary)parent) + { + var key = child.Key; + object item = null; + if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(List<>)) + { + item = BuildList(valueType, child.Value); + } + else + { + item = ConvertValue(valueType, child.Value); + } + dict.Add(key, item); + } + return dict; + } + + private IList BuildList(Type type, object parent) + { + var list = (IList)Activator.CreateInstance(type); + var listType = type.GetInterfaces().First(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList<>)); + var itemType = listType.GetGenericArguments()[0]; + + if (parent is IList) + { + foreach (var element in (IList)parent) + { + if (itemType.IsPrimitive) + { + var value = element.ToString(); + list.Add(value.ChangeType(itemType, Culture)); + } + else if (itemType == typeof(string)) + { + if (element == null) + { + list.Add(null); + continue; + } + + list.Add(element.ToString()); + } + else + { + if (element == null) + { + list.Add(null); + continue; + } + + var item = ConvertValue(itemType, element); + list.Add(item); + } + } + } + else + { + list.Add(ConvertValue(itemType, parent)); + } + return list; + } + + private object ConvertValue(Type type, object value) + { + var stringValue = Convert.ToString(value, Culture); + + // check for nullable and extract underlying type + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + // Since the type is nullable and no value is provided return null + if (String.IsNullOrEmpty(stringValue)) return null; + + type = type.GetGenericArguments()[0]; + } + + if (type == typeof(System.Object) && value != null) + { + type = value.GetType(); + } + + if (type.IsPrimitive) + { + return value.ChangeType(type, Culture); + } + else if (type.IsEnum) + { + return type.FindEnumValue(stringValue, Culture); + } + else if (type == typeof(Uri)) + { + return new Uri(stringValue, UriKind.RelativeOrAbsolute); + } + else if (type == typeof(string)) + { + return stringValue; + } + else if (type == typeof(DateTime) +#if !PocketPC + || type == typeof(DateTimeOffset) +#endif + ) + { + DateTime dt; + if (DateFormat.HasValue()) + { + dt = DateTime.ParseExact(stringValue, DateFormat, Culture); + } + else + { + // try parsing instead + dt = stringValue.ParseJsonDate(Culture); + } + +#if PocketPC + return dt; +#else + if (type == typeof(DateTime)) + { + return dt; + } + else if (type == typeof(DateTimeOffset)) + { + return (DateTimeOffset)dt; + } +#endif + } + else if (type == typeof(Decimal)) + { + if (value is double) + return (decimal)((double)value); + + return Decimal.Parse(stringValue, Culture); + } + else if (type == typeof(Guid)) + { + return string.IsNullOrEmpty(stringValue) ? Guid.Empty : new Guid(stringValue); + } + else if (type == typeof(TimeSpan)) + { + return TimeSpan.Parse(stringValue); + } + else if (type.IsGenericType) + { + var genericTypeDef = type.GetGenericTypeDefinition(); + if (genericTypeDef == typeof(List<>)) + { + return BuildList(type, value); + } + else if (genericTypeDef == typeof(Dictionary<,>)) + { + var keyType = type.GetGenericArguments()[0]; + + // only supports Dict() + if (keyType == typeof(string)) + { + return BuildDictionary(type, value); + } + } + else + { + // nested property classes + return CreateAndMap(type, value); + } + } + else if (type.IsSubclassOfRawGeneric(typeof(List<>))) + { + // handles classes that derive from List + return BuildList(type, value); + } + else if (type == typeof(JsonObject)) + { + // simplify JsonObject into a Dictionary + return BuildDictionary(typeof(Dictionary), value); + } + else + { + // nested property classes + return CreateAndMap(type, value); + } + + return null; + } + + private object CreateAndMap(Type type, object element) + { + var instance = Activator.CreateInstance(type); + + Map(instance, (IDictionary)element); + + return instance; + } + } +} diff --git a/Backup/RestSharp.Silverlight/Deserializers/XmlAttributeDeserializer.cs b/Backup/RestSharp.Silverlight/Deserializers/XmlAttributeDeserializer.cs new file mode 100644 index 000000000..aea2af8ea --- /dev/null +++ b/Backup/RestSharp.Silverlight/Deserializers/XmlAttributeDeserializer.cs @@ -0,0 +1,49 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System.Reflection; +using System.Xml.Linq; +using RestSharp.Extensions; + +namespace RestSharp.Deserializers +{ + public class XmlAttributeDeserializer : XmlDeserializer + { + protected override object GetValueFromXml(XElement root, XName name, PropertyInfo prop) + { + var isAttribute = false; + + //Check for the DeserializeAs attribute on the property + var options = prop.GetAttribute(); + if (options != null) + { + name = options.Name ?? name; + isAttribute = options.Attribute; + } + + if (isAttribute) + { + var attributeVal = GetAttributeByName(root, name); + if (attributeVal != null) + { + return attributeVal.Value; + } + } + + return base.GetValueFromXml(root, name, prop); + } + } +} diff --git a/Backup/RestSharp.Silverlight/Deserializers/XmlDeserializer.cs b/Backup/RestSharp.Silverlight/Deserializers/XmlDeserializer.cs new file mode 100644 index 000000000..277b4fee6 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Deserializers/XmlDeserializer.cs @@ -0,0 +1,466 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Xml.Linq; + +using RestSharp.Extensions; +using System.Globalization; +using System.Xml; +using System.ComponentModel; + +namespace RestSharp.Deserializers +{ + public class XmlDeserializer : IDeserializer + { + public string RootElement { get; set; } + public string Namespace { get; set; } + public string DateFormat { get; set; } + public CultureInfo Culture { get; set; } + + public XmlDeserializer() + { + Culture = CultureInfo.InvariantCulture; + } + + public virtual T Deserialize(IRestResponse response) + { + if (string.IsNullOrEmpty( response.Content )) + return default(T); + + var doc = XDocument.Parse(response.Content); + var root = doc.Root; + if (RootElement.HasValue() && doc.Root != null) + { + root = doc.Root.Element(RootElement.AsNamespaced(Namespace)); + } + + // autodetect xml namespace + if (!Namespace.HasValue()) + { + RemoveNamespace(doc); + } + + var x = Activator.CreateInstance(); + var objType = x.GetType(); + + if (objType.IsSubclassOfRawGeneric(typeof(List<>))) + { + x = (T)HandleListDerivative(x, root, objType.Name, objType); + } + else + { + Map(x, root); + } + + return x; + } + + private void RemoveNamespace(XDocument xdoc) + { + foreach (XElement e in xdoc.Root.DescendantsAndSelf()) + { + if (e.Name.Namespace != XNamespace.None) + { + e.Name = XNamespace.None.GetName(e.Name.LocalName); + } + if (e.Attributes().Any(a => a.IsNamespaceDeclaration || a.Name.Namespace != XNamespace.None)) + { + e.ReplaceAttributes(e.Attributes().Select(a => a.IsNamespaceDeclaration ? null : a.Name.Namespace != XNamespace.None ? new XAttribute(XNamespace.None.GetName(a.Name.LocalName), a.Value) : a)); + } + } + } + + protected virtual void Map(object x, XElement root) + { + var objType = x.GetType(); + var props = objType.GetProperties(); + + foreach (var prop in props) + { + var type = prop.PropertyType; + + if (!type.IsPublic || !prop.CanWrite) + continue; + + var name = prop.Name.AsNamespaced(Namespace); + var value = GetValueFromXml(root, name, prop); + + if (value == null) + { + // special case for inline list items + if (type.IsGenericType) + { + var genericType = type.GetGenericArguments()[0]; + var first = GetElementByName(root, genericType.Name); + var list = (IList)Activator.CreateInstance(type); + + if (first != null) + { + var elements = root.Elements(first.Name); + PopulateListFromElements(genericType, elements, list); + } + + prop.SetValue(x, list, null); + } + continue; + } + + // check for nullable and extract underlying type + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + // if the value is empty, set the property to null... + if (value == null || String.IsNullOrEmpty(value.ToString())) + { + prop.SetValue(x, null, null); + continue; + } + type = type.GetGenericArguments()[0]; + } + + if (type == typeof(bool)) + { + var toConvert = value.ToString().ToLower(); + prop.SetValue(x, XmlConvert.ToBoolean(toConvert), null); + } + else if (type.IsPrimitive) + { + prop.SetValue(x, value.ChangeType(type, Culture), null); + } + else if (type.IsEnum) + { + var converted = type.FindEnumValue(value.ToString(), Culture); + prop.SetValue(x, converted, null); + } + else if (type == typeof(Uri)) + { + var uri = new Uri(value.ToString(), UriKind.RelativeOrAbsolute); + prop.SetValue(x, uri, null); + } + else if (type == typeof(string)) + { + prop.SetValue(x, value, null); + } + else if (type == typeof(DateTime)) + { + if (DateFormat.HasValue()) + { + value = DateTime.ParseExact(value.ToString(), DateFormat, Culture); + } + else + { + value = DateTime.Parse(value.ToString(), Culture); + } + + prop.SetValue(x, value, null); + } +#if !PocketPC + else if (type == typeof(DateTimeOffset)) + { + var toConvert = value.ToString(); + if (!string.IsNullOrEmpty(toConvert)) + { + DateTimeOffset deserialisedValue; + try + { + deserialisedValue = XmlConvert.ToDateTimeOffset(toConvert); + prop.SetValue(x, deserialisedValue, null); + } + catch (Exception) + { + object result; + if (TryGetFromString(toConvert, out result, type)) + { + prop.SetValue(x, result, null); + } + else + { + //fallback to parse + deserialisedValue = DateTimeOffset.Parse(toConvert); + prop.SetValue(x, deserialisedValue, null); + } + } + } + } +#endif + else if (type == typeof(Decimal)) + { + value = Decimal.Parse(value.ToString(), Culture); + prop.SetValue(x, value, null); + } + else if (type == typeof(Guid)) + { + var raw = value.ToString(); + value = string.IsNullOrEmpty(raw) ? Guid.Empty : new Guid(value.ToString()); + prop.SetValue(x, value, null); + } + else if (type == typeof(TimeSpan)) + { + var timeSpan = XmlConvert.ToTimeSpan(value.ToString()); + prop.SetValue(x, timeSpan, null); + } + else if (type.IsGenericType) + { + var t = type.GetGenericArguments()[0]; + var list = (IList)Activator.CreateInstance(type); + + var container = GetElementByName(root, prop.Name.AsNamespaced(Namespace)); + + if (container.HasElements) + { + var first = container.Elements().FirstOrDefault(); + var elements = container.Elements(first.Name); + PopulateListFromElements(t, elements, list); + } + + prop.SetValue(x, list, null); + } + else if (type.IsSubclassOfRawGeneric(typeof(List<>))) + { + // handles classes that derive from List + // e.g. a collection that also has attributes + var list = HandleListDerivative(x, root, prop.Name, type); + prop.SetValue(x, list, null); + } + else + { + //fallback to type converters if possible + object result; + if (TryGetFromString(value.ToString(), out result, type)) + { + prop.SetValue(x, result, null); + } + else + { + // nested property classes + if (root != null) + { + var element = GetElementByName(root, name); + if (element != null) + { + var item = CreateAndMap(type, element); + prop.SetValue(x, item, null); + } + } + } + } + } + } + + private static bool TryGetFromString(string inputString, out object result, Type type) + { +#if !SILVERLIGHT && !WINDOWS_PHONE && !PocketPC + var converter = TypeDescriptor.GetConverter(type); + if (converter.CanConvertFrom(typeof(string))) + { + result = (converter.ConvertFromInvariantString(inputString)); + return true; + } + result = null; + return false; +#else + result = null; + return false; +#endif + } + + private void PopulateListFromElements(Type t, IEnumerable elements, IList list) + { + foreach (var element in elements) + { + var item = CreateAndMap(t, element); + list.Add(item); + } + } + + private object HandleListDerivative(object x, XElement root, string propName, Type type) + { + Type t; + + if (type.IsGenericType) + { + t = type.GetGenericArguments()[0]; + } + else + { + t = type.BaseType.GetGenericArguments()[0]; + } + + + var list = (IList)Activator.CreateInstance(type); + + var elements = root.Descendants(t.Name.AsNamespaced(Namespace)); + + var name = t.Name; + + if (!elements.Any()) + { + var lowerName = name.ToLower().AsNamespaced(Namespace); + elements = root.Descendants(lowerName); + } + + if (!elements.Any()) + { + var camelName = name.ToCamelCase(Culture).AsNamespaced(Namespace); + elements = root.Descendants(camelName); + } + + if (!elements.Any()) + { + elements = root.Descendants().Where(e => e.Name.LocalName.RemoveUnderscoresAndDashes() == name); + } + + if (!elements.Any()) + { + var lowerName = name.ToLower().AsNamespaced(Namespace); + elements = root.Descendants().Where(e => e.Name.LocalName.RemoveUnderscoresAndDashes() == lowerName); + } + + PopulateListFromElements(t, elements, list); + + // get properties too, not just list items + // only if this isn't a generic type + if (!type.IsGenericType) + { + Map(list, root.Element(propName.AsNamespaced(Namespace)) ?? root); // when using RootElement, the heirarchy is different + } + + return list; + } + + protected virtual object CreateAndMap(Type t, XElement element) + { + object item; + if (t == typeof(String)) + { + item = element.Value; + } + else if (t.IsPrimitive) + { + item = element.Value.ChangeType(t, Culture); + } + else + { + item = Activator.CreateInstance(t); + Map(item, element); + } + + return item; + } + + protected virtual object GetValueFromXml(XElement root, XName name, PropertyInfo prop) + { + object val = null; + + if (root != null) + { + var element = GetElementByName(root, name); + if (element == null) + { + var attribute = GetAttributeByName(root, name); + if (attribute != null) + { + val = attribute.Value; + } + } + else + { + if (!element.IsEmpty || element.HasElements || element.HasAttributes) + { + val = element.Value; + } + } + } + + return val; + } + + protected virtual XElement GetElementByName(XElement root, XName name) + { + var lowerName = name.LocalName.ToLower().AsNamespaced(name.NamespaceName); + var camelName = name.LocalName.ToCamelCase(Culture).AsNamespaced(name.NamespaceName); + + if (root.Element(name) != null) + { + return root.Element(name); + } + + if (root.Element(lowerName) != null) + { + return root.Element(lowerName); + } + + if (root.Element(camelName) != null) + { + return root.Element(camelName); + } + + if (name == "Value".AsNamespaced(name.NamespaceName)) + { + return root; + } + + // try looking for element that matches sanitized property name (Order by depth) + var element = root.Descendants() + .OrderBy(d => d.Ancestors().Count()) + .FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName) + ?? root.Descendants() + .OrderBy(d => d.Ancestors().Count()) + .FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName.ToLower()); + + if (element != null) + { + return element; + } + + return null; + } + + protected virtual XAttribute GetAttributeByName(XElement root, XName name) + { + var lowerName = name.LocalName.ToLower().AsNamespaced(name.NamespaceName); + var camelName = name.LocalName.ToCamelCase(Culture).AsNamespaced(name.NamespaceName); + + if (root.Attribute(name) != null) + { + return root.Attribute(name); + } + + if (root.Attribute(lowerName) != null) + { + return root.Attribute(lowerName); + } + + if (root.Attribute(camelName) != null) + { + return root.Attribute(camelName); + } + + // try looking for element that matches sanitized property name + var element = root.Attributes().FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName); + if (element != null) + { + return element; + } + + return null; + } + } +} diff --git a/Backup/RestSharp.Silverlight/Enum.cs b/Backup/RestSharp.Silverlight/Enum.cs new file mode 100644 index 000000000..942dac2e3 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Enum.cs @@ -0,0 +1,82 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace RestSharp +{ + /// + /// Types of parameters that can be added to requests + /// + public enum ParameterType + { + Cookie, + GetOrPost, + UrlSegment, + HttpHeader, + RequestBody, + QueryString + } + + /// + /// Data formats + /// + public enum DataFormat + { + Json, + Xml + } + + /// + /// HTTP method to use when making requests + /// + public enum Method + { + GET, + POST, + PUT, + DELETE, + HEAD, + OPTIONS, + PATCH, + MERGE, + } + + /// + /// Format strings for commonly-used date formats + /// + public struct DateFormat + { + /// + /// .NET format string for ISO 8601 date format + /// + public const string Iso8601 = "s"; + /// + /// .NET format string for roundtrip date format + /// + public const string RoundTrip = "u"; + } + + /// + /// Status for responses (surprised?) + /// + public enum ResponseStatus + { + None, + Completed, + Error, + TimedOut, + Aborted + } +} diff --git a/Backup/RestSharp.Silverlight/Extensions/MiscExtensions.cs b/Backup/RestSharp.Silverlight/Extensions/MiscExtensions.cs new file mode 100644 index 000000000..110fdba7a --- /dev/null +++ b/Backup/RestSharp.Silverlight/Extensions/MiscExtensions.cs @@ -0,0 +1,128 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System.Globalization; +using System.IO; +using System.Text; + +namespace RestSharp.Extensions +{ + /// + /// Extension method overload! + /// + public static class MiscExtensions + { +#if !WINDOWS_PHONE && !PocketPC + /// + /// Save a byte array to a file + /// + /// Bytes to save + /// Full path to save file to + public static void SaveAs(this byte[] input, string path) + { + File.WriteAllBytes(path, input); + } +#endif + + /// + /// Read a stream into a byte array + /// + /// Stream to read + /// byte[] + public static byte[] ReadAsBytes(this Stream input) + { + byte[] buffer = new byte[16 * 1024]; + using (MemoryStream ms = new MemoryStream()) + { + int read; + while ((read = input.Read(buffer, 0, buffer.Length)) > 0) + { + ms.Write(buffer, 0, read); + } + return ms.ToArray(); + } + } + + /// + /// Copies bytes from one stream to another + /// + /// The input stream. + /// The output stream. + public static void CopyTo(this Stream input, Stream output) + { + var buffer = new byte[32768]; + while(true) + { + var read = input.Read(buffer, 0, buffer.Length); + if(read <= 0) + return; + output.Write(buffer, 0, read); + } + } + + /// + /// Converts a byte array to a string, using its byte order mark to convert it to the right encoding. + /// http://www.shrinkrays.net/code-snippets/csharp/an-extension-method-for-converting-a-byte-array-to-a-string.aspx + /// + /// An array of bytes to convert + /// The byte as a string. + public static string AsString(this byte[] buffer) + { + if (buffer == null) return ""; + + // Ansi as default + Encoding encoding = Encoding.UTF8; + +#if FRAMEWORK + return encoding.GetString(buffer, 0, buffer.Length); +#else + if (buffer == null || buffer.Length == 0) + return ""; + + /* + EF BB BF UTF-8 + FF FE UTF-16 little endian + FE FF UTF-16 big endian + FF FE 00 00 UTF-32, little endian + 00 00 FE FF UTF-32, big-endian + */ + + if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf) + { + encoding = Encoding.UTF8; + } + else if (buffer[0] == 0xfe && buffer[1] == 0xff) + { + encoding = Encoding.Unicode; + } + else if (buffer[0] == 0xfe && buffer[1] == 0xff) + { + encoding = Encoding.BigEndianUnicode; // utf-16be + } + + using (MemoryStream stream = new MemoryStream()) + { + stream.Write(buffer, 0, buffer.Length); + stream.Seek(0, SeekOrigin.Begin); + using (StreamReader reader = new StreamReader(stream, encoding)) + { + return reader.ReadToEnd(); + } + } +#endif + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Extensions/ReflectionExtensions.cs b/Backup/RestSharp.Silverlight/Extensions/ReflectionExtensions.cs new file mode 100644 index 000000000..82fa61625 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Extensions/ReflectionExtensions.cs @@ -0,0 +1,114 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Globalization; +using System.Linq; +using System.Reflection; + +namespace RestSharp.Extensions +{ + /// + /// Reflection extensions + /// + public static class ReflectionExtensions + { + /// + /// Retrieve an attribute from a member (property) + /// + /// Type of attribute to retrieve + /// Member to retrieve attribute from + /// + public static T GetAttribute(this MemberInfo prop) where T : Attribute { + return Attribute.GetCustomAttribute(prop, typeof(T)) as T; + } + + /// + /// Retrieve an attribute from a type + /// + /// Type of attribute to retrieve + /// Type to retrieve attribute from + /// + public static T GetAttribute(this Type type) where T : Attribute { + return Attribute.GetCustomAttribute(type, typeof(T)) as T; + } + + /// + /// Checks a type to see if it derives from a raw generic (e.g. List[[]]) + /// + /// + /// + /// + public static bool IsSubclassOfRawGeneric(this Type toCheck, Type generic) { + while (toCheck != typeof(object)) { + var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck; + if (generic == cur) { + return true; + } + toCheck = toCheck.BaseType; + } + return false; + } + + public static object ChangeType(this object source, Type newType) + { +#if FRAMEWORK && !PocketPC + return Convert.ChangeType(source, newType); +#else + return Convert.ChangeType(source, newType, null); +#endif + } + + public static object ChangeType(this object source, Type newType, CultureInfo culture) + { +#if FRAMEWORK || SILVERLIGHT || WINDOWS_PHONE + return Convert.ChangeType(source, newType, culture); +#else + return Convert.ChangeType(source, newType, null); +#endif + } + + /// + /// Find a value from a System.Enum by trying several possible variants + /// of the string value of the enum. + /// + /// Type of enum + /// Value for which to search + /// The culture used to calculate the name variants + /// + public static object FindEnumValue(this Type type, string value, CultureInfo culture) + { +#if FRAMEWORK && !PocketPC + var ret = Enum.GetValues( type ) + .Cast() + .FirstOrDefault(v => v.ToString().GetNameVariants(culture).Contains(value, StringComparer.Create(culture, true))); + + if (ret == null) + { + var enumValueAsUnderlyingType = Convert.ChangeType(value, Enum.GetUnderlyingType(type), culture); + if (enumValueAsUnderlyingType != null && Enum.IsDefined(type, enumValueAsUnderlyingType)) + { + ret = (Enum) Enum.ToObject(type, enumValueAsUnderlyingType); + } + } + + return ret; +#else + return Enum.Parse(type, value, true); +#endif + } + } +} diff --git a/Backup/RestSharp.Silverlight/Extensions/ResponseExtensions.cs b/Backup/RestSharp.Silverlight/Extensions/ResponseExtensions.cs new file mode 100644 index 000000000..89df2c6bf --- /dev/null +++ b/Backup/RestSharp.Silverlight/Extensions/ResponseExtensions.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RestSharp.Extensions +{ + public static class ResponseExtensions + { + public static IRestResponse toAsyncResponse(this IRestResponse response) + { + return new RestResponse + { + ContentEncoding = response.ContentEncoding, + ContentLength = response.ContentLength, + ContentType = response.ContentType, + Cookies = response.Cookies, + ErrorException = response.ErrorException, + ErrorMessage = response.ErrorMessage, + Headers = response.Headers, + RawBytes = response.RawBytes, + ResponseStatus = response.ResponseStatus, + ResponseUri = response.ResponseUri, + Server = response.Server, + StatusCode = response.StatusCode, + StatusDescription = response.StatusDescription + }; + } + } +} diff --git a/Backup/RestSharp.Silverlight/Extensions/StringExtensions.cs b/Backup/RestSharp.Silverlight/Extensions/StringExtensions.cs new file mode 100644 index 000000000..92dfc35cc --- /dev/null +++ b/Backup/RestSharp.Silverlight/Extensions/StringExtensions.cs @@ -0,0 +1,396 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Globalization; + +#if SILVERLIGHT +using System.Windows.Browser; +#endif + +#if WINDOWS_PHONE +#endif + +#if FRAMEWORK || MONOTOUCH || MONODROID +using RestSharp.Contrib; +#endif + + +namespace RestSharp.Extensions +{ + public static class StringExtensions + { +#if !PocketPC + public static string UrlDecode(this string input) + { + return HttpUtility.UrlDecode(input); + } +#endif + + /// + /// Uses Uri.EscapeDataString() based on recommendations on MSDN + /// http://blogs.msdn.com/b/yangxind/archive/2006/11/09/don-t-use-net-system-uri-unescapedatastring-in-url-decoding.aspx + /// + public static string UrlEncode(this string input) + { + const int maxLength = 32766; + if (input == null) + throw new ArgumentNullException("input"); + + if (input.Length <= maxLength) + return Uri.EscapeDataString(input); + + StringBuilder sb = new StringBuilder(input.Length * 2); + int index = 0; + while (index < input.Length) + { + int length = Math.Min(input.Length - index, maxLength); + string subString = input.Substring(index, length); + sb.Append(Uri.EscapeDataString(subString)); + index += subString.Length; + } + + return sb.ToString(); + } + +#if !PocketPC + public static string HtmlDecode(this string input) + { + return HttpUtility.HtmlDecode(input); + } + + public static string HtmlEncode(this string input) + { + return HttpUtility.HtmlEncode(input); + } +#endif + +#if FRAMEWORK + public static string HtmlAttributeEncode(this string input) + { + return HttpUtility.HtmlAttributeEncode(input); + } +#endif + + /// + /// Check that a string is not null or empty + /// + /// String to check + /// bool + public static bool HasValue(this string input) + { + return !string.IsNullOrEmpty(input); + } + + /// + /// Remove underscores from a string + /// + /// String to process + /// string + public static string RemoveUnderscoresAndDashes(this string input) + { + return input.Replace("_", "").Replace("-", ""); // avoiding regex + } + + /// + /// Parses most common JSON date formats + /// + /// JSON value to parse + /// DateTime + public static DateTime ParseJsonDate(this string input, CultureInfo culture) + { + input = input.Replace("\n", ""); + input = input.Replace("\r", ""); + + input = input.RemoveSurroundingQuotes(); + + long? unix = null; + try { + unix = Int64.Parse(input); + } catch (Exception) { }; + if (unix.HasValue) + { + var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + return epoch.AddSeconds(unix.Value); + } + + if (input.Contains("/Date(")) + { + return ExtractDate(input, @"\\?/Date\((-?\d+)(-|\+)?([0-9]{4})?\)\\?/", culture); + } + + if (input.Contains("new Date(")) + { + input = input.Replace(" ", ""); + // because all whitespace is removed, match against newDate( instead of new Date( + return ExtractDate(input, @"newDate\((-?\d+)*\)", culture); + } + + return ParseFormattedDate(input, culture); + } + + /// + /// Remove leading and trailing " from a string + /// + /// String to parse + /// String + public static string RemoveSurroundingQuotes(this string input) + { + if (input.StartsWith("\"") && input.EndsWith("\"")) + { + // remove leading/trailing quotes + input = input.Substring(1, input.Length - 2); + } + return input; + } + + private static DateTime ParseFormattedDate(string input, CultureInfo culture) + { + var formats = new[] { + "u", + "s", + "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", + "yyyy-MM-ddTHH:mm:ssZ", + "yyyy-MM-dd HH:mm:ssZ", + "yyyy-MM-ddTHH:mm:ss", + "yyyy-MM-ddTHH:mm:sszzzzzz", + "M/d/yyyy h:mm:ss tt" // default format for invariant culture + }; + +#if PocketPC + foreach (string format in formats) { + try { + return DateTime.ParseExact(input, format, culture); + } catch (Exception) { + } + } + try { + return DateTime.Parse(input, culture); + } catch (Exception) { + } +#else + DateTime date; + if (DateTime.TryParseExact(input, formats, culture, DateTimeStyles.None, out date)) + { + return date; + } + if (DateTime.TryParse(input, culture, DateTimeStyles.None, out date)) + { + return date; + } +#endif + + return default(DateTime); + } + + private static DateTime ExtractDate(string input, string pattern, CultureInfo culture) + { + DateTime dt = DateTime.MinValue; + var regex = new Regex(pattern); + if (regex.IsMatch(input)) + { + var matches = regex.Matches(input); + var match = matches[0]; + var ms = Convert.ToInt64(match.Groups[1].Value); + var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + dt = epoch.AddMilliseconds(ms); + + // adjust if time zone modifier present + if (match.Groups.Count > 2 && !String.IsNullOrEmpty(match.Groups[3].Value)) + { + var mod = DateTime.ParseExact(match.Groups[3].Value, "HHmm", culture); + if (match.Groups[2].Value == "+") + { + dt = dt.Add(mod.TimeOfDay); + } + else + { + dt = dt.Subtract(mod.TimeOfDay); + } + } + + } + return dt; + } + + /// + /// Checks a string to see if it matches a regex + /// + /// String to check + /// Pattern to match + /// bool + public static bool Matches(this string input, string pattern) + { + return Regex.IsMatch(input, pattern); + } + + /// + /// Converts a string to pascal case + /// + /// String to convert + /// string + public static string ToPascalCase(this string lowercaseAndUnderscoredWord, CultureInfo culture) + { + return ToPascalCase(lowercaseAndUnderscoredWord, true, culture); + } + + /// + /// Converts a string to pascal case with the option to remove underscores + /// + /// String to convert + /// Option to remove underscores + /// + public static string ToPascalCase(this string text, bool removeUnderscores, CultureInfo culture) + { + if (String.IsNullOrEmpty(text)) + return text; + + text = text.Replace("_", " "); + string joinString = removeUnderscores ? String.Empty : "_"; + string[] words = text.Split(' '); + if (words.Length > 1 || words[0].IsUpperCase()) + { + for (int i = 0; i < words.Length; i++) + { + if (words[i].Length > 0) + { + string word = words[i]; + string restOfWord = word.Substring(1); + + if (restOfWord.IsUpperCase()) + restOfWord = restOfWord.ToLower(culture); + + char firstChar = char.ToUpper(word[0], culture); + words[i] = String.Concat(firstChar, restOfWord); + } + } + return String.Join(joinString, words); + } + return String.Concat(words[0].Substring(0, 1).ToUpper(culture), words[0].Substring(1)); + } + + /// + /// Converts a string to camel case + /// + /// String to convert + /// String + public static string ToCamelCase(this string lowercaseAndUnderscoredWord, CultureInfo culture) + { + return MakeInitialLowerCase(ToPascalCase(lowercaseAndUnderscoredWord, culture)); + } + + /// + /// Convert the first letter of a string to lower case + /// + /// String to convert + /// string + public static string MakeInitialLowerCase(this string word) + { + return String.Concat(word.Substring(0, 1).ToLower(), word.Substring(1)); + } + + /// + /// Checks to see if a string is all uppper case + /// + /// String to check + /// bool + public static bool IsUpperCase(this string inputString) + { + return Regex.IsMatch(inputString, @"^[A-Z]+$"); + } + + /// + /// Add underscores to a pascal-cased string + /// + /// String to convert + /// string + public static string AddUnderscores(this string pascalCasedWord) + { + return + Regex.Replace( + Regex.Replace(Regex.Replace(pascalCasedWord, @"([A-Z]+)([A-Z][a-z])", "$1_$2"), @"([a-z\d])([A-Z])", + "$1_$2"), @"[-\s]", "_"); + } + + /// + /// Add dashes to a pascal-cased string + /// + /// String to convert + /// string + public static string AddDashes(this string pascalCasedWord) + { + return + Regex.Replace( + Regex.Replace( + Regex.Replace(pascalCasedWord, @"([A-Z]+)([A-Z][a-z])", "$1-$2"), + @"([a-z\d])([A-Z])", + "$1-$2"), @"[\s]", "-"); + } + + /// + /// Add an undescore prefix to a pascasl-cased string + /// + /// + /// + public static string AddUnderscorePrefix(this string pascalCasedWord) + { + return string.Format("_{0}", pascalCasedWord); + } + + /// + /// Return possible variants of a name for name matching. + /// + /// String to convert + /// The culture to use for conversion + /// IEnumerable<string> + public static IEnumerable GetNameVariants(this string name, CultureInfo culture) + { + if (String.IsNullOrEmpty(name)) + yield break; + + yield return name; + + // try camel cased name + yield return name.ToCamelCase(culture); + + // try lower cased name + yield return name.ToLower(culture); + + // try name with underscores + yield return name.AddUnderscores(); + + // try name with underscores with lower case + yield return name.AddUnderscores().ToLower(culture); + + // try name with dashes + yield return name.AddDashes(); + + // try name with dashes with lower case + yield return name.AddDashes().ToLower(culture); + + // try name with underscore prefix + yield return name.AddUnderscorePrefix(); + + // try name with underscore prefix, using camel case + yield return name.ToCamelCase(culture).AddUnderscorePrefix(); + } + } +} diff --git a/Backup/RestSharp.Silverlight/Extensions/XmlExtensions.cs b/Backup/RestSharp.Silverlight/Extensions/XmlExtensions.cs new file mode 100644 index 000000000..e35cce9d9 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Extensions/XmlExtensions.cs @@ -0,0 +1,41 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System.Xml.Linq; + +namespace RestSharp.Extensions +{ + /// + /// XML Extension Methods + /// + public static class XmlExtensions + { + /// + /// Returns the name of an element with the namespace if specified + /// + /// Element name + /// XML Namespace + /// + public static XName AsNamespaced(this string name, string @namespace) { + XName xName = name; + + if (@namespace.HasValue()) + xName = XName.Get(name, @namespace); + + return xName; + } + } +} diff --git a/Backup/RestSharp.Silverlight/FileParameter.cs b/Backup/RestSharp.Silverlight/FileParameter.cs new file mode 100644 index 000000000..6f1f197e1 --- /dev/null +++ b/Backup/RestSharp.Silverlight/FileParameter.cs @@ -0,0 +1,69 @@ +using System; +using System.IO; + +namespace RestSharp +{ + /// + /// Container for files to be uploaded with requests + /// + public class FileParameter + { + /// + /// Creates a file parameter from an array of bytes. + /// + ///The parameter name to use in the request. + ///The data to use as the file's contents. + ///The filename to use in the request. + ///The content type to use in the request. + ///The + public static FileParameter Create(string name, byte[] data, string filename, string contentType) + { +#if FRAMEWORK && !PocketPC + var length = data.LongLength; +#else + var length = (long)data.Length; +#endif + return new FileParameter + { + Writer = s => s.Write(data, 0, data.Length), + FileName = filename, + ContentType = contentType, + ContentLength = length, + Name = name + }; + } + + /// + /// Creates a file parameter from an array of bytes. + /// + ///The parameter name to use in the request. + ///The data to use as the file's contents. + ///The filename to use in the request. + ///The using the default content type. + public static FileParameter Create(string name, byte[] data, string filename) + { + return Create(name, data, filename, null); + } + + /// + /// The length of data to be sent + /// + public long ContentLength { get; set; } + /// + /// Provides raw data for file + /// + public Action Writer { get; set; } + /// + /// Name of the file to use when uploading + /// + public string FileName { get; set; } + /// + /// MIME content type of file + /// + public string ContentType { get; set; } + /// + /// Name of the parameter + /// + public string Name { get; set; } + } +} diff --git a/Backup/RestSharp.Silverlight/Http.Async.cs b/Backup/RestSharp.Silverlight/Http.Async.cs new file mode 100644 index 000000000..11235fb69 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Http.Async.cs @@ -0,0 +1,460 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Net; +using System.Threading; +using RestSharp.Extensions; + +#if SILVERLIGHT +using System.Windows.Browser; +using System.Net.Browser; +#endif + +#if WINDOWS_PHONE +using System.Windows.Threading; +using System.Windows; +#endif + +#if (FRAMEWORK && !MONOTOUCH && !MONODROID && !PocketPC) +using System.Web; +#endif + +namespace RestSharp +{ + /// + /// HttpWebRequest wrapper (async methods) + /// + public partial class Http + { + private TimeOutState _timeoutState; + + public HttpWebRequest DeleteAsync(Action action) + { + return GetStyleMethodInternalAsync("DELETE", action); + } + + public HttpWebRequest GetAsync(Action action) + { + return GetStyleMethodInternalAsync("GET", action); + } + + public HttpWebRequest HeadAsync(Action action) + { + return GetStyleMethodInternalAsync("HEAD", action); + } + + public HttpWebRequest OptionsAsync(Action action) + { + return GetStyleMethodInternalAsync("OPTIONS", action); + } + + public HttpWebRequest PostAsync(Action action) + { + return PutPostInternalAsync("POST", action); + } + + public HttpWebRequest PutAsync(Action action) + { + return PutPostInternalAsync("PUT", action); + } + + public HttpWebRequest PatchAsync(Action action) + { + return PutPostInternalAsync("PATCH", action); + } + + public HttpWebRequest MergeAsync(Action action) + { + return PutPostInternalAsync("MERGE", action); + } + + /// + /// Execute an async POST-style request with the specified HTTP Method. + /// + /// The HTTP method to execute. + /// + public HttpWebRequest AsPostAsync(Action action, string httpMethod) + { +#if PocketPC + return PutPostInternalAsync(httpMethod.ToUpper(), action); +#else + return PutPostInternalAsync(httpMethod.ToUpperInvariant(), action); +#endif + } + + /// + /// Execute an async GET-style request with the specified HTTP Method. + /// + /// The HTTP method to execute. + /// + public HttpWebRequest AsGetAsync(Action action, string httpMethod) + { +#if PocketPC + return GetStyleMethodInternalAsync(httpMethod.ToUpper(), action); +#else + return GetStyleMethodInternalAsync(httpMethod.ToUpperInvariant(), action); +#endif + } + + private HttpWebRequest GetStyleMethodInternalAsync(string method, Action callback) + { + HttpWebRequest webRequest = null; + try + { + var url = Url; + webRequest = ConfigureAsyncWebRequest(method, url); + if (HasBody && (method == "DELETE" || method == "OPTIONS")) + { + webRequest.ContentType = RequestContentType; + WriteRequestBodyAsync(webRequest, callback); + } + else + { + _timeoutState = new TimeOutState { Request = webRequest }; + var asyncResult = webRequest.BeginGetResponse(result => ResponseCallback(result, callback), webRequest); + SetTimeout(asyncResult, _timeoutState); + } + } + catch (Exception ex) + { + ExecuteCallback(CreateErrorResponse(ex), callback); + } + return webRequest; + } + + private HttpResponse CreateErrorResponse(Exception ex) + { + var response = new HttpResponse(); + var webException = ex as WebException; + if (webException != null && webException.Status == WebExceptionStatus.RequestCanceled) + { + response.ResponseStatus = _timeoutState.TimedOut ? ResponseStatus.TimedOut : ResponseStatus.Aborted; + return response; + } + + response.ErrorMessage = ex.Message; + response.ErrorException = ex; + response.ResponseStatus = ResponseStatus.Error; + return response; + } + + private HttpWebRequest PutPostInternalAsync(string method, Action callback) + { + HttpWebRequest webRequest = null; + try + { + webRequest = ConfigureAsyncWebRequest(method, Url); + PreparePostBody(webRequest); + WriteRequestBodyAsync(webRequest, callback); + } + catch (Exception ex) + { + ExecuteCallback(CreateErrorResponse(ex), callback); + } + + return webRequest; + } + + private void WriteRequestBodyAsync(HttpWebRequest webRequest, Action callback) + { + IAsyncResult asyncResult; + _timeoutState = new TimeOutState { Request = webRequest }; + + if (HasBody || HasFiles || AlwaysMultipartFormData) + { +#if !WINDOWS_PHONE && !PocketPC + webRequest.ContentLength = CalculateContentLength(); +#endif + asyncResult = webRequest.BeginGetRequestStream(result => RequestStreamCallback(result, callback), webRequest); + } + + else + { + asyncResult = webRequest.BeginGetResponse(r => ResponseCallback(r, callback), webRequest); + } + + SetTimeout(asyncResult, _timeoutState); + } + + private long CalculateContentLength() + { + if (RequestBodyBytes != null) + return RequestBodyBytes.Length; + + if (!HasFiles && !AlwaysMultipartFormData) + { + return _defaultEncoding.GetByteCount(RequestBody); + } + + // calculate length for multipart form + long length = 0; + foreach (var file in Files) + { + length += _defaultEncoding.GetByteCount(GetMultipartFileHeader(file)); + length += file.ContentLength; + length += _defaultEncoding.GetByteCount(_lineBreak); + } + + foreach (var param in Parameters) + { + length += _defaultEncoding.GetByteCount(GetMultipartFormData(param)); + } + + length += _defaultEncoding.GetByteCount(GetMultipartFooter()); + return length; + } + + private void RequestStreamCallback(IAsyncResult result, Action callback) + { + var webRequest = (HttpWebRequest)result.AsyncState; + + if (_timeoutState.TimedOut) + { + var response = new HttpResponse { ResponseStatus = ResponseStatus.TimedOut }; + ExecuteCallback(response, callback); + return; + } + + // write body to request stream + try + { + using (var requestStream = webRequest.EndGetRequestStream(result)) + { + if (HasFiles || AlwaysMultipartFormData) + { + WriteMultipartFormData(requestStream); + } + else if (RequestBodyBytes != null) + { + requestStream.Write(RequestBodyBytes, 0, RequestBodyBytes.Length); + } + else + { + WriteStringTo(requestStream, RequestBody); + } + } + } + catch (Exception ex) + { + ExecuteCallback(CreateErrorResponse(ex), callback); + return; + } + + IAsyncResult asyncResult = webRequest.BeginGetResponse(r => ResponseCallback(r, callback), webRequest); + SetTimeout(asyncResult, _timeoutState); + } + + private void SetTimeout(IAsyncResult asyncResult, TimeOutState timeOutState) + { +#if FRAMEWORK && !PocketPC + if (Timeout != 0) + { + ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), timeOutState, Timeout, true); + } +#endif + } + + private static void TimeoutCallback(object state, bool timedOut) + { + if (!timedOut) + return; + + var timeoutState = state as TimeOutState; + + if (timeoutState == null) + { + return; + } + + lock (timeoutState) + { + timeoutState.TimedOut = true; + } + + if (timeoutState.Request != null) + { + timeoutState.Request.Abort(); + } + } + + private static void GetRawResponseAsync(IAsyncResult result, Action callback) + { + var response = new HttpResponse(); + response.ResponseStatus = ResponseStatus.None; + + HttpWebResponse raw = null; + + try + { + var webRequest = (HttpWebRequest)result.AsyncState; + raw = webRequest.EndGetResponse(result) as HttpWebResponse; + } + catch (WebException ex) + { + if (ex.Status == WebExceptionStatus.RequestCanceled) + { + throw ex; + } + + // Check to see if this is an HTTP error or a transport error. + // In cases where an HTTP error occurs ( status code >= 400 ) + // return the underlying HTTP response, otherwise assume a + // transport exception (ex: connection timeout) and + // rethrow the exception + + if (ex.Response is HttpWebResponse) + { + raw = ex.Response as HttpWebResponse; + } + else + { + throw ex; + } + } + + callback(raw); + raw.Close(); + } + + private void ResponseCallback(IAsyncResult result, Action callback) + { + var response = new HttpResponse { ResponseStatus = ResponseStatus.None }; + + try + { + if (_timeoutState.TimedOut) + { + response.ResponseStatus = ResponseStatus.TimedOut; + ExecuteCallback(response, callback); + return; + } + + GetRawResponseAsync(result, webResponse => + { + ExtractResponseData(response, webResponse); + ExecuteCallback(response, callback); + }); + } + catch (Exception ex) + { + ExecuteCallback(CreateErrorResponse(ex), callback); + } + } + + private static void ExecuteCallback(HttpResponse response, Action callback) + { + callback(response); + } + + partial void AddAsyncHeaderActions() + { +#if SILVERLIGHT + _restrictedHeaderActions.Add("Content-Length", (r, v) => r.ContentLength = Convert.ToInt64(v)); +#endif +#if WINDOWS_PHONE + // WP7 doesn't as of Beta doesn't support a way to set Content-Length either directly + // or indirectly + _restrictedHeaderActions.Add("Content-Length", (r, v) => { }); +#endif + } + + // TODO: Try to merge the shared parts between ConfigureWebRequest and ConfigureAsyncWebRequest (quite a bit of code + // TODO: duplication at the moment). + private HttpWebRequest ConfigureAsyncWebRequest(string method, Uri url) + { +#if SILVERLIGHT + WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp); + WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp); +#endif + var webRequest = (HttpWebRequest)WebRequest.Create(url); +#if !PocketPC + webRequest.UseDefaultCredentials = UseDefaultCredentials; +#endif + +#if !WINDOWS_PHONE && !SILVERLIGHT + webRequest.PreAuthenticate = PreAuthenticate; +#endif + AppendHeaders(webRequest); + AppendCookies(webRequest); + + webRequest.Method = method; + + // make sure Content-Length header is always sent since default is -1 +#if !WINDOWS_PHONE && !PocketPC + // WP7 doesn't as of Beta doesn't support a way to set this value either directly + // or indirectly + if (!HasFiles && !AlwaysMultipartFormData) + { + webRequest.ContentLength = 0; + } +#endif + + if (Credentials != null) + { + webRequest.Credentials = Credentials; + } + +#if !SILVERLIGHT + if (UserAgent.HasValue()) + { + webRequest.UserAgent = UserAgent; + } +#endif + +#if FRAMEWORK + if (ClientCertificates != null) + { + webRequest.ClientCertificates.AddRange(ClientCertificates); + } + + webRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None; + ServicePointManager.Expect100Continue = false; + + if (Timeout != 0) + { + webRequest.Timeout = Timeout; + } + + if (ReadWriteTimeout != 0) + { + webRequest.ReadWriteTimeout = ReadWriteTimeout; + } + + if (Proxy != null) + { + webRequest.Proxy = Proxy; + } + + if (FollowRedirects && MaxRedirects.HasValue) + { + webRequest.MaximumAutomaticRedirections = MaxRedirects.Value; + } +#endif + +#if !SILVERLIGHT + webRequest.AllowAutoRedirect = FollowRedirects; +#endif + return webRequest; + } + + private class TimeOutState + { + public bool TimedOut { get; set; } + public HttpWebRequest Request { get; set; } + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Http.cs b/Backup/RestSharp.Silverlight/Http.cs new file mode 100644 index 000000000..20a633087 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Http.cs @@ -0,0 +1,454 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using RestSharp.Extensions; + +#if WINDOWS_PHONE +using RestSharp.Compression.ZLib; +#endif + +namespace RestSharp +{ + /// + /// HttpWebRequest wrapper + /// + public partial class Http : IHttp, IHttpFactory + { + private const string _lineBreak = "\r\n"; + private static readonly Encoding _defaultEncoding = Encoding.UTF8; + + /// + /// Creates an IHttp + /// + /// + public IHttp Create() + { + return new Http(); + } + + /// + /// True if this HTTP request has any HTTP parameters + /// + protected bool HasParameters + { + get + { + return Parameters.Any(); + } + } + + /// + /// True if this HTTP request has any HTTP cookies + /// + protected bool HasCookies + { + get + { + return Cookies.Any(); + } + } + + /// + /// True if a request body has been specified + /// + protected bool HasBody + { + get + { + return RequestBodyBytes != null || !string.IsNullOrEmpty(RequestBody); + } + } + + /// + /// True if files have been set to be uploaded + /// + protected bool HasFiles + { + get + { + return Files.Any(); + } + } + + /// + /// Always send a multipart/form-data request - even when no Files are present. + /// + public bool AlwaysMultipartFormData { get; set; } + /// + /// UserAgent to be sent with request + /// + public string UserAgent { get; set; } + /// + /// Timeout in milliseconds to be used for the request + /// + public int Timeout { get; set; } + /// + /// The number of milliseconds before the writing or reading times out. + /// + public int ReadWriteTimeout { get; set; } + /// + /// System.Net.ICredentials to be sent with request + /// + public ICredentials Credentials { get; set; } + /// + /// The System.Net.CookieContainer to be used for the request + /// +#if !PocketPC + public CookieContainer CookieContainer { get; set; } +#endif + /// + /// The method to use to write the response instead of reading into RawBytes + /// + public Action ResponseWriter { get; set; } + /// + /// Collection of files to be sent with request + /// + public IList Files { get; private set; } +#if !SILVERLIGHT + /// + /// Whether or not HTTP 3xx response redirects should be automatically followed + /// + public bool FollowRedirects { get; set; } +#endif +#if FRAMEWORK + /// + /// X509CertificateCollection to be sent with request + /// + public X509CertificateCollection ClientCertificates { get; set; } +#endif +#if FRAMEWORK || PocketPC + /// + /// Maximum number of automatic redirects to follow if FollowRedirects is true + /// + public int? MaxRedirects { get; set; } +#endif + /// + /// Determine whether or not the "default credentials" (e.g. the user account under which the current process is running) + /// will be sent along to the server. + /// +#if !PocketPC + public bool UseDefaultCredentials { get; set; } +#endif + /// + /// HTTP headers to be sent with request + /// + public IList Headers { get; private set; } + /// + /// HTTP parameters (QueryString or Form values) to be sent with request + /// + public IList Parameters { get; private set; } + /// + /// HTTP cookies to be sent with request + /// + public IList Cookies { get; private set; } + /// + /// Request body to be sent with request + /// + public string RequestBody { get; set; } + /// + /// Content type of the request body. + /// + public string RequestContentType { get; set; } + /// + /// An alternative to RequestBody, for when the caller already has the byte array. + /// + public byte[] RequestBodyBytes { get; set; } + /// + /// URL to call for this request + /// + public Uri Url { get; set; } + /// + /// Flag to send authorisation header with the HttpWebRequest + /// + public bool PreAuthenticate { get; set; } + +#if FRAMEWORK || PocketPC + /// + /// Proxy info to be sent with request + /// + public IWebProxy Proxy { get; set; } +#endif + + /// + /// Default constructor + /// + public Http() + { + Headers = new List(); + Files = new List(); + Parameters = new List(); + Cookies = new List(); + + _restrictedHeaderActions = new Dictionary>(StringComparer.OrdinalIgnoreCase); + + AddSharedHeaderActions(); + AddSyncHeaderActions(); + } + + partial void AddSyncHeaderActions(); + partial void AddAsyncHeaderActions(); + private void AddSharedHeaderActions() + { + _restrictedHeaderActions.Add("Accept", (r, v) => r.Accept = v); + _restrictedHeaderActions.Add("Content-Type", (r, v) => r.ContentType = v); +#if NET4 + _restrictedHeaderActions.Add("Date", (r, v) => + { + DateTime parsed; + if (DateTime.TryParse(v, out parsed)) + { + r.Date = parsed; + } + }); + _restrictedHeaderActions.Add("Host", (r, v) => r.Host = v); +#else + _restrictedHeaderActions.Add("Date", (r, v) => { /* Set by system */ }); + _restrictedHeaderActions.Add("Host", (r, v) => { /* Set by system */ }); +#endif +#if FRAMEWORK + _restrictedHeaderActions.Add("Range", (r, v) => { AddRange(r, v); }); +#endif + } + + private const string FormBoundary = "-----------------------------28947758029299"; + private static string GetMultipartFormContentType() + { + return string.Format("multipart/form-data; boundary={0}", FormBoundary); + } + + private static string GetMultipartFileHeader (HttpFile file) + { + return string.Format ("--{0}{4}Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"{4}Content-Type: {3}{4}{4}", + FormBoundary, file.Name, file.FileName, file.ContentType ?? "application/octet-stream", _lineBreak); + } + + private static string GetMultipartFormData (HttpParameter param) + { + return string.Format ("--{0}{3}Content-Disposition: form-data; name=\"{1}\"{3}{3}{2}{3}", + FormBoundary, param.Name, param.Value, _lineBreak); + } + + private static string GetMultipartFooter () + { + return string.Format ("--{0}--{1}", FormBoundary, _lineBreak); + } + + private readonly IDictionary> _restrictedHeaderActions; + + // handle restricted headers the .NET way - thanks @dimebrain! + // http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.headers.aspx + private void AppendHeaders(HttpWebRequest webRequest) + { + foreach (var header in Headers) + { + if (_restrictedHeaderActions.ContainsKey(header.Name)) + { + _restrictedHeaderActions[header.Name].Invoke(webRequest, header.Value); + } + else + { +#if FRAMEWORK + webRequest.Headers.Add(header.Name, header.Value); +#else + webRequest.Headers[header.Name] = header.Value; +#endif + } + } + } + + private void AppendCookies(HttpWebRequest webRequest) + { +#if !PocketPC + webRequest.CookieContainer = this.CookieContainer ?? new CookieContainer(); +#endif + foreach (var httpCookie in Cookies) + { +#if !PocketPC +#if FRAMEWORK + var cookie = new Cookie + { + Name = httpCookie.Name, + Value = httpCookie.Value, + Domain = webRequest.RequestUri.Host + }; + webRequest.CookieContainer.Add(cookie); +#else + var cookie = new Cookie + { + Name = httpCookie.Name, + Value = httpCookie.Value + }; + var uri = webRequest.RequestUri; + webRequest.CookieContainer.Add(new Uri(string.Format("{0}://{1}", uri.Scheme, uri.Host)), cookie); +#endif +#endif + } + } + + private string EncodeParameters() + { + var querystring = new StringBuilder(); + foreach (var p in Parameters) + { + if (querystring.Length > 1) + querystring.Append("&"); + querystring.AppendFormat("{0}={1}", p.Name.UrlEncode(), p.Value.UrlEncode()); + } + + return querystring.ToString(); + } + + private void PreparePostBody(HttpWebRequest webRequest) + { + if (HasFiles || AlwaysMultipartFormData) + { + webRequest.ContentType = GetMultipartFormContentType(); + } + else if(HasParameters) + { + webRequest.ContentType = "application/x-www-form-urlencoded"; + RequestBody = EncodeParameters(); + } + else if(HasBody) + { + webRequest.ContentType = RequestContentType; + } + } + + private static void WriteStringTo(Stream stream, string toWrite) + { + var bytes = _defaultEncoding.GetBytes(toWrite); + stream.Write(bytes, 0, bytes.Length); + } + + private void WriteMultipartFormData(Stream requestStream) + { + foreach (var param in Parameters) + { + WriteStringTo(requestStream, GetMultipartFormData(param)); + } + + foreach (var file in Files) + { + // Add just the first part of this param, since we will write the file data directly to the Stream + WriteStringTo(requestStream, GetMultipartFileHeader(file)); + + // Write the file data directly to the Stream, rather than serializing it to a string. + file.Writer(requestStream); + WriteStringTo(requestStream, _lineBreak); + } + + WriteStringTo(requestStream, GetMultipartFooter()); + } + + private void ExtractResponseData(HttpResponse response, HttpWebResponse webResponse) + { + using (webResponse) + { +#if FRAMEWORK + response.ContentEncoding = webResponse.ContentEncoding; + response.Server = webResponse.Server; +#endif + response.ContentType = webResponse.ContentType; + response.ContentLength = webResponse.ContentLength; + Stream webResponseStream = webResponse.GetResponseStream(); +#if WINDOWS_PHONE + if (String.Equals(webResponse.Headers[HttpRequestHeader.ContentEncoding], "gzip", StringComparison.OrdinalIgnoreCase)) + { + var gzStream = new GZipStream(webResponseStream); + ProcessResponseStream(gzStream, response); + } + else + { + ProcessResponseStream(webResponseStream, response); + } +#else + ProcessResponseStream(webResponseStream, response); +#endif + response.StatusCode = webResponse.StatusCode; + response.StatusDescription = webResponse.StatusDescription; + response.ResponseUri = webResponse.ResponseUri; + response.ResponseStatus = ResponseStatus.Completed; + +#if !PocketPC + if (webResponse.Cookies != null) + { + foreach (Cookie cookie in webResponse.Cookies) + { + response.Cookies.Add(new HttpCookie { + Comment = cookie.Comment, + CommentUri = cookie.CommentUri, + Discard = cookie.Discard, + Domain = cookie.Domain, + Expired = cookie.Expired, + Expires = cookie.Expires, + HttpOnly = cookie.HttpOnly, + Name = cookie.Name, + Path = cookie.Path, + Port = cookie.Port, + Secure = cookie.Secure, + TimeStamp = cookie.TimeStamp, + Value = cookie.Value, + Version = cookie.Version + }); + } + } +#endif + foreach (var headerName in webResponse.Headers.AllKeys) + { + var headerValue = webResponse.Headers[headerName]; + response.Headers.Add(new HttpHeader { Name = headerName, Value = headerValue }); + } + + webResponse.Close(); + } + } + + private void ProcessResponseStream(Stream webResponseStream, HttpResponse response) + { + if (ResponseWriter == null) + { + response.RawBytes = webResponseStream.ReadAsBytes(); + } + else + { + ResponseWriter(webResponseStream); + } + } + +#if FRAMEWORK + private void AddRange(HttpWebRequest r, string range) + { + System.Text.RegularExpressions.Match m = System.Text.RegularExpressions.Regex.Match(range, "=(\\d+)-(\\d+)$"); + if (!m.Success) + { + return; + } + + int from = Convert.ToInt32(m.Groups[1].Value); + int to = Convert.ToInt32(m.Groups[2].Value); + r.AddRange(from, to); + } +#endif + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/HttpCookie.cs b/Backup/RestSharp.Silverlight/HttpCookie.cs new file mode 100644 index 000000000..7382590d5 --- /dev/null +++ b/Backup/RestSharp.Silverlight/HttpCookie.cs @@ -0,0 +1,67 @@ +using System; + +namespace RestSharp +{ + /// + /// Representation of an HTTP cookie + /// + public class HttpCookie + { + /// + /// Comment of the cookie + /// + public string Comment { get; set; } + /// + /// Comment of the cookie + /// + public Uri CommentUri { get; set; } + /// + /// Indicates whether the cookie should be discarded at the end of the session + /// + public bool Discard { get; set; } + /// + /// Domain of the cookie + /// + public string Domain { get; set; } + /// + /// Indicates whether the cookie is expired + /// + public bool Expired { get; set; } + /// + /// Date and time that the cookie expires + /// + public DateTime Expires { get; set; } + /// + /// Indicates that this cookie should only be accessed by the server + /// + public bool HttpOnly { get; set; } + /// + /// Name of the cookie + /// + public string Name { get; set; } + /// + /// Path of the cookie + /// + public string Path { get; set; } + /// + /// Port of the cookie + /// + public string Port { get; set; } + /// + /// Indicates that the cookie should only be sent over secure channels + /// + public bool Secure { get; set; } + /// + /// Date and time the cookie was created + /// + public DateTime TimeStamp { get; set; } + /// + /// Value of the cookie + /// + public string Value { get; set; } + /// + /// Version of the cookie + /// + public int Version { get; set; } + } +} diff --git a/Backup/RestSharp.Silverlight/HttpFile.cs b/Backup/RestSharp.Silverlight/HttpFile.cs new file mode 100644 index 000000000..bd7ddbdf7 --- /dev/null +++ b/Backup/RestSharp.Silverlight/HttpFile.cs @@ -0,0 +1,33 @@ +using System; +using System.IO; + +namespace RestSharp +{ + /// + /// Container for HTTP file + /// + public class HttpFile + { + + /// + /// The length of data to be sent + /// + public long ContentLength { get; set; } + /// + /// Provides raw data for file + /// + public Action Writer { get; set; } + /// + /// Name of the file to use when uploading + /// + public string FileName { get; set; } + /// + /// MIME content type of file + /// + public string ContentType { get; set; } + /// + /// Name of the parameter + /// + public string Name { get; set; } + } +} diff --git a/Backup/RestSharp.Silverlight/HttpHeader.cs b/Backup/RestSharp.Silverlight/HttpHeader.cs new file mode 100644 index 000000000..f2ef461f0 --- /dev/null +++ b/Backup/RestSharp.Silverlight/HttpHeader.cs @@ -0,0 +1,17 @@ +namespace RestSharp +{ + /// + /// Representation of an HTTP header + /// + public class HttpHeader + { + /// + /// Name of the header + /// + public string Name { get; set; } + /// + /// Value of the header + /// + public string Value { get; set; } + } +} diff --git a/Backup/RestSharp.Silverlight/HttpParameter.cs b/Backup/RestSharp.Silverlight/HttpParameter.cs new file mode 100644 index 000000000..8423a80fb --- /dev/null +++ b/Backup/RestSharp.Silverlight/HttpParameter.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RestSharp +{ + /// + /// Representation of an HTTP parameter (QueryString or Form value) + /// + public class HttpParameter + { + /// + /// Name of the parameter + /// + public string Name { get; set; } + /// + /// Value of the parameter + /// + public string Value { get; set; } + } +} diff --git a/Backup/RestSharp.Silverlight/HttpResponse.cs b/Backup/RestSharp.Silverlight/HttpResponse.cs new file mode 100644 index 000000000..83ffb782e --- /dev/null +++ b/Backup/RestSharp.Silverlight/HttpResponse.cs @@ -0,0 +1,122 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections.Generic; +using System.Net; +using RestSharp.Extensions; + +namespace RestSharp +{ + /// + /// HTTP response data + /// + public class HttpResponse : IHttpResponse + { + private string _content; + + /// + /// Default constructor + /// + public HttpResponse() + { + Headers = new List(); + Cookies = new List(); + } + + /// + /// MIME content type of response + /// + public string ContentType { get; set; } + /// + /// Length in bytes of the response content + /// + public long ContentLength { get; set; } + /// + /// Encoding of the response content + /// + public string ContentEncoding { get; set; } + /// + /// Lazy-loaded string representation of response content + /// + public string Content + { + get + { + if (_content == null) + { + _content = RawBytes.AsString(); + } + return _content; + } + } + /// + /// HTTP response status code + /// + public HttpStatusCode StatusCode { get; set; } + /// + /// Description of HTTP status returned + /// + public string StatusDescription { get; set; } + /// + /// Response content + /// + public byte[] RawBytes { get; set; } + /// + /// The URL that actually responded to the content (different from request if redirected) + /// + public Uri ResponseUri { get; set; } + /// + /// HttpWebResponse.Server + /// + public string Server { get; set; } + /// + /// Headers returned by server with the response + /// + public IList Headers { get; private set; } + /// + /// Cookies returned by server with the response + /// + public IList Cookies { get; private set; } + + private ResponseStatus _responseStatus = ResponseStatus.None; + /// + /// Status of the request. Will return Error for transport errors. + /// HTTP errors will still return ResponseStatus.Completed, check StatusCode instead + /// + public ResponseStatus ResponseStatus + { + get + { + return _responseStatus; + } + set + { + _responseStatus = value; + } + } + + /// + /// Transport or other non-HTTP error generated while attempting request + /// + public string ErrorMessage { get; set; } + + /// + /// Exception thrown when error is encountered. + /// + public Exception ErrorException { get; set; } + } +} diff --git a/Backup/RestSharp.Silverlight/IHttp.cs b/Backup/RestSharp.Silverlight/IHttp.cs new file mode 100644 index 000000000..bf3e7ea7f --- /dev/null +++ b/Backup/RestSharp.Silverlight/IHttp.cs @@ -0,0 +1,92 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Security.Cryptography.X509Certificates; + +namespace RestSharp +{ + public interface IHttp + { + Action ResponseWriter { get; set; } +#if !PocketPC + CookieContainer CookieContainer { get; set; } +#endif + ICredentials Credentials { get; set; } + + /// + /// Always send a multipart/form-data request - even when no Files are present. + /// + bool AlwaysMultipartFormData { get; set; } + + string UserAgent { get; set; } + int Timeout { get; set; } + int ReadWriteTimeout { get; set; } +#if !SILVERLIGHT + bool FollowRedirects { get; set; } +#endif +#if FRAMEWORK + X509CertificateCollection ClientCertificates { get; set; } + int? MaxRedirects { get; set; } +#endif +#if !PocketPC + bool UseDefaultCredentials { get; set; } +#endif + IList Headers { get; } + IList Parameters { get; } + IList Files { get; } + IList Cookies { get; } + string RequestBody { get; set; } + string RequestContentType { get; set; } + bool PreAuthenticate { get; set; } + + /// + /// An alternative to RequestBody, for when the caller already has the byte array. + /// + byte[] RequestBodyBytes { get; set; } + + Uri Url { get; set; } + + HttpWebRequest DeleteAsync(Action action); + HttpWebRequest GetAsync(Action action); + HttpWebRequest HeadAsync(Action action); + HttpWebRequest OptionsAsync(Action action); + HttpWebRequest PostAsync(Action action); + HttpWebRequest PutAsync(Action action); + HttpWebRequest PatchAsync(Action action); + HttpWebRequest MergeAsync(Action action); + HttpWebRequest AsPostAsync(Action action, string httpMethod); + HttpWebRequest AsGetAsync(Action action, string httpMethod); + +#if FRAMEWORK || PocketPC + HttpResponse Delete(); + HttpResponse Get(); + HttpResponse Head(); + HttpResponse Options(); + HttpResponse Post(); + HttpResponse Put(); + HttpResponse Patch(); + HttpResponse Merge(); + HttpResponse AsPost(string httpMethod); + HttpResponse AsGet(string httpMethod); + + IWebProxy Proxy { get; set; } +#endif + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/IHttpFactory.cs b/Backup/RestSharp.Silverlight/IHttpFactory.cs new file mode 100644 index 000000000..bbcad8463 --- /dev/null +++ b/Backup/RestSharp.Silverlight/IHttpFactory.cs @@ -0,0 +1,15 @@ +namespace RestSharp +{ + public interface IHttpFactory + { + IHttp Create(); + } + + public class SimpleFactory : IHttpFactory where T : IHttp, new() + { + public IHttp Create() + { + return new T(); + } + } +} diff --git a/Backup/RestSharp.Silverlight/IHttpResponse.cs b/Backup/RestSharp.Silverlight/IHttpResponse.cs new file mode 100644 index 000000000..91f05dec1 --- /dev/null +++ b/Backup/RestSharp.Silverlight/IHttpResponse.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Net; + +namespace RestSharp +{ + /// + /// HTTP response data + /// + public interface IHttpResponse + { + /// + /// MIME content type of response + /// + string ContentType { get; set; } + + /// + /// Length in bytes of the response content + /// + long ContentLength { get; set; } + + /// + /// Encoding of the response content + /// + string ContentEncoding { get; set; } + + /// + /// String representation of response content + /// + string Content { get; } + + /// + /// HTTP response status code + /// + HttpStatusCode StatusCode { get; set; } + + /// + /// Description of HTTP status returned + /// + string StatusDescription { get; set; } + + /// + /// Response content + /// + byte[] RawBytes { get; set; } + + /// + /// The URL that actually responded to the content (different from request if redirected) + /// + Uri ResponseUri { get; set; } + + /// + /// HttpWebResponse.Server + /// + string Server { get; set; } + + /// + /// Headers returned by server with the response + /// + IList Headers { get; } + + /// + /// Cookies returned by server with the response + /// + IList Cookies { get; } + + /// + /// Status of the request. Will return Error for transport errors. + /// HTTP errors will still return ResponseStatus.Completed, check StatusCode instead + /// + ResponseStatus ResponseStatus { get; set; } + + /// + /// Transport or other non-HTTP error generated while attempting request + /// + string ErrorMessage { get; set; } + + /// + /// Exception thrown when error is encountered. + /// + Exception ErrorException { get; set; } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/IRestClient.cs b/Backup/RestSharp.Silverlight/IRestClient.cs new file mode 100644 index 000000000..0a8ce2c29 --- /dev/null +++ b/Backup/RestSharp.Silverlight/IRestClient.cs @@ -0,0 +1,222 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Net; +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; +#if NET4 || MONODROID || MONOTOUCH || WP8 +using System.Threading; +using System.Threading.Tasks; +#endif + +namespace RestSharp +{ + /// + /// + /// + public interface IRestClient + { + /// + /// + /// +#if !PocketPC + CookieContainer CookieContainer { get; set; } +#endif + /// + /// + /// + string UserAgent { get; set; } + /// + /// + /// + int Timeout { get; set; } + /// + /// + /// + int ReadWriteTimeout { get; set; } + /// + /// + /// + bool UseSynchronizationContext { get; set; } + /// + /// + /// + IAuthenticator Authenticator { get; set; } + /// + /// + /// + string BaseUrl { get; set; } + /// + /// + /// + bool PreAuthenticate { get; set; } + /// + /// + /// + IList DefaultParameters { get; } + /// + /// + /// + /// + RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action callback); + /// + /// + /// + /// + RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action, RestRequestAsyncHandle> callback); + +#if FRAMEWORK + /// + /// X509CertificateCollection to be sent with request + /// + X509CertificateCollection ClientCertificates { get; set; } + IRestResponse Execute(IRestRequest request); + IRestResponse Execute(IRestRequest request) where T : new(); + + IWebProxy Proxy { get; set; } +#endif + + Uri BuildUri(IRestRequest request); + + /// + /// Executes a GET-style request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// Callback function to be executed upon completion providing access to the async handle. + /// The HTTP method to execute + RestRequestAsyncHandle ExecuteAsyncGet(IRestRequest request, Action callback, string httpMethod); + + /// + /// Executes a POST-style request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// Callback function to be executed upon completion providing access to the async handle. + /// The HTTP method to execute + RestRequestAsyncHandle ExecuteAsyncPost(IRestRequest request, Action callback, string httpMethod); + + /// + /// Executes a GET-style request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// Callback function to be executed upon completion + /// The HTTP method to execute + RestRequestAsyncHandle ExecuteAsyncGet(IRestRequest request, Action, RestRequestAsyncHandle> callback, string httpMethod); + + /// + /// Executes a GET-style request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// Callback function to be executed upon completion + /// The HTTP method to execute + RestRequestAsyncHandle ExecuteAsyncPost(IRestRequest request, Action, RestRequestAsyncHandle> callback, string httpMethod); + +#if FRAMEWORK + IRestResponse ExecuteAsGet(IRestRequest request, string httpMethod); + IRestResponse ExecuteAsPost(IRestRequest request, string httpMethod); + IRestResponse ExecuteAsGet(IRestRequest request, string httpMethod) where T : new(); + IRestResponse ExecuteAsPost(IRestRequest request, string httpMethod) where T : new(); +#endif + +#if NET4 || MONODROID || MONOTOUCH || WP8 + /// + /// Executes the request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + Task> ExecuteTaskAsync(IRestRequest request, CancellationToken token); + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + Task> ExecuteTaskAsync(IRestRequest request); + + /// + /// Executes a GET-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + Task> ExecuteGetTaskAsync(IRestRequest request); + + /// + /// Executes a GET-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + Task> ExecuteGetTaskAsync(IRestRequest request, CancellationToken token); + + /// + /// Executes a POST-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + Task> ExecutePostTaskAsync(IRestRequest request); + + /// + /// Executes a POST-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + Task> ExecutePostTaskAsync(IRestRequest request, CancellationToken token); + + /// + /// Executes the request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + Task ExecuteTaskAsync(IRestRequest request, CancellationToken token); + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Request to be executed + Task ExecuteTaskAsync(IRestRequest request); + + /// + /// Executes a GET-style asynchronously, authenticating if needed + /// + /// Request to be executed + Task ExecuteGetTaskAsync(IRestRequest request); + + /// + /// Executes a GET-style asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + Task ExecuteGetTaskAsync(IRestRequest request, CancellationToken token); + + /// + /// Executes a POST-style asynchronously, authenticating if needed + /// + /// Request to be executed + Task ExecutePostTaskAsync(IRestRequest request); + + /// + /// Executes a POST-style asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + Task ExecutePostTaskAsync(IRestRequest request, CancellationToken token); +#endif + } +} diff --git a/Backup/RestSharp.Silverlight/IRestRequest.cs b/Backup/RestSharp.Silverlight/IRestRequest.cs new file mode 100644 index 000000000..942c64cdc --- /dev/null +++ b/Backup/RestSharp.Silverlight/IRestRequest.cs @@ -0,0 +1,251 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using RestSharp.Serializers; + +namespace RestSharp +{ + public interface IRestRequest + { + /// + /// Always send a multipart/form-data request - even when no Files are present. + /// + bool AlwaysMultipartFormData { get; set; } + + /// + /// Serializer to use when writing JSON request bodies. Used if RequestFormat is Json. + /// By default the included JsonSerializer is used (currently using JSON.NET default serialization). + /// + ISerializer JsonSerializer { get; set; } + + /// + /// Serializer to use when writing XML request bodies. Used if RequestFormat is Xml. + /// By default the included XmlSerializer is used. + /// + ISerializer XmlSerializer { get; set; } + + /// + /// Set this to write response to Stream rather than reading into memory. + /// + Action ResponseWriter { get; set; } + + /// + /// Container of all HTTP parameters to be passed with the request. + /// See AddParameter() for explanation of the types of parameters that can be passed + /// + List Parameters { get; } + + /// + /// Container of all the files to be uploaded with the request. + /// + List Files { get; } + + /// + /// Determines what HTTP method to use for this request. Supported methods: GET, POST, PUT, DELETE, HEAD, OPTIONS + /// Default is GET + /// + Method Method { get; set; } + + /// + /// The Resource URL to make the request against. + /// Tokens are substituted with UrlSegment parameters and match by name. + /// Should not include the scheme or domain. Do not include leading slash. + /// Combined with RestClient.BaseUrl to assemble final URL: + /// {BaseUrl}/{Resource} (BaseUrl is scheme + domain, e.g. http://example.com) + /// + /// + /// // example for url token replacement + /// request.Resource = "Products/{ProductId}"; + /// request.AddParameter("ProductId", 123, ParameterType.UrlSegment); + /// + string Resource { get; set; } + + /// + /// Serializer to use when writing XML request bodies. Used if RequestFormat is Xml. + /// By default XmlSerializer is used. + /// + DataFormat RequestFormat { get; set; } + + /// + /// Used by the default deserializers to determine where to start deserializing from. + /// Can be used to skip container or root elements that do not have corresponding deserialzation targets. + /// + string RootElement { get; set; } + + /// + /// Used by the default deserializers to explicitly set which date format string to use when parsing dates. + /// + string DateFormat { get; set; } + + /// + /// Used by XmlDeserializer. If not specified, XmlDeserializer will flatten response by removing namespaces from element names. + /// + string XmlNamespace { get; set; } + + /// + /// In general you would not need to set this directly. Used by the NtlmAuthenticator. + /// + ICredentials Credentials { get; set; } + + /// + /// Timeout in milliseconds to be used for the request. This timeout value overrides a timeout set on the RestClient. + /// + int Timeout { get; set; } + + /// + /// The number of milliseconds before the writing or reading times out. This timeout value overrides a timeout set on the RestClient. + /// + int ReadWriteTimeout { get; set; } + + /// + /// How many attempts were made to send this Request? + /// + /// + /// This Number is incremented each time the RestClient sends the request. + /// Useful when using Asynchronous Execution with Callbacks + /// + int Attempts { get; } + + /// + /// Determine whether or not the "default credentials" (e.g. the user account under which the current process is running) + /// will be sent along to the server. The default is false. + /// + bool UseDefaultCredentials { get; set; } + +#if FRAMEWORK + /// + /// Adds a file to the Files collection to be included with a POST or PUT request + /// (other methods do not support file uploads). + /// + /// The parameter name to use in the request + /// Full path to file to upload + /// This request + IRestRequest AddFile (string name, string path); + + /// + /// Adds the bytes to the Files collection with the specified file name + /// + /// The parameter name to use in the request + /// The file data + /// The file name to use for the uploaded file + /// This request + IRestRequest AddFile (string name, byte[] bytes, string fileName); + + /// + /// Adds the bytes to the Files collection with the specified file name and content type + /// + /// The parameter name to use in the request + /// The file data + /// The file name to use for the uploaded file + /// The MIME type of the file to upload + /// This request + IRestRequest AddFile (string name, byte[] bytes, string fileName, string contentType); +#endif + + /// + /// Serializes obj to format specified by RequestFormat, but passes xmlNamespace if using the default XmlSerializer + /// + /// The object to serialize + /// The XML namespace to use when serializing + /// This request + IRestRequest AddBody (object obj, string xmlNamespace); + + /// + /// Serializes obj to data format specified by RequestFormat and adds it to the request body. + /// + /// The object to serialize + /// This request + IRestRequest AddBody (object obj); + + /// + /// Calls AddParameter() for all public, readable properties specified in the white list + /// + /// + /// request.AddObject(product, "ProductId", "Price", ...); + /// + /// The object with properties to add as parameters + /// The names of the properties to include + /// This request + IRestRequest AddObject (object obj, params string[] whitelist); + + /// + /// Calls AddParameter() for all public, readable properties of obj + /// + /// The object with properties to add as parameters + /// This request + IRestRequest AddObject (object obj); + + /// + /// Add the parameter to the request + /// + /// Parameter to add + /// + IRestRequest AddParameter (Parameter p); + + /// + /// Adds a HTTP parameter to the request (QueryString for GET, DELETE, OPTIONS and HEAD; Encoded form for POST and PUT) + /// + /// Name of the parameter + /// Value of the parameter + /// This request + IRestRequest AddParameter (string name, object value); + + /// + /// Adds a parameter to the request. There are five types of parameters: + /// - GetOrPost: Either a QueryString value or encoded form value based on method + /// - HttpHeader: Adds the name/value pair to the HTTP request's Headers collection + /// - UrlSegment: Inserted into URL if there is a matching url token e.g. {AccountId} + /// - Cookie: Adds the name/value pair to the HTTP request's Cookies collection + /// - RequestBody: Used by AddBody() (not recommended to use directly) + /// + /// Name of the parameter + /// Value of the parameter + /// The type of parameter to add + /// This request + IRestRequest AddParameter (string name, object value, ParameterType type); + + /// + /// Shortcut to AddParameter(name, value, HttpHeader) overload + /// + /// Name of the header to add + /// Value of the header to add + /// + IRestRequest AddHeader (string name, string value); + + /// + /// Shortcut to AddParameter(name, value, Cookie) overload + /// + /// Name of the cookie to add + /// Value of the cookie to add + /// + IRestRequest AddCookie (string name, string value); + + /// + /// Shortcut to AddParameter(name, value, UrlSegment) overload + /// + /// Name of the segment to add + /// Value of the segment to add + /// + IRestRequest AddUrlSegment(string name, string value); + + Action OnBeforeDeserialization { get; set; } + void IncreaseNumAttempts(); + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/IRestResponse.cs b/Backup/RestSharp.Silverlight/IRestResponse.cs new file mode 100644 index 000000000..8573401c5 --- /dev/null +++ b/Backup/RestSharp.Silverlight/IRestResponse.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.Net; + +namespace RestSharp +{ + /// + /// Container for data sent back from API + /// + public interface IRestResponse + { + /// + /// The RestRequest that was made to get this RestResponse + /// + /// + /// Mainly for debugging if ResponseStatus is not OK + /// + IRestRequest Request { get; set; } + + /// + /// MIME content type of response + /// + string ContentType { get; set; } + + /// + /// Length in bytes of the response content + /// + long ContentLength { get; set; } + + /// + /// Encoding of the response content + /// + string ContentEncoding { get; set; } + + /// + /// String representation of response content + /// + string Content { get; set; } + + /// + /// HTTP response status code + /// + HttpStatusCode StatusCode { get; set; } + + /// + /// Description of HTTP status returned + /// + string StatusDescription { get; set; } + + /// + /// Response content + /// + byte[] RawBytes { get; set; } + + /// + /// The URL that actually responded to the content (different from request if redirected) + /// + Uri ResponseUri { get; set; } + + /// + /// HttpWebResponse.Server + /// + string Server { get; set; } + + /// + /// Cookies returned by server with the response + /// + IList Cookies { get; } + + /// + /// Headers returned by server with the response + /// + IList Headers { get; } + + /// + /// Status of the request. Will return Error for transport errors. + /// HTTP errors will still return ResponseStatus.Completed, check StatusCode instead + /// + ResponseStatus ResponseStatus { get; set; } + + /// + /// Transport or other non-HTTP error generated while attempting request + /// + string ErrorMessage { get; set; } + + /// + /// Exceptions thrown during the request, if any. + /// + /// Will contain only network transport or framework exceptions thrown during the request. HTTP protocol errors are handled by RestSharp and will not appear here. + Exception ErrorException { get; set; } + } + + /// + /// Container for data sent back from API including deserialized data + /// + /// Type of data to deserialize to + public interface IRestResponse : IRestResponse + { + /// + /// Deserialized entity data + /// + T Data { get; set; } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Parameter.cs b/Backup/RestSharp.Silverlight/Parameter.cs new file mode 100644 index 000000000..1b56b4045 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Parameter.cs @@ -0,0 +1,45 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace RestSharp +{ + /// + /// Parameter container for REST requests + /// + public class Parameter + { + /// + /// Name of the parameter + /// + public string Name { get; set; } + /// + /// Value of the parameter + /// + public object Value { get; set; } + /// + /// Type of the parameter + /// + public ParameterType Type { get; set; } + + /// + /// Return a human-readable representation of this parameter + /// + /// String + public override string ToString() { + return string.Format("{0}={1}", Name, Value); + } + } +} diff --git a/Backup/RestSharp.Silverlight/Properties/AssemblyInfo.cs b/Backup/RestSharp.Silverlight/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..14455cf8c --- /dev/null +++ b/Backup/RestSharp.Silverlight/Properties/AssemblyInfo.cs @@ -0,0 +1,16 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RestSharp.Silverlight")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2314f291-c979-46b1-932c-f3ae123a3cef")] \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/RestClient.Async.cs b/Backup/RestSharp.Silverlight/RestClient.Async.cs new file mode 100644 index 000000000..7e140ce19 --- /dev/null +++ b/Backup/RestSharp.Silverlight/RestClient.Async.cs @@ -0,0 +1,397 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +#if NET4 || MONODROID || MONOTOUCH || WP8 +using System.Threading.Tasks; +#endif +using System.Text; +using System.Net; + +using RestSharp.Extensions; + +namespace RestSharp +{ + public partial class RestClient + { + /// + /// Executes the request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// Callback function to be executed upon completion providing access to the async handle. + public virtual RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action callback) + { +#if PocketPC + string method = request.Method.ToString(); +#else + string method = Enum.GetName(typeof(Method), request.Method); +#endif + switch (request.Method) + { + case Method.MERGE: + case Method.PATCH: + case Method.POST: + case Method.PUT: + return ExecuteAsync(request, callback, method, DoAsPostAsync); + default: + return ExecuteAsync(request, callback, method, DoAsGetAsync); + } + } + + /// + /// Executes a GET-style request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// Callback function to be executed upon completion providing access to the async handle. + /// The HTTP method to execute + public virtual RestRequestAsyncHandle ExecuteAsyncGet(IRestRequest request, Action callback, string httpMethod) + { + return ExecuteAsync(request, callback, httpMethod, DoAsGetAsync); + } + + /// + /// Executes a POST-style request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// Callback function to be executed upon completion providing access to the async handle. + /// The HTTP method to execute + public virtual RestRequestAsyncHandle ExecuteAsyncPost(IRestRequest request, Action callback, string httpMethod) + { + request.Method = Method.POST; // Required by RestClient.BuildUri... + return ExecuteAsync(request, callback, httpMethod, DoAsPostAsync); + } + + private RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action callback, string httpMethod, Func, string, HttpWebRequest> getWebRequest) + { + var http = HttpFactory.Create(); + AuthenticateIfNeeded(this, request); + + ConfigureHttp(request, http); + + var asyncHandle = new RestRequestAsyncHandle(); + + Action response_cb = r => ProcessResponse(request, r, asyncHandle, callback); + +#if !PocketPC + if (UseSynchronizationContext && SynchronizationContext.Current != null) + { + var ctx = SynchronizationContext.Current; + var cb = response_cb; + + response_cb = resp => ctx.Post(s => cb(resp), null); + } +#endif + asyncHandle.WebRequest = getWebRequest(http, response_cb, httpMethod); + return asyncHandle; + } + + private static HttpWebRequest DoAsGetAsync(IHttp http, Action response_cb, string method) + { + return http.AsGetAsync(response_cb, method); + } + + private static HttpWebRequest DoAsPostAsync(IHttp http, Action response_cb, string method) + { + return http.AsPostAsync(response_cb, method); + } + + private void ProcessResponse(IRestRequest request, HttpResponse httpResponse, RestRequestAsyncHandle asyncHandle, Action callback) + { + var restResponse = ConvertToRestResponse(request, httpResponse); + callback(restResponse, asyncHandle); + } + + /// + /// Executes the request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// Callback function to be executed upon completion + public virtual RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action, RestRequestAsyncHandle> callback) + { + return ExecuteAsync(request, (response, asyncHandle) => DeserializeResponse(request, callback, response, asyncHandle)); + } + + /// + /// Executes a GET-style request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// Callback function to be executed upon completion + /// The HTTP method to execute + public virtual RestRequestAsyncHandle ExecuteAsyncGet(IRestRequest request, Action, RestRequestAsyncHandle> callback, string httpMethod) + { + return ExecuteAsyncGet(request, (response, asyncHandle) => DeserializeResponse(request, callback, response, asyncHandle), httpMethod); + } + + /// + /// Executes a POST-style request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// Callback function to be executed upon completion + /// The HTTP method to execute + public virtual RestRequestAsyncHandle ExecuteAsyncPost(IRestRequest request, Action, RestRequestAsyncHandle> callback, string httpMethod) + { + return ExecuteAsyncPost(request, (response, asyncHandle) => DeserializeResponse(request, callback, response, asyncHandle), httpMethod); + } + + private void DeserializeResponse(IRestRequest request, Action, RestRequestAsyncHandle> callback, IRestResponse response, RestRequestAsyncHandle asyncHandle) + { + IRestResponse restResponse; + + try + { + restResponse = Deserialize(request, response); + } + catch (Exception ex) + { + restResponse = new RestResponse { Request = request, ResponseStatus = ResponseStatus.Error, ErrorMessage = ex.Message, ErrorException = ex}; + } + + callback(restResponse, asyncHandle); + } + +#if NET4 || MONODROID || MONOTOUCH || WP8 + /// + /// Executes a GET-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + public virtual Task> ExecuteGetTaskAsync(IRestRequest request) + { + return ExecuteGetTaskAsync(request, CancellationToken.None); + } + + /// + /// Executes a GET-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + public virtual Task> ExecuteGetTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + request.Method = Method.GET; + return ExecuteTaskAsync(request, token); + } + + /// + /// Executes a POST-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + public virtual Task> ExecutePostTaskAsync(IRestRequest request) + { + return ExecutePostTaskAsync(request, CancellationToken.None); + } + + /// + /// Executes a POST-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + public virtual Task> ExecutePostTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + request.Method = Method.POST; + return ExecuteTaskAsync(request, token); + } + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + public virtual Task> ExecuteTaskAsync(IRestRequest request) + { + return ExecuteTaskAsync(request, CancellationToken.None); + } + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + public virtual Task> ExecuteTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + var taskCompletionSource = new TaskCompletionSource>(); + + try + { + var async = ExecuteAsync(request, (response, _) => + { + if (token.IsCancellationRequested) + { + taskCompletionSource.TrySetCanceled(); + } + else if (response.ErrorException != null) + { + taskCompletionSource.TrySetException(response.ErrorException); + } + else if (response.ResponseStatus != ResponseStatus.Completed) + { + taskCompletionSource.TrySetException(response.ResponseStatus.ToWebException()); + } + else + { + taskCompletionSource.TrySetResult(response); + } + }); + + token.Register(() => + { + async.Abort(); + taskCompletionSource.TrySetCanceled(); + }); + } + catch (Exception ex) + { + taskCompletionSource.TrySetException(ex); + } + + return taskCompletionSource.Task; + } + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Request to be executed + public virtual Task ExecuteTaskAsync(IRestRequest request) + { + return ExecuteTaskAsync(request, CancellationToken.None); + } + + /// + /// Executes a GET-style asynchronously, authenticating if needed + /// + /// Request to be executed + public virtual Task ExecuteGetTaskAsync(IRestRequest request) + { + return this.ExecuteGetTaskAsync(request, CancellationToken.None); + } + + /// + /// Executes a GET-style asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + public virtual Task ExecuteGetTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + request.Method = Method.GET; + return ExecuteTaskAsync(request, token); + } + + /// + /// Executes a POST-style asynchronously, authenticating if needed + /// + /// Request to be executed + public virtual Task ExecutePostTaskAsync(IRestRequest request) + { + return this.ExecutePostTaskAsync(request, CancellationToken.None); + } + + /// + /// Executes a POST-style asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + public virtual Task ExecutePostTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + request.Method = Method.POST; + return ExecuteTaskAsync(request, token); + } + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + public virtual Task ExecuteTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + var taskCompletionSource = new TaskCompletionSource(); + + try + { + var async = this.ExecuteAsync(request, (response, _) => + { + if (token.IsCancellationRequested) + { + taskCompletionSource.TrySetCanceled(); + } + else if (response.ErrorException != null) + { + taskCompletionSource.TrySetException(response.ErrorException); + } + else if (response.ResponseStatus != ResponseStatus.Completed) + { + taskCompletionSource.TrySetException(response.ResponseStatus.ToWebException()); + } + else + { + taskCompletionSource.TrySetResult(response); + } + }); + + token.Register(() => + { + async.Abort(); + taskCompletionSource.TrySetCanceled(); + }); + } + catch (Exception ex) + { + taskCompletionSource.TrySetException(ex); + } + + return taskCompletionSource.Task; + } +#endif + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/RestClient.cs b/Backup/RestSharp.Silverlight/RestClient.cs new file mode 100644 index 000000000..94f669411 --- /dev/null +++ b/Backup/RestSharp.Silverlight/RestClient.cs @@ -0,0 +1,533 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using RestSharp.Deserializers; +using RestSharp.Extensions; + +namespace RestSharp +{ + /// + /// Client to translate RestRequests into Http requests and process response result + /// + public partial class RestClient : IRestClient + { + // silverlight friendly way to get current version +#if PocketPC + static readonly Version version = Assembly.GetExecutingAssembly().GetName().Version; +#else + static readonly Version version = new AssemblyName(Assembly.GetExecutingAssembly().FullName).Version; +#endif + public IHttpFactory HttpFactory = new SimpleFactory(); + + /// + /// Default constructor that registers default content handlers + /// + public RestClient() + { +#if WINDOWS_PHONE + UseSynchronizationContext = true; +#endif + ContentHandlers = new Dictionary(); + AcceptTypes = new List(); + DefaultParameters = new List(); + + // register default handlers + AddHandler("application/json", new JsonDeserializer()); + AddHandler("application/xml", new XmlDeserializer()); + AddHandler("text/json", new JsonDeserializer()); + AddHandler("text/x-json", new JsonDeserializer()); + AddHandler("text/javascript", new JsonDeserializer()); + AddHandler("text/xml", new XmlDeserializer()); + AddHandler("*", new XmlDeserializer()); + + FollowRedirects = true; + } + + /// + /// Sets the BaseUrl property for requests made by this client instance + /// + /// + public RestClient(string baseUrl) + : this() + { + BaseUrl = baseUrl; + } + + private IDictionary ContentHandlers { get; set; } + private IList AcceptTypes { get; set; } + + /// + /// Parameters included with every request made with this instance of RestClient + /// If specified in both client and request, the request wins + /// + public IList DefaultParameters { get; private set; } + + /// + /// Registers a content handler to process response content + /// + /// MIME content type of the response content + /// Deserializer to use to process content + public void AddHandler(string contentType, IDeserializer deserializer) + { + ContentHandlers[contentType] = deserializer; + if (contentType != "*") + { + AcceptTypes.Add(contentType); + // add Accept header based on registered deserializers + var accepts = string.Join(", ", AcceptTypes.ToArray()); + this.RemoveDefaultParameter("Accept"); + this.AddDefaultParameter("Accept", accepts, ParameterType.HttpHeader); + } + } + + /// + /// Remove a content handler for the specified MIME content type + /// + /// MIME content type to remove + public void RemoveHandler(string contentType) + { + ContentHandlers.Remove(contentType); + AcceptTypes.Remove(contentType); + this.RemoveDefaultParameter("Accept"); + } + + /// + /// Remove all content handlers + /// + public void ClearHandlers() + { + ContentHandlers.Clear(); + AcceptTypes.Clear(); + this.RemoveDefaultParameter("Accept"); + } + + /// + /// Retrieve the handler for the specified MIME content type + /// + /// MIME content type to retrieve + /// IDeserializer instance + IDeserializer GetHandler(string contentType) + { + if (string.IsNullOrEmpty(contentType) && ContentHandlers.ContainsKey("*")) + { + return ContentHandlers["*"]; + } + + var semicolonIndex = contentType.IndexOf(';'); + if (semicolonIndex > -1) contentType = contentType.Substring(0, semicolonIndex); + IDeserializer handler = null; + if (ContentHandlers.ContainsKey(contentType)) + { + handler = ContentHandlers[contentType]; + } + else if (ContentHandlers.ContainsKey("*")) + { + handler = ContentHandlers["*"]; + } + + return handler; + } + + /// + /// Maximum number of redirects to follow if FollowRedirects is true + /// + public int? MaxRedirects { get; set; } + +#if FRAMEWORK + /// + /// X509CertificateCollection to be sent with request + /// + public X509CertificateCollection ClientCertificates { get; set; } + + /// + /// Proxy to use for requests made by this client instance. + /// Passed on to underlying WebRequest if set. + /// + public IWebProxy Proxy { get; set; } +#endif + + /// + /// Default is true. Determine whether or not requests that result in + /// HTTP status codes of 3xx should follow returned redirect + /// + public bool FollowRedirects { get; set; } + + /// + /// The CookieContainer used for requests made by this client instance + /// +#if !PocketPC + public CookieContainer CookieContainer { get; set; } +#endif + + /// + /// UserAgent to use for requests made by this client instance + /// + public string UserAgent { get; set; } + + /// + /// Timeout in milliseconds to use for requests made by this client instance + /// + public int Timeout { get; set; } + + /// + /// The number of milliseconds before the writing or reading times out. + /// + public int ReadWriteTimeout { get; set; } + + /// + /// Whether to invoke async callbacks using the SynchronizationContext.Current captured when invoked + /// + public bool UseSynchronizationContext { get; set; } + + /// + /// Authenticator to use for requests made by this client instance + /// + public IAuthenticator Authenticator { get; set; } + + private string _baseUrl; + /// + /// Combined with Request.Resource to construct URL for request + /// Should include scheme and domain without trailing slash. + /// + /// + /// client.BaseUrl = "http://example.com"; + /// + public virtual string BaseUrl + { + get + { + return _baseUrl; + } + set + { + _baseUrl = value; + if (_baseUrl != null && _baseUrl.EndsWith("/")) + { + _baseUrl = _baseUrl.Substring(0, _baseUrl.Length - 1); + } + } + } + + public bool PreAuthenticate { get; set; } + + private void AuthenticateIfNeeded(RestClient client, IRestRequest request) + { + if (Authenticator != null) + { + Authenticator.Authenticate(client, request); + } + } + + /// + /// Assembles URL to call based on parameters, method and resource + /// + /// RestRequest to execute + /// Assembled System.Uri + public Uri BuildUri(IRestRequest request) + { + var assembled = request.Resource; + var urlParms = request.Parameters.Where(p => p.Type == ParameterType.UrlSegment); + foreach (var p in urlParms) + { + if (p.Value == null) + { + throw new ArgumentException(string.Format("Cannot build uri when url segment parameter '{0}' value is null.", p.Name), "request"); + } + + assembled = assembled.Replace("{" + p.Name + "}", p.Value.ToString().UrlEncode()); + } + + if (!string.IsNullOrEmpty(assembled) && assembled.StartsWith("/")) + { + assembled = assembled.Substring(1); + } + + if (!string.IsNullOrEmpty(BaseUrl)) + { + assembled = string.IsNullOrEmpty(assembled) ? this.BaseUrl : string.Format("{0}/{1}", this.BaseUrl, assembled); + } + + IEnumerable parameters; + + if (request.Method != Method.POST && request.Method != Method.PUT && request.Method != Method.PATCH) + { + // build and attach querystring if this is a get-style request + parameters = request.Parameters.Where(p => p.Type == ParameterType.GetOrPost || p.Type == ParameterType.QueryString).ToList(); + } + else + { + parameters = request.Parameters.Where(p => p.Type == ParameterType.QueryString).ToList(); + } + + if (!parameters.Any()) + { + return new Uri(assembled); + } + + // build and attach querystring + var data = EncodeParameters(parameters); + var separator = assembled.Contains("?") ? "&" : "?"; + assembled = string.Concat(assembled, separator, data); + + return new Uri(assembled); + } + + private static string EncodeParameters(IEnumerable parameters) + { + return string.Join("&", parameters.Select(x=>EncodeParameter(x)).ToArray()); + } + + private static string EncodeParameter(Parameter parameter) + { + if (parameter.Value == null) + { + return string.Concat(parameter.Name.UrlEncode(), "="); + } + + return string.Concat(parameter.Name.UrlEncode(), "=", parameter.Value.ToString().UrlEncode()); + } + + private void ConfigureHttp(IRestRequest request, IHttp http) + { + http.AlwaysMultipartFormData = request.AlwaysMultipartFormData; +#if !PocketPC + http.UseDefaultCredentials = request.UseDefaultCredentials; +#endif + http.ResponseWriter = request.ResponseWriter; +#if !PocketPC + http.CookieContainer = CookieContainer; +#endif + // move RestClient.DefaultParameters into Request.Parameters + foreach (var p in DefaultParameters) + { + if (request.Parameters.Any(p2 => p2.Name == p.Name && p2.Type == p.Type)) + { + continue; + } + + request.AddParameter(p); + } + + // Add Accept header based on registered deserializers if none has been set by the caller. +#if PocketPC + if (request.Parameters.All(p2 => p2.Name.ToLower() != "accept")) +#else + if (request.Parameters.All(p2 => p2.Name.ToLowerInvariant() != "accept")) +#endif + { + var accepts = string.Join(", ", AcceptTypes.ToArray()); + request.AddParameter("Accept", accepts, ParameterType.HttpHeader); + } + + http.Url = BuildUri(request); + http.PreAuthenticate = PreAuthenticate; + + var userAgent = UserAgent ?? http.UserAgent; + http.UserAgent = userAgent.HasValue() ? userAgent : "RestSharp/" + version; + + var timeout = request.Timeout > 0 ? request.Timeout : Timeout; + if (timeout > 0) + { + http.Timeout = timeout; + } + + var readWriteTimeout = request.ReadWriteTimeout > 0 ? request.ReadWriteTimeout : ReadWriteTimeout; + if (readWriteTimeout > 0) + { + http.ReadWriteTimeout = readWriteTimeout; + } + +#if !SILVERLIGHT + http.FollowRedirects = FollowRedirects; +#endif +#if FRAMEWORK + if (ClientCertificates != null) + { + http.ClientCertificates = ClientCertificates; + } + + http.MaxRedirects = MaxRedirects; +#endif + + if (request.Credentials != null) + { + http.Credentials = request.Credentials; + } + + var headers = from p in request.Parameters + where p.Type == ParameterType.HttpHeader + select new HttpHeader + { + Name = p.Name, + Value = p.Value.ToString() + }; + + foreach (var header in headers) + { + http.Headers.Add(header); + } + + var cookies = from p in request.Parameters + where p.Type == ParameterType.Cookie + select new HttpCookie + { + Name = p.Name, + Value = p.Value.ToString() + }; + + foreach (var cookie in cookies) + { + http.Cookies.Add(cookie); + } + + var @params = from p in request.Parameters + where p.Type == ParameterType.GetOrPost + && p.Value != null + select new HttpParameter + { + Name = p.Name, + Value = p.Value.ToString() + }; + + foreach (var parameter in @params) + { + http.Parameters.Add(parameter); + } + + foreach (var file in request.Files) + { + http.Files.Add(new HttpFile { Name = file.Name, ContentType = file.ContentType, Writer = file.Writer, FileName = file.FileName, ContentLength = file.ContentLength }); + } + + var body = (from p in request.Parameters + where p.Type == ParameterType.RequestBody + select p).FirstOrDefault(); + + if (body != null) + { + object val = body.Value; + if (val is byte[]) + http.RequestBodyBytes = (byte[])val; + else + http.RequestBody = body.Value.ToString(); + http.RequestContentType = body.Name; + } +#if FRAMEWORK + ConfigureProxy(http); +#endif + } + +#if FRAMEWORK + private void ConfigureProxy(IHttp http) + { + if (Proxy != null) + { + http.Proxy = Proxy; + } + } +#endif + + private RestResponse ConvertToRestResponse(IRestRequest request, HttpResponse httpResponse) + { + var restResponse = new RestResponse(); + restResponse.Content = httpResponse.Content; + restResponse.ContentEncoding = httpResponse.ContentEncoding; + restResponse.ContentLength = httpResponse.ContentLength; + restResponse.ContentType = httpResponse.ContentType; + restResponse.ErrorException = httpResponse.ErrorException; + restResponse.ErrorMessage = httpResponse.ErrorMessage; + restResponse.RawBytes = httpResponse.RawBytes; + restResponse.ResponseStatus = httpResponse.ResponseStatus; + restResponse.ResponseUri = httpResponse.ResponseUri; + restResponse.Server = httpResponse.Server; + restResponse.StatusCode = httpResponse.StatusCode; + restResponse.StatusDescription = httpResponse.StatusDescription; + restResponse.Request = request; + + foreach (var header in httpResponse.Headers) + { + restResponse.Headers.Add(new Parameter { Name = header.Name, Value = header.Value, Type = ParameterType.HttpHeader }); + } + + foreach (var cookie in httpResponse.Cookies) + { + restResponse.Cookies.Add(new RestResponseCookie + { + Comment = cookie.Comment, + CommentUri = cookie.CommentUri, + Discard = cookie.Discard, + Domain = cookie.Domain, + Expired = cookie.Expired, + Expires = cookie.Expires, + HttpOnly = cookie.HttpOnly, + Name = cookie.Name, + Path = cookie.Path, + Port = cookie.Port, + Secure = cookie.Secure, + TimeStamp = cookie.TimeStamp, + Value = cookie.Value, + Version = cookie.Version + }); + } + + return restResponse; + } + + private IRestResponse Deserialize(IRestRequest request, IRestResponse raw) + { + request.OnBeforeDeserialization(raw); + + IRestResponse response = new RestResponse(); + try + { + response = raw.toAsyncResponse(); + response.Request = request; + + // Only attempt to deserialize if the request has not errored due + // to a transport or framework exception. HTTP errors should attempt to + // be deserialized + if (response.ErrorException == null) + { + IDeserializer handler = GetHandler(raw.ContentType); + // Only continue if there is a handler defined else there is no way to deserialize the data. + // This can happen when a request returns for example a 404 page instead of the requested JSON/XML resource + if (handler != null) + { + handler.RootElement = request.RootElement; + handler.DateFormat = request.DateFormat; + handler.Namespace = request.XmlNamespace; + + response.Data = handler.Deserialize(raw); + } + } + } + catch (Exception ex) + { + response.ResponseStatus = ResponseStatus.Error; + response.ErrorMessage = ex.Message; + response.ErrorException = ex; + } + + return response; + } + } +} diff --git a/Backup/RestSharp.Silverlight/RestClientExtensions.cs b/Backup/RestSharp.Silverlight/RestClientExtensions.cs new file mode 100644 index 000000000..c0c29efde --- /dev/null +++ b/Backup/RestSharp.Silverlight/RestClientExtensions.cs @@ -0,0 +1,333 @@ +using System; +using System.Linq; +#if NET4 +using System.Threading.Tasks; +#endif + +namespace RestSharp +{ + public static partial class RestClientExtensions + { + /// + /// Executes the request and callback asynchronously, authenticating if needed + /// + /// The IRestClient this method extends + /// Request to be executed + /// Callback function to be executed upon completion + public static RestRequestAsyncHandle ExecuteAsync(this IRestClient client, IRestRequest request, Action callback) + { + return client.ExecuteAsync(request, (response, handle) => callback(response)); + } + + /// + /// Executes the request and callback asynchronously, authenticating if needed + /// + /// The IRestClient this method extends + /// Target deserialization type + /// Request to be executed + /// Callback function to be executed upon completion providing access to the async handle + public static RestRequestAsyncHandle ExecuteAsync(this IRestClient client, IRestRequest request, Action> callback) where T : new() + { + return client.ExecuteAsync(request, (response, asyncHandle) => callback(response)); + } + + public static RestRequestAsyncHandle GetAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() + { + request.Method = Method.GET; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle PostAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() + { + request.Method = Method.POST; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle PutAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() + { + request.Method = Method.PUT; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle HeadAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() + { + request.Method = Method.HEAD; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle OptionsAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() + { + request.Method = Method.OPTIONS; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle PatchAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() + { + request.Method = Method.PATCH; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle DeleteAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() + { + request.Method = Method.DELETE; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle GetAsync(this IRestClient client, IRestRequest request, Action callback) + { + request.Method = Method.GET; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle PostAsync(this IRestClient client, IRestRequest request, Action callback) + { + request.Method = Method.POST; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle PutAsync(this IRestClient client, IRestRequest request, Action callback) + { + request.Method = Method.PUT; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle HeadAsync(this IRestClient client, IRestRequest request, Action callback) + { + request.Method = Method.HEAD; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle OptionsAsync(this IRestClient client, IRestRequest request, Action callback) + { + request.Method = Method.OPTIONS; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle PatchAsync(this IRestClient client, IRestRequest request, Action callback) + { + request.Method = Method.PATCH; + return client.ExecuteAsync(request, callback); + } + + public static RestRequestAsyncHandle DeleteAsync(this IRestClient client, IRestRequest request, Action callback) + { + request.Method = Method.DELETE; + return client.ExecuteAsync(request, callback); + } + +#if NET4 + public static Task GetTaskAsync(this IRestClient client, IRestRequest request) where T : new() + { + return client.ExecuteGetTaskAsync(request).ContinueWith(x => x.Result.Data); + } + + public static Task PostTaskAsync(this IRestClient client, IRestRequest request) where T : new() + { + return client.ExecutePostTaskAsync(request).ContinueWith(x => x.Result.Data); + } + + public static Task PutTaskAsync(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.PUT; + return client.ExecuteTaskAsync(request).ContinueWith(x => x.Result.Data); + } + + public static Task HeadTaskAsync(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.HEAD; + return client.ExecuteTaskAsync(request).ContinueWith(x => x.Result.Data); + } + + public static Task OptionsTaskAsync(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.OPTIONS; + return client.ExecuteTaskAsync(request).ContinueWith(x => x.Result.Data); + } + + public static Task PatchTaskAsync(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.PATCH; + return client.ExecuteTaskAsync(request).ContinueWith(x => x.Result.Data); + } + + public static Task DeleteTaskAsync(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.DELETE; + return client.ExecuteTaskAsync(request).ContinueWith(x => x.Result.Data); + } +#endif + +#if FRAMEWORK + public static IRestResponse Get(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.GET; + return client.Execute(request); + } + + public static IRestResponse Post(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.POST; + return client.Execute(request); + } + + public static IRestResponse Put(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.PUT; + return client.Execute(request); + } + + public static IRestResponse Head(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.HEAD; + return client.Execute(request); + } + + public static IRestResponse Options(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.OPTIONS; + return client.Execute(request); + } + + public static IRestResponse Patch(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.PATCH; + return client.Execute(request); + } + + public static IRestResponse Delete(this IRestClient client, IRestRequest request) where T : new() + { + request.Method = Method.DELETE; + return client.Execute(request); + } + + public static IRestResponse Get(this IRestClient client, IRestRequest request) + { + request.Method = Method.GET; + return client.Execute(request); + } + + public static IRestResponse Post(this IRestClient client, IRestRequest request) + { + request.Method = Method.POST; + return client.Execute(request); + } + + public static IRestResponse Put(this IRestClient client, IRestRequest request) + { + request.Method = Method.PUT; + return client.Execute(request); + } + + public static IRestResponse Head(this IRestClient client, IRestRequest request) + { + request.Method = Method.HEAD; + return client.Execute(request); + } + + public static IRestResponse Options(this IRestClient client, IRestRequest request) + { + request.Method = Method.OPTIONS; + return client.Execute(request); + } + + public static IRestResponse Patch(this IRestClient client, IRestRequest request) + { + request.Method = Method.PATCH; + return client.Execute(request); + } + + public static IRestResponse Delete(this IRestClient client, IRestRequest request) + { + request.Method = Method.DELETE; + return client.Execute(request); + } +#endif + + /// + /// Add a parameter to use on every request made with this client instance + /// + /// The IRestClient instance + /// Parameter to add + /// + public static void AddDefaultParameter(this IRestClient restClient, Parameter p) + { + if (p.Type == ParameterType.RequestBody) + { + throw new NotSupportedException( + "Cannot set request body from default headers. Use Request.AddBody() instead."); + } + + restClient.DefaultParameters.Add(p); + } + + /// + /// Removes a parameter from the default parameters that are used on every request made with this client instance + /// + /// The IRestClient instance + /// The name of the parameter that needs to be removed + /// + public static void RemoveDefaultParameter(this IRestClient restClient, string name) + { + var parameter = restClient.DefaultParameters.SingleOrDefault(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + if (parameter != null) + { + restClient.DefaultParameters.Remove(parameter); + } + } + + /// + /// Adds a HTTP parameter (QueryString for GET, DELETE, OPTIONS and HEAD; Encoded form for POST and PUT) + /// Used on every request made by this client instance + /// + /// The IRestClient instance + /// Name of the parameter + /// Value of the parameter + /// This request + public static void AddDefaultParameter(this IRestClient restClient, string name, object value) + { + restClient.AddDefaultParameter(new Parameter { Name = name, Value = value, Type = ParameterType.GetOrPost }); + } + + /// + /// Adds a parameter to the request. There are four types of parameters: + /// - GetOrPost: Either a QueryString value or encoded form value based on method + /// - HttpHeader: Adds the name/value pair to the HTTP request's Headers collection + /// - UrlSegment: Inserted into URL if there is a matching url token e.g. {AccountId} + /// - RequestBody: Used by AddBody() (not recommended to use directly) + /// + /// The IRestClient instance + /// Name of the parameter + /// Value of the parameter + /// The type of parameter to add + /// This request + public static void AddDefaultParameter(this IRestClient restClient, string name, object value, ParameterType type) + { + restClient.AddDefaultParameter(new Parameter { Name = name, Value = value, Type = type }); + } + + /// + /// Shortcut to AddDefaultParameter(name, value, HttpHeader) overload + /// + /// The IRestClient instance + /// Name of the header to add + /// Value of the header to add + /// + public static void AddDefaultHeader(this IRestClient restClient, string name, string value) + { + restClient.AddDefaultParameter(name, value, ParameterType.HttpHeader); + } + + /// + /// Shortcut to AddDefaultParameter(name, value, UrlSegment) overload + /// + /// The IRestClient instance + /// Name of the segment to add + /// Value of the segment to add + /// + public static void AddDefaultUrlSegment(this IRestClient restClient, string name, string value) + { + restClient.AddDefaultParameter(name, value, ParameterType.UrlSegment); + } + + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/RestRequest.cs b/Backup/RestSharp.Silverlight/RestRequest.cs new file mode 100644 index 000000000..2cbf2ee8b --- /dev/null +++ b/Backup/RestSharp.Silverlight/RestRequest.cs @@ -0,0 +1,501 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using RestSharp.Extensions; +using RestSharp.Serializers; + +namespace RestSharp +{ + /// + /// Container for data used to make requests + /// + public class RestRequest : IRestRequest + { + /// + /// Always send a multipart/form-data request - even when no Files are present. + /// + public bool AlwaysMultipartFormData { get; set; } + + /// + /// Serializer to use when writing JSON request bodies. Used if RequestFormat is Json. + /// By default the included JsonSerializer is used (currently using JSON.NET default serialization). + /// + public ISerializer JsonSerializer { get; set; } + + /// + /// Serializer to use when writing XML request bodies. Used if RequestFormat is Xml. + /// By default the included XmlSerializer is used. + /// + public ISerializer XmlSerializer { get; set; } + + /// + /// Set this to write response to Stream rather than reading into memory. + /// + public Action ResponseWriter { get; set; } + + /// + /// Determine whether or not the "default credentials" (e.g. the user account under which the current process is running) + /// will be sent along to the server. The default is false. + /// + public bool UseDefaultCredentials { get; set; } + + /// + /// Default constructor + /// + public RestRequest() + { + Parameters = new List(); + Files = new List(); + XmlSerializer = new XmlSerializer(); + JsonSerializer = new JsonSerializer(); + + OnBeforeDeserialization = r => { }; + } + + /// + /// Sets Method property to value of method + /// + /// Method to use for this request + public RestRequest(Method method) + : this() + { + Method = method; + } + + /// + /// Sets Resource property + /// + /// Resource to use for this request + public RestRequest(string resource) + : this(resource, Method.GET) + { + } + + /// + /// Sets Resource and Method properties + /// + /// Resource to use for this request + /// Method to use for this request + public RestRequest(string resource, Method method) + : this() + { + Resource = resource; + Method = method; + } + + + /// + /// Sets Resource property + /// + /// Resource to use for this request + public RestRequest(Uri resource) + : this(resource, Method.GET) + { + + } + + /// + /// Sets Resource and Method properties + /// + /// Resource to use for this request + /// Method to use for this request + public RestRequest(Uri resource, Method method) + : this(resource.IsAbsoluteUri ? resource.AbsolutePath + resource.Query : resource.OriginalString, method) + { + //resource.PathAndQuery not supported by Silverlight :( + } + + /// + /// Adds a file to the Files collection to be included with a POST or PUT request + /// (other methods do not support file uploads). + /// + /// The parameter name to use in the request + /// Full path to file to upload + /// This request + public IRestRequest AddFile (string name, string path) + { + FileInfo f = new FileInfo (path); + long fileLength = f.Length; + return AddFile(new FileParameter + { + Name = name, + FileName = Path.GetFileName(path), + ContentLength = fileLength, + Writer = s => + { + using(var file = new StreamReader(path)) + { + file.BaseStream.CopyTo(s); + } + } + }); + } + + /// + /// Adds the bytes to the Files collection with the specified file name + /// + /// The parameter name to use in the request + /// The file data + /// The file name to use for the uploaded file + /// This request + public IRestRequest AddFile (string name, byte[] bytes, string fileName) + { + return AddFile(FileParameter.Create(name, bytes, fileName)); + } + + /// + /// Adds the bytes to the Files collection with the specified file name and content type + /// + /// The parameter name to use in the request + /// The file data + /// The file name to use for the uploaded file + /// The MIME type of the file to upload + /// This request + public IRestRequest AddFile (string name, byte[] bytes, string fileName, string contentType) + { + return AddFile(FileParameter.Create(name, bytes, fileName, contentType)); + } + + /// + /// Adds the bytes to the Files collection with the specified file name and content type + /// + /// The parameter name to use in the request + /// A function that writes directly to the stream. Should NOT close the stream. + /// The file name to use for the uploaded file + /// This request + public IRestRequest AddFile (string name, Action writer, string fileName) + { + return AddFile(name, writer, fileName, null); + } + + /// + /// Adds the bytes to the Files collection with the specified file name and content type + /// + /// The parameter name to use in the request + /// A function that writes directly to the stream. Should NOT close the stream. + /// The file name to use for the uploaded file + /// The MIME type of the file to upload + /// This request + public IRestRequest AddFile (string name, Action writer, string fileName, string contentType) + { + return AddFile(new FileParameter { Name = name, Writer = writer, FileName = fileName, ContentType = contentType }); + } + + private IRestRequest AddFile (FileParameter file) + { + Files.Add(file); + return this; + } + + /// + /// Serializes obj to format specified by RequestFormat, but passes xmlNamespace if using the default XmlSerializer + /// + /// The object to serialize + /// The XML namespace to use when serializing + /// This request + public IRestRequest AddBody (object obj, string xmlNamespace) + { + string serialized; + string contentType; + + switch (RequestFormat) + { + case DataFormat.Json: + serialized = JsonSerializer.Serialize(obj); + contentType = JsonSerializer.ContentType; + break; + + case DataFormat.Xml: + XmlSerializer.Namespace = xmlNamespace; + serialized = XmlSerializer.Serialize(obj); + contentType = XmlSerializer.ContentType; + break; + + default: + serialized = ""; + contentType = ""; + break; + } + + // passing the content type as the parameter name because there can only be + // one parameter with ParameterType.RequestBody so name isn't used otherwise + // it's a hack, but it works :) + return AddParameter(contentType, serialized, ParameterType.RequestBody); + } + + /// + /// Serializes obj to data format specified by RequestFormat and adds it to the request body. + /// + /// The object to serialize + /// This request + public IRestRequest AddBody (object obj) + { + return AddBody(obj, ""); + } + + /// + /// Calls AddParameter() for all public, readable properties specified in the white list + /// + /// + /// request.AddObject(product, "ProductId", "Price", ...); + /// + /// The object with properties to add as parameters + /// The names of the properties to include + /// This request + public IRestRequest AddObject (object obj, params string[] whitelist) + { + // automatically create parameters from object props + var type = obj.GetType(); + var props = type.GetProperties(); + + foreach (var prop in props) + { + bool isAllowed = whitelist.Length == 0 || (whitelist.Length > 0 && whitelist.Contains(prop.Name)); + + if (isAllowed) + { + var propType = prop.PropertyType; + var val = prop.GetValue(obj, null); + + if (val != null) + { + if (propType.IsArray) + { + var elementType = propType.GetElementType(); + + if (((Array)val).Length > 0 && (elementType.IsPrimitive || elementType.IsValueType || elementType == typeof(string))) { + // convert the array to an array of strings + var values = (from object item in ((Array)val) select item.ToString()).ToArray(); + val = string.Join(",", values); + } else { + // try to cast it + val = string.Join(",", (string[])val); + } + } + + AddParameter(prop.Name, val); + } + } + } + + return this; + } + + /// + /// Calls AddParameter() for all public, readable properties of obj + /// + /// The object with properties to add as parameters + /// This request + public IRestRequest AddObject (object obj) + { + AddObject(obj, new string[] { }); + return this; + } + + /// + /// Add the parameter to the request + /// + /// Parameter to add + /// + public IRestRequest AddParameter (Parameter p) + { + Parameters.Add(p); + return this; + } + + /// + /// Adds a HTTP parameter to the request (QueryString for GET, DELETE, OPTIONS and HEAD; Encoded form for POST and PUT) + /// + /// Name of the parameter + /// Value of the parameter + /// This request + public IRestRequest AddParameter (string name, object value) + { + return AddParameter(new Parameter { Name = name, Value = value, Type = ParameterType.GetOrPost }); + } + + /// + /// Adds a parameter to the request. There are four types of parameters: + /// - GetOrPost: Either a QueryString value or encoded form value based on method + /// - HttpHeader: Adds the name/value pair to the HTTP request's Headers collection + /// - UrlSegment: Inserted into URL if there is a matching url token e.g. {AccountId} + /// - RequestBody: Used by AddBody() (not recommended to use directly) + /// + /// Name of the parameter + /// Value of the parameter + /// The type of parameter to add + /// This request + public IRestRequest AddParameter (string name, object value, ParameterType type) + { + return AddParameter(new Parameter { Name = name, Value = value, Type = type }); + } + + /// + /// Shortcut to AddParameter(name, value, HttpHeader) overload + /// + /// Name of the header to add + /// Value of the header to add + /// + public IRestRequest AddHeader (string name, string value) + { + return AddParameter(name, value, ParameterType.HttpHeader); + } + + /// + /// Shortcut to AddParameter(name, value, Cookie) overload + /// + /// Name of the cookie to add + /// Value of the cookie to add + /// + public IRestRequest AddCookie (string name, string value) + { + return AddParameter(name, value, ParameterType.Cookie); + } + + /// + /// Shortcut to AddParameter(name, value, UrlSegment) overload + /// + /// Name of the segment to add + /// Value of the segment to add + /// + public IRestRequest AddUrlSegment (string name, string value) + { + return AddParameter(name, value, ParameterType.UrlSegment); + } + + /// + /// Container of all HTTP parameters to be passed with the request. + /// See AddParameter() for explanation of the types of parameters that can be passed + /// + public List Parameters { get; private set; } + + /// + /// Container of all the files to be uploaded with the request. + /// + public List Files { get; private set; } + + private Method _method = Method.GET; + /// + /// Determines what HTTP method to use for this request. Supported methods: GET, POST, PUT, DELETE, HEAD, OPTIONS + /// Default is GET + /// + public Method Method + { + get { return _method; } + set { _method = value; } + } + + /// + /// The Resource URL to make the request against. + /// Tokens are substituted with UrlSegment parameters and match by name. + /// Should not include the scheme or domain. Do not include leading slash. + /// Combined with RestClient.BaseUrl to assemble final URL: + /// {BaseUrl}/{Resource} (BaseUrl is scheme + domain, e.g. http://example.com) + /// + /// + /// // example for url token replacement + /// request.Resource = "Products/{ProductId}"; + /// request.AddParameter("ProductId", 123, ParameterType.UrlSegment); + /// + public string Resource { get; set; } + + private DataFormat _requestFormat = DataFormat.Xml; + /// + /// Serializer to use when writing XML request bodies. Used if RequestFormat is Xml. + /// By default XmlSerializer is used. + /// + public DataFormat RequestFormat + { + get + { + return _requestFormat; + } + set + { + _requestFormat = value; + } + } + + /// + /// Used by the default deserializers to determine where to start deserializing from. + /// Can be used to skip container or root elements that do not have corresponding deserialzation targets. + /// + public string RootElement { get; set; } + + /// + /// A function to run prior to deserializing starting (e.g. change settings if error encountered) + /// + public Action OnBeforeDeserialization { get; set; } + + /// + /// Used by the default deserializers to explicitly set which date format string to use when parsing dates. + /// + public string DateFormat { get; set; } + + /// + /// Used by XmlDeserializer. If not specified, XmlDeserializer will flatten response by removing namespaces from element names. + /// + public string XmlNamespace { get; set; } + + /// + /// In general you would not need to set this directly. Used by the NtlmAuthenticator. + /// + public ICredentials Credentials { get; set; } + + /// + /// Gets or sets a user-defined state object that contains information about a request and which can be later + /// retrieved when the request completes. + /// + public object UserState { get; set; } + + /// + /// Timeout in milliseconds to be used for the request. This timeout value overrides a timeout set on the RestClient. + /// + public int Timeout { get; set; } + + /// + /// The number of milliseconds before the writing or reading times out. This timeout value overrides a timeout set on the RestClient. + /// + public int ReadWriteTimeout { get; set; } + + private int _attempts; + + /// + /// Internal Method so that RestClient can increase the number of attempts + /// + public void IncreaseNumAttempts() + { + _attempts++; + } + + /// + /// How many attempts were made to send this Request? + /// + /// + /// This Number is incremented each time the RestClient sends the request. + /// Useful when using Asynchronous Execution with Callbacks + /// + public int Attempts + { + get { return _attempts; } + } + } +} diff --git a/Backup/RestSharp.Silverlight/RestRequestAsyncHandle.cs b/Backup/RestSharp.Silverlight/RestRequestAsyncHandle.cs new file mode 100644 index 000000000..7e1c5650b --- /dev/null +++ b/Backup/RestSharp.Silverlight/RestRequestAsyncHandle.cs @@ -0,0 +1,25 @@ +using System; +using System.Net; +namespace RestSharp +{ + public class RestRequestAsyncHandle + { + public HttpWebRequest WebRequest; + + public RestRequestAsyncHandle() + { + } + + public RestRequestAsyncHandle(HttpWebRequest webRequest) + { + WebRequest = webRequest; + } + + public void Abort() + { + if (WebRequest != null) + WebRequest.Abort(); + } + } +} + diff --git a/Backup/RestSharp.Silverlight/RestResponse.cs b/Backup/RestSharp.Silverlight/RestResponse.cs new file mode 100644 index 000000000..80bf41761 --- /dev/null +++ b/Backup/RestSharp.Silverlight/RestResponse.cs @@ -0,0 +1,174 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections.Generic; +using System.Net; +using RestSharp.Extensions; + +namespace RestSharp +{ + /// + /// Base class for common properties shared by RestResponse and RestResponse[[T]] + /// + public abstract class RestResponseBase + { + private string _content; + + /// + /// Default constructor + /// + public RestResponseBase() + { + Headers = new List(); + Cookies = new List(); + } + /// + /// The RestRequest that was made to get this RestResponse + /// + /// + /// Mainly for debugging if ResponseStatus is not OK + /// + public IRestRequest Request { get; set; } + /// + /// MIME content type of response + /// + public string ContentType { get; set; } + /// + /// Length in bytes of the response content + /// + public long ContentLength { get; set; } + /// + /// Encoding of the response content + /// + public string ContentEncoding { get; set; } + /// + /// String representation of response content + /// + public string Content + { + get + { + if (_content == null) + { + _content = RawBytes.AsString(); + } + return _content; + } + set + { + _content = value; + } + } + /// + /// HTTP response status code + /// + public HttpStatusCode StatusCode { get; set; } + /// + /// Description of HTTP status returned + /// + public string StatusDescription { get; set; } + /// + /// Response content + /// + public byte[] RawBytes { get; set; } + /// + /// The URL that actually responded to the content (different from request if redirected) + /// + public Uri ResponseUri { get; set; } + /// + /// HttpWebResponse.Server + /// + public string Server { get; set; } + /// + /// Cookies returned by server with the response + /// + public IList Cookies { get; protected internal set; } + /// + /// Headers returned by server with the response + /// + public IList Headers { get; protected internal set; } + + private ResponseStatus _responseStatus = ResponseStatus.None; + /// + /// Status of the request. Will return Error for transport errors. + /// HTTP errors will still return ResponseStatus.Completed, check StatusCode instead + /// + public ResponseStatus ResponseStatus + { + get + { + return _responseStatus; + } + set + { + _responseStatus = value; + } + } + + /// + /// Transport or other non-HTTP error generated while attempting request + /// + public string ErrorMessage { get; set; } + + /// + /// The exception thrown during the request, if any + /// + public Exception ErrorException { get; set; } + } + + /// + /// Container for data sent back from API including deserialized data + /// + /// Type of data to deserialize to + public class RestResponse : RestResponseBase, IRestResponse + { + /// + /// Deserialized entity data + /// + public T Data { get; set; } + + public static explicit operator RestResponse(RestResponse response) + { + return new RestResponse + { + ContentEncoding = response.ContentEncoding, + ContentLength = response.ContentLength, + ContentType = response.ContentType, + Cookies = response.Cookies, + ErrorMessage = response.ErrorMessage, + ErrorException = response.ErrorException, + Headers = response.Headers, + RawBytes = response.RawBytes, + ResponseStatus = response.ResponseStatus, + ResponseUri = response.ResponseUri, + Server = response.Server, + StatusCode = response.StatusCode, + StatusDescription = response.StatusDescription, + Request = response.Request + }; + } + + } + + /// + /// Container for data sent back from API + /// + public class RestResponse : RestResponseBase, IRestResponse + { + + } +} diff --git a/Backup/RestSharp.Silverlight/RestResponseCookie.cs b/Backup/RestSharp.Silverlight/RestResponseCookie.cs new file mode 100644 index 000000000..5d42c2b44 --- /dev/null +++ b/Backup/RestSharp.Silverlight/RestResponseCookie.cs @@ -0,0 +1,64 @@ +using System; +namespace RestSharp +{ + public class RestResponseCookie + { + /// + /// Comment of the cookie + /// + public string Comment { get; set; } + /// + /// Comment of the cookie + /// + public Uri CommentUri { get; set; } + /// + /// Indicates whether the cookie should be discarded at the end of the session + /// + public bool Discard { get; set; } + /// + /// Domain of the cookie + /// + public string Domain { get; set; } + /// + /// Indicates whether the cookie is expired + /// + public bool Expired { get; set; } + /// + /// Date and time that the cookie expires + /// + public DateTime Expires { get; set; } + /// + /// Indicates that this cookie should only be accessed by the server + /// + public bool HttpOnly { get; set; } + /// + /// Name of the cookie + /// + public string Name { get; set; } + /// + /// Path of the cookie + /// + public string Path { get; set; } + /// + /// Port of the cookie + /// + public string Port { get; set; } + /// + /// Indicates that the cookie should only be sent over secure channels + /// + public bool Secure { get; set; } + /// + /// Date and time the cookie was created + /// + public DateTime TimeStamp { get; set; } + /// + /// Value of the cookie + /// + public string Value { get; set; } + /// + /// Version of the cookie + /// + public int Version { get; set; } + } +} + diff --git a/Backup/RestSharp.Silverlight/RestSharp.Silverlight.csproj b/Backup/RestSharp.Silverlight/RestSharp.Silverlight.csproj new file mode 100644 index 000000000..0d272963f --- /dev/null +++ b/Backup/RestSharp.Silverlight/RestSharp.Silverlight.csproj @@ -0,0 +1,288 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {11F84600-0978-48B9-A28F-63B3781E54B3} + {A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + RestSharp.Silverlight + RestSharp.Silverlight + Silverlight + v4.0 + $(TargetFrameworkVersion) + false + true + true + ..\ + true + + + + v3.5 + + + true + full + false + Bin\Debug + DEBUG;TRACE;SILVERLIGHT + true + true + prompt + 4 + Bin\Debug\RestSharp.Silverlight.xml + + + pdbonly + true + Bin\Release + TRACE;SILVERLIGHT + true + true + prompt + 4 + Bin\Release\RestSharp.Silverlight.xml + 1591,1573,1658,1584,1574,1572 + true + + + + + + + + + + + + + + + + + Authenticators\HttpBasicAuthenticator.cs + + + Authenticators\IAuthenticator.cs + + + Authenticators\NtlmAuthenticator.cs + + + Authenticators\OAuth1Authenticator.cs + + + Authenticators\OAuth2Authenticator.cs + + + Authenticators\OAuth\Extensions\CollectionExtensions.cs + + + Authenticators\OAuth\Extensions\OAuthExtensions.cs + + + Authenticators\OAuth\Extensions\StringExtensions.cs + + + Authenticators\OAuth\Extensions\TimeExtensions.cs + + + Authenticators\OAuth\HttpPostParameter.cs + + + Authenticators\OAuth\HttpPostParameterType.cs + + + Authenticators\OAuth\OAuthParameterHandling.cs + + + Authenticators\OAuth\OAuthSignatureMethod.cs + + + Authenticators\OAuth\OAuthSignatureTreatment.cs + + + Authenticators\OAuth\OAuthTools.cs + + + Authenticators\OAuth\OAuthType.cs + + + Authenticators\OAuth\OAuthWebQueryInfo.cs + + + Authenticators\OAuth\OAuthWorkflow.cs + + + Authenticators\OAuth\WebPair.cs + + + Authenticators\OAuth\WebPairCollection.cs + + + Authenticators\OAuth\WebParameter.cs + + + Authenticators\OAuth\WebParameterCollection.cs + + + Authenticators\SimpleAuthenticator.cs + + + Deserializers\DeserializeAsAttribute.cs + + + Deserializers\DotNetXmlDeserializer.cs + + + Deserializers\IDeserializer.cs + + + Deserializers\JsonDeserializer.cs + + + Deserializers\XmlAttributeDeserializer.cs + + + Deserializers\XmlDeserializer.cs + + + Enum.cs + + + Extensions\MiscExtensions.cs + + + Extensions\ReflectionExtensions.cs + + + Extensions\ResponseExtensions.cs + + + Extensions\StringExtensions.cs + + + Extensions\XmlExtensions.cs + + + FileParameter.cs + + + Http.Async.cs + + + Http.cs + + + HttpCookie.cs + + + HttpFile.cs + + + HttpHeader.cs + + + HttpParameter.cs + + + HttpResponse.cs + + + IHttp.cs + + + IHttpFactory.cs + + + IHttpResponse.cs + + + IRestClient.cs + + + IRestRequest.cs + + + IRestResponse.cs + + + Parameter.cs + + + RestClient.Async.cs + + + RestClient.cs + + + RestClientExtensions.cs + + + RestRequest.cs + + + RestResponse.cs + + + Serializers\DotNetXmlSerializer.cs + + + Serializers\ISerializer.cs + + + Serializers\JsonSerializer.cs + + + Serializers\SerializeAsAttribute.cs + + + Serializers\XmlSerializer.cs + + + SharedAssemblyInfo.cs + + + SimpleJson.cs + + + Validation\Require.cs + + + Validation\Validate.cs + + + RestResponseCookie.cs + + + RestRequestAsyncHandle.cs + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Serializers/DotNetXmlSerializer.cs b/Backup/RestSharp.Silverlight/Serializers/DotNetXmlSerializer.cs new file mode 100644 index 000000000..8b3d2bed2 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Serializers/DotNetXmlSerializer.cs @@ -0,0 +1,89 @@ +using System.IO; +using System.Text; +using System.Xml.Serialization; + +namespace RestSharp.Serializers +{ + /// + /// Wrapper for System.Xml.Serialization.XmlSerializer. + /// + public class DotNetXmlSerializer : ISerializer + { + /// + /// Default constructor, does not specify namespace + /// + public DotNetXmlSerializer() + { + ContentType = "application/xml"; + Encoding = Encoding.UTF8; + } + + /// + /// Specify the namespaced to be used when serializing + /// + /// XML namespace + public DotNetXmlSerializer(string @namespace) : this() + { + Namespace = @namespace; + } + + /// + /// Serialize the object as XML + /// + /// Object to serialize + /// XML as string + public string Serialize(object obj) + { + var ns = new XmlSerializerNamespaces(); + ns.Add(string.Empty, Namespace); + var serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType()); + var writer = new EncodingStringWriter(Encoding); + serializer.Serialize(writer, obj, ns); + + return writer.ToString(); + } + + /// + /// Name of the root element to use when serializing + /// + public string RootElement { get; set; } + + /// + /// XML namespace to use when serializing + /// + public string Namespace { get; set; } + + /// + /// Format string to use when serializing dates + /// + public string DateFormat { get; set; } + + /// + /// Content type for serialized content + /// + public string ContentType { get; set; } + + /// + /// Encoding for serialized content + /// + public Encoding Encoding { get; set; } + + /// + /// Need to subclass StringWriter in order to override Encoding + /// + private class EncodingStringWriter : StringWriter + { + private readonly Encoding encoding; + + public EncodingStringWriter(Encoding encoding) + { + this.encoding = encoding; + } + + public override Encoding Encoding + { + get { return encoding; } + } + } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Serializers/ISerializer.cs b/Backup/RestSharp.Silverlight/Serializers/ISerializer.cs new file mode 100644 index 000000000..0ca2a4dc3 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Serializers/ISerializer.cs @@ -0,0 +1,27 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace RestSharp.Serializers +{ + public interface ISerializer + { + string Serialize(object obj); + string RootElement { get; set; } + string Namespace { get; set; } + string DateFormat { get; set; } + string ContentType { get; set; } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Serializers/JsonSerializer.cs b/Backup/RestSharp.Silverlight/Serializers/JsonSerializer.cs new file mode 100644 index 000000000..191e7c4ca --- /dev/null +++ b/Backup/RestSharp.Silverlight/Serializers/JsonSerializer.cs @@ -0,0 +1,46 @@ +using System.IO; + +namespace RestSharp.Serializers +{ + /// + /// Default JSON serializer for request bodies + /// Doesn't currently use the SerializeAs attribute, defers to Newtonsoft's attributes + /// + public class JsonSerializer : ISerializer + { + /// + /// Default serializer + /// + public JsonSerializer() + { + ContentType = "application/json"; + } + + /// + /// Serialize the object as JSON + /// + /// Object to serialize + /// JSON as String + public string Serialize(object obj) + { + return SimpleJson.SerializeObject(obj); + } + + /// + /// Unused for JSON Serialization + /// + public string DateFormat { get; set; } + /// + /// Unused for JSON Serialization + /// + public string RootElement { get; set; } + /// + /// Unused for JSON Serialization + /// + public string Namespace { get; set; } + /// + /// Content type for serialized content + /// + public string ContentType { get; set; } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Serializers/SerializeAsAttribute.cs b/Backup/RestSharp.Silverlight/Serializers/SerializeAsAttribute.cs new file mode 100644 index 000000000..98a89a74d --- /dev/null +++ b/Backup/RestSharp.Silverlight/Serializers/SerializeAsAttribute.cs @@ -0,0 +1,92 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using RestSharp.Extensions; +using System.Globalization; + +namespace RestSharp.Serializers +{ + /// + /// Allows control how class and property names and values are serialized by XmlSerializer + /// Currently not supported with the JsonSerializer + /// When specified at the property level the class-level specification is overridden + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] + public sealed class SerializeAsAttribute : Attribute + { + public SerializeAsAttribute() { + NameStyle = NameStyle.AsIs; + Index = int.MaxValue; + Culture = CultureInfo.InvariantCulture; + } + + /// + /// The name to use for the serialized element + /// + public string Name { get; set; } + + /// + /// Sets the value to be serialized as an Attribute instead of an Element + /// + public bool Attribute { get; set; } + + /// + /// The culture to use when serializing + /// + public CultureInfo Culture { get; set; } + + /// + /// Transforms the casing of the name based on the selected value. + /// + public NameStyle NameStyle { get; set; } + + /// + /// The order to serialize the element. Default is int.MaxValue. + /// + public int Index { get; set; } + + /// + /// Called by the attribute when NameStyle is speficied + /// + /// The string to transform + /// String + public string TransformName(string input) { + var name = Name ?? input; + switch (NameStyle) { + case NameStyle.CamelCase: + return name.ToCamelCase(Culture); + case NameStyle.PascalCase: + return name.ToPascalCase(Culture); + case NameStyle.LowerCase: + return name.ToLower(); + } + + return input; + } + } + + /// + /// Options for transforming casing of element names + /// + public enum NameStyle + { + AsIs, + CamelCase, + LowerCase, + PascalCase + } +} diff --git a/Backup/RestSharp.Silverlight/Serializers/XmlSerializer.cs b/Backup/RestSharp.Silverlight/Serializers/XmlSerializer.cs new file mode 100644 index 000000000..a6fcca2d6 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Serializers/XmlSerializer.cs @@ -0,0 +1,245 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Collections; +using System.Globalization; +using System.Linq; +using System.Xml.Linq; +using RestSharp.Extensions; + +namespace RestSharp.Serializers +{ + /// + /// Default XML Serializer + /// + public class XmlSerializer : ISerializer + { + /// + /// Default constructor, does not specify namespace + /// + public XmlSerializer() { + ContentType = "text/xml"; + } + + /// + /// Specify the namespaced to be used when serializing + /// + /// XML namespace + public XmlSerializer(string @namespace) { + Namespace = @namespace; + ContentType = "text/xml"; + } + + /// + /// Serialize the object as XML + /// + /// Object to serialize + /// XML as string + public string Serialize(object obj) { + var doc = new XDocument(); + + var t = obj.GetType(); + var name = t.Name; + + var options = t.GetAttribute(); + if (options != null) { + name = options.TransformName(options.Name ?? name); + } + + var root = new XElement(name.AsNamespaced(Namespace)); + + if (obj is IList) + { + var itemTypeName = ""; + foreach (var item in (IList)obj) + { + var type = item.GetType(); + var opts = type.GetAttribute(); + if (opts != null) + { + itemTypeName = opts.TransformName(opts.Name ?? name); + } + if (itemTypeName == "") + { + itemTypeName = type.Name; + } + var instance = new XElement(itemTypeName.AsNamespaced(Namespace)); + Map(instance, item); + root.Add(instance); + } + } + else + Map(root, obj); + + if (RootElement.HasValue()) { + var wrapper = new XElement(RootElement.AsNamespaced(Namespace), root); + doc.Add(wrapper); + } + else { + doc.Add(root); + } + + return doc.ToString(); + } + + private void Map(XElement root, object obj) { + var objType = obj.GetType(); + + var props = from p in objType.GetProperties() + let indexAttribute = p.GetAttribute() + where p.CanRead && p.CanWrite + orderby indexAttribute == null ? int.MaxValue : indexAttribute.Index + select p; + + var globalOptions = objType.GetAttribute(); + + foreach (var prop in props) { + var name = prop.Name; + var rawValue = prop.GetValue(obj, null); + + if (rawValue == null) { + continue; + } + + var value = GetSerializedValue(rawValue); + var propType = prop.PropertyType; + + var useAttribute = false; + var settings = prop.GetAttribute(); + if (settings != null) { + name = settings.Name.HasValue() ? settings.Name : name; + useAttribute = settings.Attribute; + } + + var options = prop.GetAttribute(); + if (options != null) { + name = options.TransformName(name); + } + else if (globalOptions != null) { + name = globalOptions.TransformName(name); + } + + var nsName = name.AsNamespaced(Namespace); + var element = new XElement(nsName); + + if (propType.IsPrimitive || propType.IsValueType || propType == typeof(string)) { + if (useAttribute) { + root.Add(new XAttribute(name, value)); + continue; + } + + element.Value = value; + } + else if (rawValue is IList) { + var itemTypeName = ""; + foreach (var item in (IList)rawValue) { + if (itemTypeName == "") + { + var type = item.GetType(); + var setting = type.GetAttribute(); + itemTypeName = setting != null && setting.Name.HasValue() + ? setting.Name + : type.Name; + } + var instance = new XElement(itemTypeName.AsNamespaced(Namespace)); + Map(instance, item); + element.Add(instance); + } + } + else { + Map(element, rawValue); + } + + root.Add(element); + } + } + + private string GetSerializedValue(object obj) { + var output = obj; + + if (obj is DateTime && DateFormat.HasValue()) + { + output = ((DateTime) obj).ToString(DateFormat, CultureInfo.InvariantCulture); + } + if (obj is bool) + { + output = ((bool)obj).ToString(CultureInfo.InvariantCulture).ToLower(); + } + if (IsNumeric(obj)) + { + return SerializeNumber(obj); + } + + return output.ToString(); + } + + static string SerializeNumber(object number) + { + if (number is long) + return ((long)number).ToString(CultureInfo.InvariantCulture); + else if (number is ulong) + return ((ulong)number).ToString(CultureInfo.InvariantCulture); + else if (number is int) + return ((int)number).ToString(CultureInfo.InvariantCulture); + else if (number is uint) + return ((uint)number).ToString(CultureInfo.InvariantCulture); + else if (number is decimal) + return ((decimal)number).ToString(CultureInfo.InvariantCulture); + else if (number is float) + return ((float)number).ToString(CultureInfo.InvariantCulture); + else + return (Convert.ToDouble(number, CultureInfo.InvariantCulture).ToString("r", CultureInfo.InvariantCulture)); + } + + /// + /// Determines if a given object is numeric in any way + /// (can be integer, double, null, etc). + /// + static bool IsNumeric(object value) + { + if (value is sbyte) return true; + if (value is byte) return true; + if (value is short) return true; + if (value is ushort) return true; + if (value is int) return true; + if (value is uint) return true; + if (value is long) return true; + if (value is ulong) return true; + if (value is float) return true; + if (value is double) return true; + if (value is decimal) return true; + return false; + } + + /// + /// Name of the root element to use when serializing + /// + public string RootElement { get; set; } + /// + /// XML namespace to use when serializing + /// + public string Namespace { get; set; } + /// + /// Format string to use when serializing dates + /// + public string DateFormat { get; set; } + /// + /// Content type for serialized content + /// + public string ContentType { get; set; } + } +} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/SharedAssemblyInfo.cs b/Backup/RestSharp.Silverlight/SharedAssemblyInfo.cs new file mode 100644 index 000000000..c7f7ed61b --- /dev/null +++ b/Backup/RestSharp.Silverlight/SharedAssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyDescription("Simple REST and HTTP API Client")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("John Sheehan, RestSharp Community")] +[assembly: AssemblyProduct("RestSharp")] +[assembly: AssemblyCopyright("Copyright © RestSharp Project 2009-2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: CLSCompliant(true)] +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion(SharedAssembylInfo.Version + ".0")] +[assembly: AssemblyInformationalVersion(SharedAssembylInfo.Version)] + +#if !PocketPC +[assembly: AssemblyFileVersion(SharedAssembylInfo.Version + ".0")] +#endif + +class SharedAssembylInfo +{ + public const string Version = "104.4.0"; +} diff --git a/Backup/RestSharp.Silverlight/SimpleJson.cs b/Backup/RestSharp.Silverlight/SimpleJson.cs new file mode 100644 index 000000000..e5fc1066f --- /dev/null +++ b/Backup/RestSharp.Silverlight/SimpleJson.cs @@ -0,0 +1,2094 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) 2011, The Outercurve Foundation. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.opensource.org/licenses/mit-license.php +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Nathan Totten (ntotten.com), Jim Zimmerman (jimzimmerman.com) and Prabir Shrestha (prabir.me) +// https://github.com/facebook-csharp-sdk/simple-json +//----------------------------------------------------------------------- + +// VERSION: 0.26.0 + +// NOTE: uncomment the following line to make SimpleJson class internal. +//#define SIMPLE_JSON_INTERNAL + +// NOTE: uncomment the following line to make JsonArray and JsonObject class internal. +//#define SIMPLE_JSON_OBJARRAYINTERNAL + +// NOTE: uncomment the following line to enable dynamic support. +//#define SIMPLE_JSON_DYNAMIC + +// NOTE: uncomment the following line to enable DataContract support. +//#define SIMPLE_JSON_DATACONTRACT + +// NOTE: uncomment the following line to disable linq expressions/compiled lambda (better performance) instead of method.invoke(). +// define if you are using .net framework <= 3.0 or < WP7.5 +//#define SIMPLE_JSON_NO_LINQ_EXPRESSION + +// NOTE: uncomment the following line if you are compiling under Window Metro style application/library. +// usually already defined in properties +//#define NETFX_CORE; + +// If you are targetting WinStore, WP8 and NET4.5+ PCL make sure to #define SIMPLE_JSON_TYPEINFO; + +// original json parsing code from http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html + +#if NETFX_CORE +#define SIMPLE_JSON_TYPEINFO +#endif + +using System; +using System.CodeDom.Compiler; +using System.Collections; +using System.Collections.Generic; +#if !SIMPLE_JSON_NO_LINQ_EXPRESSION +using System.Linq.Expressions; +#endif +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +#if SIMPLE_JSON_DYNAMIC +using System.Dynamic; +#endif +using System.Globalization; +using System.Reflection; +using System.Runtime.Serialization; +using System.Text; +using RestSharp.Reflection; + +// ReSharper disable LoopCanBeConvertedToQuery +// ReSharper disable RedundantExplicitArrayCreation +// ReSharper disable SuggestUseVarKeywordEvident +namespace RestSharp +{ + /// + /// Represents the json array. + /// + [GeneratedCode("simple-json", "1.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] +#if SIMPLE_JSON_OBJARRAYINTERNAL + internal +#else + public +#endif + class JsonArray : List + { + /// + /// Initializes a new instance of the class. + /// + public JsonArray() { } + + /// + /// Initializes a new instance of the class. + /// + /// The capacity of the json array. + public JsonArray(int capacity) : base(capacity) { } + + /// + /// The json representation of the array. + /// + /// The json representation of the array. + public override string ToString() + { + return SimpleJson.SerializeObject(this) ?? string.Empty; + } + } + + /// + /// Represents the json object. + /// + [GeneratedCode("simple-json", "1.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] +#if SIMPLE_JSON_OBJARRAYINTERNAL + internal +#else + public +#endif + class JsonObject : +#if SIMPLE_JSON_DYNAMIC + DynamicObject, +#endif + IDictionary + { + /// + /// The internal member dictionary. + /// + private readonly Dictionary _members; + + /// + /// Initializes a new instance of . + /// + public JsonObject() + { + _members = new Dictionary(); + } + + /// + /// Initializes a new instance of . + /// + /// The implementation to use when comparing keys, or null to use the default for the type of the key. + public JsonObject(IEqualityComparer comparer) + { + _members = new Dictionary(comparer); + } + + /// + /// Gets the at the specified index. + /// + /// + public object this[int index] + { + get { return GetAtIndex(_members, index); } + } + + internal static object GetAtIndex(IDictionary obj, int index) + { + if (obj == null) + throw new ArgumentNullException("obj"); + if (index >= obj.Count) + throw new ArgumentOutOfRangeException("index"); + int i = 0; + foreach (KeyValuePair o in obj) + if (i++ == index) return o.Value; + return null; + } + + /// + /// Adds the specified key. + /// + /// The key. + /// The value. + public void Add(string key, object value) + { + _members.Add(key, value); + } + + /// + /// Determines whether the specified key contains key. + /// + /// The key. + /// + /// true if the specified key contains key; otherwise, false. + /// + public bool ContainsKey(string key) + { + return _members.ContainsKey(key); + } + + /// + /// Gets the keys. + /// + /// The keys. + public ICollection Keys + { + get { return _members.Keys; } + } + + /// + /// Removes the specified key. + /// + /// The key. + /// + public bool Remove(string key) + { + return _members.Remove(key); + } + + /// + /// Tries the get value. + /// + /// The key. + /// The value. + /// + public bool TryGetValue(string key, out object value) + { + return _members.TryGetValue(key, out value); + } + + /// + /// Gets the values. + /// + /// The values. + public ICollection Values + { + get { return _members.Values; } + } + + /// + /// Gets or sets the with the specified key. + /// + /// + public object this[string key] + { + get { return _members[key]; } + set { _members[key] = value; } + } + + /// + /// Adds the specified item. + /// + /// The item. + public void Add(KeyValuePair item) + { + _members.Add(item.Key, item.Value); + } + + /// + /// Clears this instance. + /// + public void Clear() + { + _members.Clear(); + } + + /// + /// Determines whether [contains] [the specified item]. + /// + /// The item. + /// + /// true if [contains] [the specified item]; otherwise, false. + /// + public bool Contains(KeyValuePair item) + { + return _members.ContainsKey(item.Key) && _members[item.Key] == item.Value; + } + + /// + /// Copies to. + /// + /// The array. + /// Index of the array. + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + if (array == null) throw new ArgumentNullException("array"); + int num = Count; + foreach (KeyValuePair kvp in this) + { + array[arrayIndex++] = kvp; + if (--num <= 0) + return; + } + } + + /// + /// Gets the count. + /// + /// The count. + public int Count + { + get { return _members.Count; } + } + + /// + /// Gets a value indicating whether this instance is read only. + /// + /// + /// true if this instance is read only; otherwise, false. + /// + public bool IsReadOnly + { + get { return false; } + } + + /// + /// Removes the specified item. + /// + /// The item. + /// + public bool Remove(KeyValuePair item) + { + return _members.Remove(item.Key); + } + + /// + /// Gets the enumerator. + /// + /// + public IEnumerator> GetEnumerator() + { + return _members.GetEnumerator(); + } + + /// + /// Returns an enumerator that iterates through a collection. + /// + /// + /// An object that can be used to iterate through the collection. + /// + IEnumerator IEnumerable.GetEnumerator() + { + return _members.GetEnumerator(); + } + + /// + /// Returns a json that represents the current . + /// + /// + /// A json that represents the current . + /// + public override string ToString() + { + return SimpleJson.SerializeObject(this); + } + +#if SIMPLE_JSON_DYNAMIC + /// + /// Provides implementation for type conversion operations. Classes derived from the class can override this method to specify dynamic behavior for operations that convert an object from one type to another. + /// + /// Provides information about the conversion operation. The binder.Type property provides the type to which the object must be converted. For example, for the statement (String)sampleObject in C# (CType(sampleObject, Type) in Visual Basic), where sampleObject is an instance of the class derived from the class, binder.Type returns the type. The binder.Explicit property provides information about the kind of conversion that occurs. It returns true for explicit conversion and false for implicit conversion. + /// The result of the type conversion operation. + /// + /// Alwasy returns true. + /// + public override bool TryConvert(ConvertBinder binder, out object result) + { + // + if (binder == null) + throw new ArgumentNullException("binder"); + // + Type targetType = binder.Type; + + if ((targetType == typeof(IEnumerable)) || + (targetType == typeof(IEnumerable>)) || + (targetType == typeof(IDictionary)) || + (targetType == typeof(IDictionary))) + { + result = this; + return true; + } + + return base.TryConvert(binder, out result); + } + + /// + /// Provides the implementation for operations that delete an object member. This method is not intended for use in C# or Visual Basic. + /// + /// Provides information about the deletion. + /// + /// Alwasy returns true. + /// + public override bool TryDeleteMember(DeleteMemberBinder binder) + { + // + if (binder == null) + throw new ArgumentNullException("binder"); + // + return _members.Remove(binder.Name); + } + + /// + /// Provides the implementation for operations that get a value by index. Classes derived from the class can override this method to specify dynamic behavior for indexing operations. + /// + /// Provides information about the operation. + /// The indexes that are used in the operation. For example, for the sampleObject[3] operation in C# (sampleObject(3) in Visual Basic), where sampleObject is derived from the DynamicObject class, is equal to 3. + /// The result of the index operation. + /// + /// Alwasy returns true. + /// + public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length == 1) + { + result = ((IDictionary)this)[(string)indexes[0]]; + return true; + } + result = null; + return true; + } + + /// + /// Provides the implementation for operations that get member values. Classes derived from the class can override this method to specify dynamic behavior for operations such as getting a value for a property. + /// + /// Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive. + /// The result of the get operation. For example, if the method is called for a property, you can assign the property value to . + /// + /// Alwasy returns true. + /// + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + object value; + if (_members.TryGetValue(binder.Name, out value)) + { + result = value; + return true; + } + result = null; + return true; + } + + /// + /// Provides the implementation for operations that set a value by index. Classes derived from the class can override this method to specify dynamic behavior for operations that access objects by a specified index. + /// + /// Provides information about the operation. + /// The indexes that are used in the operation. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the class, is equal to 3. + /// The value to set to the object that has the specified index. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the class, is equal to 10. + /// + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown. + /// + public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) + { + if (indexes == null) throw new ArgumentNullException("indexes"); + if (indexes.Length == 1) + { + ((IDictionary)this)[(string)indexes[0]] = value; + return true; + } + return base.TrySetIndex(binder, indexes, value); + } + + /// + /// Provides the implementation for operations that set member values. Classes derived from the class can override this method to specify dynamic behavior for operations such as setting a value for a property. + /// + /// Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member to which the value is being assigned. For example, for the statement sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive. + /// The value to set to the member. For example, for sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the class, the is "Test". + /// + /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.) + /// + public override bool TrySetMember(SetMemberBinder binder, object value) + { + // + if (binder == null) + throw new ArgumentNullException("binder"); + // + _members[binder.Name] = value; + return true; + } + + /// + /// Returns the enumeration of all dynamic member names. + /// + /// + /// A sequence that contains dynamic member names. + /// + public override IEnumerable GetDynamicMemberNames() + { + foreach (var key in Keys) + yield return key; + } +#endif + } +} + +namespace RestSharp +{ + /// + /// This class encodes and decodes JSON strings. + /// Spec. details, see http://www.json.org/ + /// + /// JSON uses Arrays and Objects. These correspond here to the datatypes JsonArray(IList<object>) and JsonObject(IDictionary<string,object>). + /// All numbers are parsed to doubles. + /// + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + static class SimpleJson + { + private const int TOKEN_NONE = 0; + private const int TOKEN_CURLY_OPEN = 1; + private const int TOKEN_CURLY_CLOSE = 2; + private const int TOKEN_SQUARED_OPEN = 3; + private const int TOKEN_SQUARED_CLOSE = 4; + private const int TOKEN_COLON = 5; + private const int TOKEN_COMMA = 6; + private const int TOKEN_STRING = 7; + private const int TOKEN_NUMBER = 8; + private const int TOKEN_TRUE = 9; + private const int TOKEN_FALSE = 10; + private const int TOKEN_NULL = 11; + private const int BUILDER_CAPACITY = 2000; + + /// + /// Parses the string json into a value + /// + /// A JSON string. + /// An IList<object>, a IDictionary<string,object>, a double, a string, null, true, or false + public static object DeserializeObject(string json) + { + object obj; + if (TryDeserializeObject(json, out obj)) + return obj; + throw new SerializationException("Invalid JSON string"); + } + + /// + /// Try parsing the json string into a value. + /// + /// + /// A JSON string. + /// + /// + /// The object. + /// + /// + /// Returns true if successfull otherwise false. + /// + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] + public static bool TryDeserializeObject(string json, out object obj) + { + bool success = true; + if (json != null) + { + char[] charArray = json.ToCharArray(); + int index = 0; + obj = ParseValue(charArray, ref index, ref success); + } + else + obj = null; + + return success; + } + + public static object DeserializeObject(string json, Type type, IJsonSerializerStrategy jsonSerializerStrategy) + { + object jsonObject = DeserializeObject(json); + return type == null || jsonObject != null && ReflectionUtils.IsAssignableFrom(jsonObject.GetType(), type) + ? jsonObject + : (jsonSerializerStrategy ?? CurrentJsonSerializerStrategy).DeserializeObject(jsonObject, type); + } + + public static object DeserializeObject(string json, Type type) + { + return DeserializeObject(json, type, null); + } + + public static T DeserializeObject(string json, IJsonSerializerStrategy jsonSerializerStrategy) + { + return (T)DeserializeObject(json, typeof(T), jsonSerializerStrategy); + } + + public static T DeserializeObject(string json) + { + return (T)DeserializeObject(json, typeof(T), null); + } + + /// + /// Converts a IDictionary<string,object> / IList<object> object into a JSON string + /// + /// A IDictionary<string,object> / IList<object> + /// Serializer strategy to use + /// A JSON encoded string, or null if object 'json' is not serializable + public static string SerializeObject(object json, IJsonSerializerStrategy jsonSerializerStrategy) + { + StringBuilder builder = new StringBuilder(BUILDER_CAPACITY); + bool success = SerializeValue(jsonSerializerStrategy, json, builder); + return (success ? builder.ToString() : null); + } + + public static string SerializeObject(object json) + { + return SerializeObject(json, CurrentJsonSerializerStrategy); + } + + public static string EscapeToJavascriptString(string jsonString) + { + if (string.IsNullOrEmpty(jsonString)) + return jsonString; + + StringBuilder sb = new StringBuilder(); + char c; + + for (int i = 0; i < jsonString.Length; ) + { + c = jsonString[i++]; + + if (c == '\\') + { + int remainingLength = jsonString.Length - i; + if (remainingLength >= 2) + { + char lookahead = jsonString[i]; + if (lookahead == '\\') + { + sb.Append('\\'); + ++i; + } + else if (lookahead == '"') + { + sb.Append("\""); + ++i; + } + else if (lookahead == 't') + { + sb.Append('\t'); + ++i; + } + else if (lookahead == 'b') + { + sb.Append('\b'); + ++i; + } + else if (lookahead == 'n') + { + sb.Append('\n'); + ++i; + } + else if (lookahead == 'r') + { + sb.Append('\r'); + ++i; + } + } + } + else + { + sb.Append(c); + } + } + return sb.ToString(); + } + + static IDictionary ParseObject(char[] json, ref int index, ref bool success) + { + IDictionary table = new JsonObject(); + int token; + + // { + NextToken(json, ref index); + + bool done = false; + while (!done) + { + token = LookAhead(json, index); + if (token == TOKEN_NONE) + { + success = false; + return null; + } + else if (token == TOKEN_COMMA) + NextToken(json, ref index); + else if (token == TOKEN_CURLY_CLOSE) + { + NextToken(json, ref index); + return table; + } + else + { + // name + string name = ParseString(json, ref index, ref success); + if (!success) + { + success = false; + return null; + } + // : + token = NextToken(json, ref index); + if (token != TOKEN_COLON) + { + success = false; + return null; + } + // value + object value = ParseValue(json, ref index, ref success); + if (!success) + { + success = false; + return null; + } + table[name] = value; + } + } + return table; + } + + static JsonArray ParseArray(char[] json, ref int index, ref bool success) + { + JsonArray array = new JsonArray(); + + // [ + NextToken(json, ref index); + + bool done = false; + while (!done) + { + int token = LookAhead(json, index); + if (token == TOKEN_NONE) + { + success = false; + return null; + } + else if (token == TOKEN_COMMA) + NextToken(json, ref index); + else if (token == TOKEN_SQUARED_CLOSE) + { + NextToken(json, ref index); + break; + } + else + { + object value = ParseValue(json, ref index, ref success); + if (!success) + return null; + array.Add(value); + } + } + return array; + } + + static object ParseValue(char[] json, ref int index, ref bool success) + { + switch (LookAhead(json, index)) + { + case TOKEN_STRING: + return ParseString(json, ref index, ref success); + case TOKEN_NUMBER: + return ParseNumber(json, ref index, ref success); + case TOKEN_CURLY_OPEN: + return ParseObject(json, ref index, ref success); + case TOKEN_SQUARED_OPEN: + return ParseArray(json, ref index, ref success); + case TOKEN_TRUE: + NextToken(json, ref index); + return true; + case TOKEN_FALSE: + NextToken(json, ref index); + return false; + case TOKEN_NULL: + NextToken(json, ref index); + return null; + case TOKEN_NONE: + break; + } + success = false; + return null; + } + + static string ParseString(char[] json, ref int index, ref bool success) + { + StringBuilder s = new StringBuilder(BUILDER_CAPACITY); + char c; + + EatWhitespace(json, ref index); + + // " + c = json[index++]; + bool complete = false; + while (!complete) + { + if (index == json.Length) + break; + + c = json[index++]; + if (c == '"') + { + complete = true; + break; + } + else if (c == '\\') + { + if (index == json.Length) + break; + c = json[index++]; + if (c == '"') + s.Append('"'); + else if (c == '\\') + s.Append('\\'); + else if (c == '/') + s.Append('/'); + else if (c == 'b') + s.Append('\b'); + else if (c == 'f') + s.Append('\f'); + else if (c == 'n') + s.Append('\n'); + else if (c == 'r') + s.Append('\r'); + else if (c == 't') + s.Append('\t'); + else if (c == 'u') + { + int remainingLength = json.Length - index; + if (remainingLength >= 4) + { + // parse the 32 bit hex into an integer codepoint + uint codePoint; + +#if PocketPC + try { + codePoint = UInt32.Parse(new string(json, index, 4), NumberStyles.HexNumber); + } catch (Exception ex) { + return ""; + } +#else + if (!(success = UInt32.TryParse(new string(json, index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codePoint))) + return ""; +#endif + // convert the integer codepoint to a unicode char and add to string + if (0xD800 <= codePoint && codePoint <= 0xDBFF) // if high surrogate + { + index += 4; // skip 4 chars + remainingLength = json.Length - index; + if (remainingLength >= 6) + { + uint lowCodePoint = 0; + +#if PocketPC + bool lowCodePointPassed = false; + try { + lowCodePoint = UInt32.Parse(new string(json, index + 2, 4), NumberStyles.HexNumber); + lowCodePointPassed = true; + } catch (Exception) { } + if (new string(json, index, 2) == "\\u" && lowCodePointPassed) +#else + if (new string(json, index, 2) == "\\u" && UInt32.TryParse(new string(json, index + 2, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out lowCodePoint)) +#endif + { + if (0xDC00 <= lowCodePoint && lowCodePoint <= 0xDFFF) // if low surrogate + { + s.Append((char)codePoint); + s.Append((char)lowCodePoint); + index += 6; // skip 6 chars + continue; + } + } + } + success = false; // invalid surrogate pair + return ""; + } + s.Append(ConvertFromUtf32((int)codePoint)); + // skip 4 chars + index += 4; + } + else + break; + } + } + else + s.Append(c); + } + if (!complete) + { + success = false; + return null; + } + return s.ToString(); + } + + private static string ConvertFromUtf32(int utf32) + { + // http://www.java2s.com/Open-Source/CSharp/2.6.4-mono-.net-core/System/System/Char.cs.htm + if (utf32 < 0 || utf32 > 0x10FFFF) + throw new ArgumentOutOfRangeException("utf32", "The argument must be from 0 to 0x10FFFF."); + if (0xD800 <= utf32 && utf32 <= 0xDFFF) + throw new ArgumentOutOfRangeException("utf32", "The argument must not be in surrogate pair range."); + if (utf32 < 0x10000) + return new string((char)utf32, 1); + utf32 -= 0x10000; + return new string(new char[] { (char)((utf32 >> 10) + 0xD800), (char)(utf32 % 0x0400 + 0xDC00) }); + } + + static object ParseNumber(char[] json, ref int index, ref bool success) + { + EatWhitespace(json, ref index); + int lastIndex = GetLastIndexOfNumber(json, index); + int charLength = (lastIndex - index) + 1; + object returnNumber; + string str = new string(json, index, charLength); + if (str.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || str.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1) + { + double number; +#if PocketPC + try { + number = double.Parse(new string(json, index, charLength), NumberStyles.Any); + success = true; + } catch (Exception) { + number = 0; + success = false; + } +#else + success = double.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); +#endif + returnNumber = number; + } + else + { + long number; +#if PocketPC + try { + number = long.Parse(new string(json, index, charLength), NumberStyles.Any); + success = true; + } catch (Exception) { + number = 0; + success = false; + } +#else + success = long.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); +#endif + returnNumber = number; + } + index = lastIndex + 1; + return returnNumber; + } + + static int GetLastIndexOfNumber(char[] json, int index) + { + int lastIndex; + for (lastIndex = index; lastIndex < json.Length; lastIndex++) + if ("0123456789+-.eE".IndexOf(json[lastIndex]) == -1) break; + return lastIndex - 1; + } + + static void EatWhitespace(char[] json, ref int index) + { + for (; index < json.Length; index++) + if (" \t\n\r\b\f".IndexOf(json[index]) == -1) break; + } + + static int LookAhead(char[] json, int index) + { + int saveIndex = index; + return NextToken(json, ref saveIndex); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + static int NextToken(char[] json, ref int index) + { + EatWhitespace(json, ref index); + if (index == json.Length) + return TOKEN_NONE; + char c = json[index]; + index++; + switch (c) + { + case '{': + return TOKEN_CURLY_OPEN; + case '}': + return TOKEN_CURLY_CLOSE; + case '[': + return TOKEN_SQUARED_OPEN; + case ']': + return TOKEN_SQUARED_CLOSE; + case ',': + return TOKEN_COMMA; + case '"': + return TOKEN_STRING; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return TOKEN_NUMBER; + case ':': + return TOKEN_COLON; + } + index--; + int remainingLength = json.Length - index; + // false + if (remainingLength >= 5) + { + if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e') + { + index += 5; + return TOKEN_FALSE; + } + } + // true + if (remainingLength >= 4) + { + if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') + { + index += 4; + return TOKEN_TRUE; + } + } + // null + if (remainingLength >= 4) + { + if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') + { + index += 4; + return TOKEN_NULL; + } + } + return TOKEN_NONE; + } + + static bool SerializeValue(IJsonSerializerStrategy jsonSerializerStrategy, object value, StringBuilder builder) + { + bool success = true; + string stringValue = value as string; + if (stringValue != null) + success = SerializeString(stringValue, builder); + else + { + IDictionary dict = value as IDictionary; + if (dict != null) + { + success = SerializeObject(jsonSerializerStrategy, dict.Keys, dict.Values, builder); + } + else + { + IDictionary stringDictionary = value as IDictionary; + if (stringDictionary != null) + { + success = SerializeObject(jsonSerializerStrategy, stringDictionary.Keys, stringDictionary.Values, builder); + } + else + { + IEnumerable enumerableValue = value as IEnumerable; + if (enumerableValue != null) + success = SerializeArray(jsonSerializerStrategy, enumerableValue, builder); + else if (IsNumeric(value)) + success = SerializeNumber(value, builder); + else if (value is bool) + builder.Append((bool)value ? "true" : "false"); + else if (value == null) + builder.Append("null"); + else + { + object serializedObject; + success = jsonSerializerStrategy.TrySerializeNonPrimitiveObject(value, out serializedObject); + if (success) + SerializeValue(jsonSerializerStrategy, serializedObject, builder); + } + } + } + } + return success; + } + + static bool SerializeObject(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable keys, IEnumerable values, StringBuilder builder) + { + builder.Append("{"); + IEnumerator ke = keys.GetEnumerator(); + IEnumerator ve = values.GetEnumerator(); + bool first = true; + while (ke.MoveNext() && ve.MoveNext()) + { + object key = ke.Current; + object value = ve.Current; + if (!first) + builder.Append(","); + string stringKey = key as string; + if (stringKey != null) + SerializeString(stringKey, builder); + else + if (!SerializeValue(jsonSerializerStrategy, value, builder)) return false; + builder.Append(":"); + if (!SerializeValue(jsonSerializerStrategy, value, builder)) + return false; + first = false; + } + builder.Append("}"); + return true; + } + + static bool SerializeArray(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable anArray, StringBuilder builder) + { + builder.Append("["); + bool first = true; + foreach (object value in anArray) + { + if (!first) + builder.Append(","); + if (!SerializeValue(jsonSerializerStrategy, value, builder)) + return false; + first = false; + } + builder.Append("]"); + return true; + } + + static bool SerializeString(string aString, StringBuilder builder) + { + builder.Append("\""); + char[] charArray = aString.ToCharArray(); + for (int i = 0; i < charArray.Length; i++) + { + char c = charArray[i]; + if (c == '"') + builder.Append("\\\""); + else if (c == '\\') + builder.Append("\\\\"); + else if (c == '\b') + builder.Append("\\b"); + else if (c == '\f') + builder.Append("\\f"); + else if (c == '\n') + builder.Append("\\n"); + else if (c == '\r') + builder.Append("\\r"); + else if (c == '\t') + builder.Append("\\t"); + else + builder.Append(c); + } + builder.Append("\""); + return true; + } + + static bool SerializeNumber(object number, StringBuilder builder) + { + if (number is long) + builder.Append(((long)number).ToString(CultureInfo.InvariantCulture)); + else if (number is ulong) + builder.Append(((ulong)number).ToString(CultureInfo.InvariantCulture)); + else if (number is int) + builder.Append(((int)number).ToString(CultureInfo.InvariantCulture)); + else if (number is uint) + builder.Append(((uint)number).ToString(CultureInfo.InvariantCulture)); + else if (number is decimal) + builder.Append(((decimal)number).ToString(CultureInfo.InvariantCulture)); + else if (number is float) + builder.Append(((float)number).ToString(CultureInfo.InvariantCulture)); + else + builder.Append(Convert.ToDouble(number, CultureInfo.InvariantCulture).ToString("r", CultureInfo.InvariantCulture)); + return true; + } + + /// + /// Determines if a given object is numeric in any way + /// (can be integer, double, null, etc). + /// + static bool IsNumeric(object value) + { + if (value is sbyte) return true; + if (value is byte) return true; + if (value is short) return true; + if (value is ushort) return true; + if (value is int) return true; + if (value is uint) return true; + if (value is long) return true; + if (value is ulong) return true; + if (value is float) return true; + if (value is double) return true; + if (value is decimal) return true; + return false; + } + + private static IJsonSerializerStrategy _currentJsonSerializerStrategy; + public static IJsonSerializerStrategy CurrentJsonSerializerStrategy + { + get + { + return _currentJsonSerializerStrategy ?? + (_currentJsonSerializerStrategy = +#if SIMPLE_JSON_DATACONTRACT + DataContractJsonSerializerStrategy +#else + PocoJsonSerializerStrategy +#endif +); + } + set + { + _currentJsonSerializerStrategy = value; + } + } + + private static PocoJsonSerializerStrategy _pocoJsonSerializerStrategy; + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static PocoJsonSerializerStrategy PocoJsonSerializerStrategy + { + get + { + return _pocoJsonSerializerStrategy ?? (_pocoJsonSerializerStrategy = new PocoJsonSerializerStrategy()); + } + } + +#if SIMPLE_JSON_DATACONTRACT + + private static DataContractJsonSerializerStrategy _dataContractJsonSerializerStrategy; + [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Advanced)] + public static DataContractJsonSerializerStrategy DataContractJsonSerializerStrategy + { + get + { + return _dataContractJsonSerializerStrategy ?? (_dataContractJsonSerializerStrategy = new DataContractJsonSerializerStrategy()); + } + } + +#endif + } + + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + interface IJsonSerializerStrategy + { + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] + bool TrySerializeNonPrimitiveObject(object input, out object output); + object DeserializeObject(object value, Type type); + } + + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + class PocoJsonSerializerStrategy : IJsonSerializerStrategy + { + internal IDictionary ConstructorCache; + internal IDictionary> GetCache; + internal IDictionary>> SetCache; + + internal static readonly Type[] EmptyTypes = new Type[0]; + internal static readonly Type[] ArrayConstructorParameterTypes = new Type[] { typeof(int) }; + + private static readonly string[] Iso8601Format = new string[] + { + @"yyyy-MM-dd\THH:mm:ss.FFFFFFF\Z", + @"yyyy-MM-dd\THH:mm:ss\Z", + @"yyyy-MM-dd\THH:mm:ssK" + }; + + public PocoJsonSerializerStrategy() + { + ConstructorCache = new ReflectionUtils.ThreadSafeDictionary(ContructorDelegateFactory); + GetCache = new ReflectionUtils.ThreadSafeDictionary>(GetterValueFactory); + SetCache = new ReflectionUtils.ThreadSafeDictionary>>(SetterValueFactory); + } + + protected virtual string MapClrMemberNameToJsonFieldName(string clrPropertyName) + { + return clrPropertyName; + } + + internal virtual ReflectionUtils.ConstructorDelegate ContructorDelegateFactory(Type key) + { + return ReflectionUtils.GetContructor(key, key.IsArray ? ArrayConstructorParameterTypes : EmptyTypes); + } + + internal virtual IDictionary GetterValueFactory(Type type) + { + IDictionary result = new Dictionary(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanRead) + { + MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); + if (getMethod.IsStatic || !getMethod.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(propertyInfo.Name)] = ReflectionUtils.GetGetMethod(propertyInfo); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (fieldInfo.IsStatic || !fieldInfo.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(fieldInfo.Name)] = ReflectionUtils.GetGetMethod(fieldInfo); + } + return result; + } + + internal virtual IDictionary> SetterValueFactory(Type type) + { + IDictionary> result = new Dictionary>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanWrite) + { + MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); + if (setMethod.IsStatic || !setMethod.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(propertyInfo.Name)] = new KeyValuePair(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (fieldInfo.IsInitOnly || fieldInfo.IsStatic || !fieldInfo.IsPublic) + continue; + result[MapClrMemberNameToJsonFieldName(fieldInfo.Name)] = new KeyValuePair(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); + } + return result; + } + + public virtual bool TrySerializeNonPrimitiveObject(object input, out object output) + { + return TrySerializeKnownTypes(input, out output) || TrySerializeUnknownTypes(input, out output); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + public virtual object DeserializeObject(object value, Type type) + { + if (type == null) throw new ArgumentNullException("type"); + string str = value as string; + + if (type == typeof (Guid) && string.IsNullOrEmpty(str)) + return default(Guid); + + if (value == null) + return null; + + object obj = null; + + if (str != null) + { + if (str.Length != 0) // We know it can't be null now. + { + if (type == typeof(DateTime) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTime))) + return DateTime.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); +#if !PocketPC + if (type == typeof(DateTimeOffset) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTimeOffset))) + return DateTimeOffset.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); +#endif + if (type == typeof(Guid) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid))) + return new Guid(str); + return str; + } + else + { + if (type == typeof(Guid)) + obj = default(Guid); + else if (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) + obj = null; + else + obj = str; + } + // Empty string case + if (!ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) + return str; + } + else if (value is bool) + return value; + + bool valueIsLong = value is long; + bool valueIsDouble = value is double; + if ((valueIsLong && type == typeof(long)) || (valueIsDouble && type == typeof(double))) + return value; + if ((valueIsDouble && type != typeof(double)) || (valueIsLong && type != typeof(long))) + { + obj = type == typeof(int) || type == typeof(long) || type == typeof(double) || type == typeof(float) || type == typeof(bool) || type == typeof(decimal) || type == typeof(byte) || type == typeof(short) + ? Convert.ChangeType(value, type, CultureInfo.InvariantCulture) + : value; + } + else + { + IDictionary objects = value as IDictionary; + if (objects != null) + { + IDictionary jsonObject = objects; + + if (ReflectionUtils.IsTypeDictionary(type)) + { + // if dictionary then + Type[] types = ReflectionUtils.GetGenericTypeArguments(type); + Type keyType = types[0]; + Type valueType = types[1]; + + Type genericType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); + + IDictionary dict = (IDictionary)ConstructorCache[genericType](); + + foreach (KeyValuePair kvp in jsonObject) + dict.Add(kvp.Key, DeserializeObject(kvp.Value, valueType)); + + obj = dict; + } + else + { + if (type == typeof(object)) + obj = value; + else + { + obj = ConstructorCache[type](); + foreach (KeyValuePair> setter in SetCache[type]) + { + object jsonValue; + if (jsonObject.TryGetValue(setter.Key, out jsonValue)) + { + jsonValue = DeserializeObject(jsonValue, setter.Value.Key); + setter.Value.Value(obj, jsonValue); + } + } + } + } + } + else + { + IList valueAsList = value as IList; + if (valueAsList != null) + { + IList jsonObject = valueAsList; + IList list = null; + + if (type.IsArray) + { + list = (IList)ConstructorCache[type](jsonObject.Count); + int i = 0; + foreach (object o in jsonObject) + list[i++] = DeserializeObject(o, type.GetElementType()); + } + else if (ReflectionUtils.IsTypeGenericeCollectionInterface(type) || ReflectionUtils.IsAssignableFrom(typeof(IList), type)) + { + Type innerType = ReflectionUtils.GetGenericTypeArguments(type)[0]; + Type genericType = typeof(List<>).MakeGenericType(innerType); + list = (IList)ConstructorCache[genericType](jsonObject.Count); + foreach (object o in jsonObject) + list.Add(DeserializeObject(o, innerType)); + } + obj = list; + } + } + return obj; + } + if (ReflectionUtils.IsNullableType(type)) + return ReflectionUtils.ToNullableType(obj, type); + return obj; + } + + protected virtual object SerializeEnum(Enum p) + { + return Convert.ToDouble(p, CultureInfo.InvariantCulture); + } + + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] + protected virtual bool TrySerializeKnownTypes(object input, out object output) + { + bool returnValue = true; + if (input is DateTime) + output = ((DateTime)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); +#if !PocketPC + else if (input is DateTimeOffset) + output = ((DateTimeOffset)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); +#endif + else if (input is Guid) + output = ((Guid)input).ToString("D"); + else if (input is Uri) + output = input.ToString(); + else + { + Enum inputEnum = input as Enum; + if (inputEnum != null) + output = SerializeEnum(inputEnum); + else + { + returnValue = false; + output = null; + } + } + return returnValue; + } + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] + protected virtual bool TrySerializeUnknownTypes(object input, out object output) + { + if (input == null) throw new ArgumentNullException("input"); + output = null; + Type type = input.GetType(); + if (type.FullName == null) + return false; + IDictionary obj = new JsonObject(); + IDictionary getters = GetCache[type]; + foreach (KeyValuePair getter in getters) + { + if (getter.Value != null) + obj.Add(MapClrMemberNameToJsonFieldName(getter.Key), getter.Value(input)); + } + output = obj; + return true; + } + } + +#if SIMPLE_JSON_DATACONTRACT + [GeneratedCode("simple-json", "1.0.0")] +#if SIMPLE_JSON_INTERNAL + internal +#else + public +#endif + class DataContractJsonSerializerStrategy : PocoJsonSerializerStrategy + { + public DataContractJsonSerializerStrategy() + { + GetCache = new ReflectionUtils.ThreadSafeDictionary>(GetterValueFactory); + SetCache = new ReflectionUtils.ThreadSafeDictionary>>(SetterValueFactory); + } + + internal override IDictionary GetterValueFactory(Type type) + { + bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; + if (!hasDataContract) + return base.GetterValueFactory(type); + string jsonKey; + IDictionary result = new Dictionary(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanRead) + { + MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); + if (!getMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) + result[jsonKey] = ReflectionUtils.GetGetMethod(propertyInfo); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (!fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) + result[jsonKey] = ReflectionUtils.GetGetMethod(fieldInfo); + } + return result; + } + + internal override IDictionary> SetterValueFactory(Type type) + { + bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; + if (!hasDataContract) + return base.SetterValueFactory(type); + string jsonKey; + IDictionary> result = new Dictionary>(); + foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) + { + if (propertyInfo.CanWrite) + { + MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); + if (!setMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) + result[jsonKey] = new KeyValuePair(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); + } + } + foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) + { + if (!fieldInfo.IsInitOnly && !fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) + result[jsonKey] = new KeyValuePair(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); + } + // todo implement sorting for DATACONTRACT. + return result; + } + + private static bool CanAdd(MemberInfo info, out string jsonKey) + { + jsonKey = null; + if (ReflectionUtils.GetAttribute(info, typeof(IgnoreDataMemberAttribute)) != null) + return false; + DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)ReflectionUtils.GetAttribute(info, typeof(DataMemberAttribute)); + if (dataMemberAttribute == null) + return false; + jsonKey = string.IsNullOrEmpty(dataMemberAttribute.Name) ? info.Name : dataMemberAttribute.Name; + return true; + } + } + +#endif + + namespace Reflection + { + // This class is meant to be copied into other libraries. So we want to exclude it from Code Analysis rules + // that might be in place in the target project. + [GeneratedCode("reflection-utils", "1.0.0")] +#if SIMPLE_JSON_REFLECTION_UTILS_PUBLIC + public +#else + internal +#endif + class ReflectionUtils + { + private static readonly object[] EmptyObjects = new object[] { }; + + public delegate object GetDelegate(object source); + public delegate void SetDelegate(object source, object value); + public delegate object ConstructorDelegate(params object[] args); + + public delegate TValue ThreadSafeDictionaryValueFactory(TKey key); + + public static Attribute GetAttribute(MemberInfo info, Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (info == null || type == null || !info.IsDefined(type)) + return null; + return info.GetCustomAttribute(type); +#else + if (info == null || type == null || !Attribute.IsDefined(info, type)) + return null; + return Attribute.GetCustomAttribute(info, type); +#endif + } + + public static Attribute GetAttribute(Type objectType, Type attributeType) + { + +#if SIMPLE_JSON_TYPEINFO + if (objectType == null || attributeType == null || !objectType.GetTypeInfo().IsDefined(attributeType)) + return null; + return objectType.GetTypeInfo().GetCustomAttribute(attributeType); +#else + if (objectType == null || attributeType == null || !Attribute.IsDefined(objectType, attributeType)) + return null; + return Attribute.GetCustomAttribute(objectType, attributeType); +#endif + } + + public static Type[] GetGenericTypeArguments(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().GenericTypeArguments; +#else + return type.GetGenericArguments(); +#endif + } + + public static bool IsTypeGenericeCollectionInterface(Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (!type.GetTypeInfo().IsGenericType) +#else + if (!type.IsGenericType) +#endif + return false; + + Type genericDefinition = type.GetGenericTypeDefinition(); + + return (genericDefinition == typeof(IList<>) || genericDefinition == typeof(ICollection<>) || genericDefinition == typeof(IEnumerable<>)); + } + + public static bool IsAssignableFrom(Type type1, Type type2) + { +#if SIMPLE_JSON_TYPEINFO + return type1.GetTypeInfo().IsAssignableFrom(type2.GetTypeInfo()); +#else + return type1.IsAssignableFrom(type2); +#endif + } + + public static bool IsTypeDictionary(Type type) + { +#if SIMPLE_JSON_TYPEINFO + if (typeof(IDictionary<,>).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) + return true; + + if (!type.GetTypeInfo().IsGenericType) + return false; +#else + if (typeof(System.Collections.IDictionary).IsAssignableFrom(type)) + return true; + + if (!type.IsGenericType) + return false; +#endif + Type genericDefinition = type.GetGenericTypeDefinition(); + return genericDefinition == typeof(IDictionary<,>); + } + + public static bool IsNullableType(Type type) + { + return +#if SIMPLE_JSON_TYPEINFO + type.GetTypeInfo().IsGenericType +#else + type.IsGenericType +#endif + && type.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + public static object ToNullableType(object obj, Type nullableType) + { + return obj == null ? null : Convert.ChangeType(obj, Nullable.GetUnderlyingType(nullableType), CultureInfo.InvariantCulture); + } + + public static bool IsValueType(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().IsValueType; +#else + return type.IsValueType; +#endif + } + + public static IEnumerable GetConstructors(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().DeclaredConstructors; +#else + return type.GetConstructors(); +#endif + } + + public static ConstructorInfo GetConstructorInfo(Type type, params Type[] argsType) + { + IEnumerable constructorInfos = GetConstructors(type); + int i; + bool matches; + foreach (ConstructorInfo constructorInfo in constructorInfos) + { + ParameterInfo[] parameters = constructorInfo.GetParameters(); + if (argsType.Length != parameters.Length) + continue; + + i = 0; + matches = true; + foreach (ParameterInfo parameterInfo in constructorInfo.GetParameters()) + { + if (parameterInfo.ParameterType != argsType[i]) + { + matches = false; + break; + } + } + + if (matches) + return constructorInfo; + } + + return null; + } + + public static IEnumerable GetProperties(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().DeclaredProperties; +#else + return type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); +#endif + } + + public static IEnumerable GetFields(Type type) + { +#if SIMPLE_JSON_TYPEINFO + return type.GetTypeInfo().DeclaredFields; +#else + return type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); +#endif + } + + public static MethodInfo GetGetterMethodInfo(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_TYPEINFO + return propertyInfo.GetMethod; +#else + return propertyInfo.GetGetMethod(true); +#endif + } + + public static MethodInfo GetSetterMethodInfo(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_TYPEINFO + return propertyInfo.SetMethod; +#else + return propertyInfo.GetSetMethod(true); +#endif + } + + public static ConstructorDelegate GetContructor(ConstructorInfo constructorInfo) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION + return GetConstructorByReflection(constructorInfo); +#else + return GetConstructorByExpression(constructorInfo); +#endif + } + + public static ConstructorDelegate GetContructor(Type type, params Type[] argsType) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION + return GetConstructorByReflection(type, argsType); +#else + return GetConstructorByExpression(type, argsType); +#endif + } + + public static ConstructorDelegate GetConstructorByReflection(ConstructorInfo constructorInfo) + { + return delegate(object[] args) { return constructorInfo.Invoke(args); }; + } + + public static ConstructorDelegate GetConstructorByReflection(Type type, params Type[] argsType) + { + ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); + return constructorInfo == null ? null : GetConstructorByReflection(constructorInfo); + } + +#if !SIMPLE_JSON_NO_LINQ_EXPRESSION + + public static ConstructorDelegate GetConstructorByExpression(ConstructorInfo constructorInfo) + { + ParameterInfo[] paramsInfo = constructorInfo.GetParameters(); + ParameterExpression param = Expression.Parameter(typeof(object[]), "args"); + Expression[] argsExp = new Expression[paramsInfo.Length]; + for (int i = 0; i < paramsInfo.Length; i++) + { + Expression index = Expression.Constant(i); + Type paramType = paramsInfo[i].ParameterType; + Expression paramAccessorExp = Expression.ArrayIndex(param, index); + Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType); + argsExp[i] = paramCastExp; + } + NewExpression newExp = Expression.New(constructorInfo, argsExp); + Expression> lambda = Expression.Lambda>(newExp, param); + Func compiledLambda = lambda.Compile(); + return delegate(object[] args) { return compiledLambda(args); }; + } + + public static ConstructorDelegate GetConstructorByExpression(Type type, params Type[] argsType) + { + ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); + return constructorInfo == null ? null : GetConstructorByExpression(constructorInfo); + } + +#endif + + public static GetDelegate GetGetMethod(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION || PocketPC + return GetGetMethodByReflection(propertyInfo); +#else + return GetGetMethodByExpression(propertyInfo); +#endif + } + + public static GetDelegate GetGetMethod(FieldInfo fieldInfo) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION || PocketPC + return GetGetMethodByReflection(fieldInfo); +#else + return GetGetMethodByExpression(fieldInfo); +#endif + } + + public static GetDelegate GetGetMethodByReflection(PropertyInfo propertyInfo) + { + MethodInfo methodInfo = GetGetterMethodInfo(propertyInfo); + return delegate(object source) { return methodInfo.Invoke(source, EmptyObjects); }; + } + + public static GetDelegate GetGetMethodByReflection(FieldInfo fieldInfo) + { + return delegate(object source) { return fieldInfo.GetValue(source); }; + } + +#if !SIMPLE_JSON_NO_LINQ_EXPRESSION && !PocketPC + + public static GetDelegate GetGetMethodByExpression(PropertyInfo propertyInfo) + { + MethodInfo getMethodInfo = GetGetterMethodInfo(propertyInfo); + ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); + UnaryExpression instanceCast = (!IsValueType(propertyInfo.DeclaringType)) ? Expression.TypeAs(instance, propertyInfo.DeclaringType) : Expression.Convert(instance, propertyInfo.DeclaringType); + Func compiled = Expression.Lambda>(Expression.TypeAs(Expression.Call(instanceCast, getMethodInfo), typeof(object)), instance).Compile(); + return delegate(object source) { return compiled(source); }; + } + + public static GetDelegate GetGetMethodByExpression(FieldInfo fieldInfo) + { + ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); + MemberExpression member = Expression.Field(Expression.Convert(instance, fieldInfo.DeclaringType), fieldInfo); + GetDelegate compiled = Expression.Lambda(Expression.Convert(member, typeof(object)), instance).Compile(); + return delegate(object source) { return compiled(source); }; + } + +#endif + + public static SetDelegate GetSetMethod(PropertyInfo propertyInfo) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION + return GetSetMethodByReflection(propertyInfo); +#else + return GetSetMethodByExpression(propertyInfo); +#endif + } + + public static SetDelegate GetSetMethod(FieldInfo fieldInfo) + { +#if SIMPLE_JSON_NO_LINQ_EXPRESSION + return GetSetMethodByReflection(fieldInfo); +#else + return GetSetMethodByExpression(fieldInfo); +#endif + } + + public static SetDelegate GetSetMethodByReflection(PropertyInfo propertyInfo) + { + MethodInfo methodInfo = GetSetterMethodInfo(propertyInfo); + return delegate(object source, object value) { methodInfo.Invoke(source, new object[] { value }); }; + } + + public static SetDelegate GetSetMethodByReflection(FieldInfo fieldInfo) + { + return delegate(object source, object value) { fieldInfo.SetValue(source, value); }; + } + +#if !SIMPLE_JSON_NO_LINQ_EXPRESSION + + public static SetDelegate GetSetMethodByExpression(PropertyInfo propertyInfo) + { + MethodInfo setMethodInfo = GetSetterMethodInfo(propertyInfo); + ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); + ParameterExpression value = Expression.Parameter(typeof(object), "value"); + UnaryExpression instanceCast = (!IsValueType(propertyInfo.DeclaringType)) ? Expression.TypeAs(instance, propertyInfo.DeclaringType) : Expression.Convert(instance, propertyInfo.DeclaringType); + UnaryExpression valueCast = (!IsValueType(propertyInfo.PropertyType)) ? Expression.TypeAs(value, propertyInfo.PropertyType) : Expression.Convert(value, propertyInfo.PropertyType); + Action compiled = Expression.Lambda>(Expression.Call(instanceCast, setMethodInfo, valueCast), new ParameterExpression[] { instance, value }).Compile(); + return delegate(object source, object val) { compiled(source, val); }; + } + + public static SetDelegate GetSetMethodByExpression(FieldInfo fieldInfo) + { + ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); + ParameterExpression value = Expression.Parameter(typeof(object), "value"); + Action compiled = Expression.Lambda>( + Assign(Expression.Field(Expression.Convert(instance, fieldInfo.DeclaringType), fieldInfo), Expression.Convert(value, fieldInfo.FieldType)), instance, value).Compile(); + return delegate(object source, object val) { compiled(source, val); }; + } + + public static BinaryExpression Assign(Expression left, Expression right) + { +#if SIMPLE_JSON_TYPEINFO + return Expression.Assign(left, right); +#else + MethodInfo assign = typeof(Assigner<>).MakeGenericType(left.Type).GetMethod("Assign"); + BinaryExpression assignExpr = Expression.Add(left, right, assign); + return assignExpr; +#endif + } + + private static class Assigner + { + public static T Assign(ref T left, T right) + { + return (left = right); + } + } + +#endif + + public sealed class ThreadSafeDictionary : IDictionary + { + private readonly object _lock = new object(); + private readonly ThreadSafeDictionaryValueFactory _valueFactory; + private Dictionary _dictionary; + + public ThreadSafeDictionary(ThreadSafeDictionaryValueFactory valueFactory) + { + _valueFactory = valueFactory; + } + + private TValue Get(TKey key) + { + if (_dictionary == null) + return AddValue(key); + TValue value; + if (!_dictionary.TryGetValue(key, out value)) + return AddValue(key); + return value; + } + + private TValue AddValue(TKey key) + { + TValue value = _valueFactory(key); + lock (_lock) + { + if (_dictionary == null) + { + _dictionary = new Dictionary(); + _dictionary[key] = value; + } + else + { + TValue val; + if (_dictionary.TryGetValue(key, out val)) + return val; + Dictionary dict = new Dictionary(_dictionary); + dict[key] = value; + _dictionary = dict; + } + } + return value; + } + + public void Add(TKey key, TValue value) + { + throw new NotImplementedException(); + } + + public bool ContainsKey(TKey key) + { + return _dictionary.ContainsKey(key); + } + + public ICollection Keys + { + get { return _dictionary.Keys; } + } + + public bool Remove(TKey key) + { + throw new NotImplementedException(); + } + + public bool TryGetValue(TKey key, out TValue value) + { + value = this[key]; + return true; + } + + public ICollection Values + { + get { return _dictionary.Values; } + } + + public TValue this[TKey key] + { + get { return Get(key); } + set { throw new NotImplementedException(); } + } + + public void Add(KeyValuePair item) + { + throw new NotImplementedException(); + } + + public void Clear() + { + throw new NotImplementedException(); + } + + public bool Contains(KeyValuePair item) + { + throw new NotImplementedException(); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public int Count + { + get { return _dictionary.Count; } + } + + public bool IsReadOnly + { + get { throw new NotImplementedException(); } + } + + public bool Remove(KeyValuePair item) + { + throw new NotImplementedException(); + } + + public IEnumerator> GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + } + + } + } +} +// ReSharper restore LoopCanBeConvertedToQuery +// ReSharper restore RedundantExplicitArrayCreation +// ReSharper restore SuggestUseVarKeywordEvident diff --git a/Backup/RestSharp.Silverlight/Validation/Require.cs b/Backup/RestSharp.Silverlight/Validation/Require.cs new file mode 100644 index 000000000..63fa37376 --- /dev/null +++ b/Backup/RestSharp.Silverlight/Validation/Require.cs @@ -0,0 +1,37 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; + +namespace RestSharp.Validation +{ + /// + /// Helper methods for validating required values + /// + public class Require + { + /// + /// Require a parameter to not be null + /// + /// Name of the parameter + /// Value of the parameter + public static void Argument(string argumentName, object argumentValue) { + if (argumentValue == null) { + throw new ArgumentException("Argument cannot be null.", argumentName); + } + } + } +} diff --git a/Backup/RestSharp.Silverlight/Validation/Validate.cs b/Backup/RestSharp.Silverlight/Validation/Validate.cs new file mode 100644 index 000000000..b23ce975f --- /dev/null +++ b/Backup/RestSharp.Silverlight/Validation/Validate.cs @@ -0,0 +1,52 @@ +#region License +// Copyright 2010 John Sheehan +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; + +namespace RestSharp.Validation +{ + /// + /// Helper methods for validating values + /// + public class Validate + { + /// + /// Validate an integer value is between the specified values (exclusive of min/max) + /// + /// Value to validate + /// Exclusive minimum value + /// Exclusive maximum value + public static void IsBetween(int value, int min, int max) { + if (value < min || value > max) { + throw new ArgumentException(string.Format("Value ({0}) is not between {1} and {2}.", value, min, max)); + } + } + + /// + /// Validate a string length + /// + /// String to be validated + /// Maximum length of the string + public static void IsValidLength(string value, int maxSize) { + if (value == null) + return; + + if (value.Length > maxSize) { + throw new ArgumentException(string.Format("String is longer than max allowed size ({0}).", maxSize)); + } + } + } +} diff --git a/Backup/RestSharp.Silverlight/packages.config b/Backup/RestSharp.Silverlight/packages.config new file mode 100644 index 000000000..6b8deb9c9 --- /dev/null +++ b/Backup/RestSharp.Silverlight/packages.config @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Backup/RestSharp.sln b/Backup/RestSharp.sln new file mode 100644 index 000000000..ffe12b3a3 --- /dev/null +++ b/Backup/RestSharp.sln @@ -0,0 +1,123 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp", "RestSharp\RestSharp.csproj", "{2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.Tests", "RestSharp.Tests\RestSharp.Tests.csproj", "{1464E4AC-18BB-4F23-8A0B-68196F9E1871}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.IntegrationTests", "RestSharp.IntegrationTests\RestSharp.IntegrationTests.csproj", "{47D3EBB9-0300-4AF8-BAC5-740D51454A63}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.Silverlight", "RestSharp.Silverlight\RestSharp.Silverlight.csproj", "{11F84600-0978-48B9-A28F-63B3781E54B3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.WindowsPhone", "RestSharp.WindowsPhone\RestSharp.WindowsPhone.csproj", "{F4D48DF6-316E-4963-B5C1-59CA39B431B7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGet", "NuGet", "{E709A928-A45C-4622-A35C-CCD8EE44CA80}" + ProjectSection(SolutionItems) = preProject + package.cmd = package.cmd + readme.txt = readme.txt + restsharp.nuspec = restsharp.nuspec + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.Net4", "RestSharp.Net4\RestSharp.Net4.csproj", "{5FF943A5-260F-4042-B4CE-C4977BAD4EBB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{1B3F12F6-D32B-48C4-98D7-AB448EB78811}" + ProjectSection(SolutionItems) = preProject + .nuget\NuGet.exe = .nuget\NuGet.exe + .nuget\NuGet.targets = .nuget\NuGet.targets + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.Build", "RestSharp.Build\RestSharp.Build.csproj", "{CCC30138-3D68-44D8-AF1A-D22F769EE8DC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Meta", "Meta", "{C5B02FAA-6A0A-4BF9-BBD4-82FD2DCBF669}" + ProjectSection(SolutionItems) = preProject + CONTRIBUTING.markdown = CONTRIBUTING.markdown + README.markdown = README.markdown + readme.txt = readme.txt + releasenotes.markdown = releasenotes.markdown + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|x86.ActiveCfg = Debug|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Any CPU.Build.0 = Release|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|x86.ActiveCfg = Release|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|x86.ActiveCfg = Debug|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Any CPU.Build.0 = Release|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|x86.ActiveCfg = Release|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|x86.ActiveCfg = Debug|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Any CPU.Build.0 = Release|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|x86.ActiveCfg = Release|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|x86.ActiveCfg = Debug|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Any CPU.Build.0 = Release|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|x86.ActiveCfg = Release|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|x86.ActiveCfg = Debug|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Any CPU.Build.0 = Release|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|x86.ActiveCfg = Release|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|x86.ActiveCfg = Debug|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Any CPU.Build.0 = Release|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|x86.ActiveCfg = Release|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|x86.ActiveCfg = Debug|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Any CPU.Build.0 = Release|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|x86.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/RestSharp.Silverlight/RestSharp.Silverlight.csproj b/RestSharp.Silverlight/RestSharp.Silverlight.csproj index 0d272963f..c86523797 100644 --- a/RestSharp.Silverlight/RestSharp.Silverlight.csproj +++ b/RestSharp.Silverlight/RestSharp.Silverlight.csproj @@ -12,13 +12,18 @@ RestSharp.Silverlight RestSharp.Silverlight Silverlight - v4.0 + v5.0 $(TargetFrameworkVersion) false true true ..\ true + + + + + 4.0 - - v3.5 - - - true - full - false - Bin\Debug - DEBUG;TRACE;SILVERLIGHT - true - true - prompt - 4 - Bin\Debug\RestSharp.Silverlight.xml - - - pdbonly - true - Bin\Release - TRACE;SILVERLIGHT - true - true - prompt - 4 - Bin\Release\RestSharp.Silverlight.xml - 1591,1573,1658,1584,1574,1572 - true - - - - - - - - - - - - - - - - - Authenticators\HttpBasicAuthenticator.cs - - - Authenticators\IAuthenticator.cs - - - Authenticators\NtlmAuthenticator.cs - - - Authenticators\OAuth1Authenticator.cs - - - Authenticators\OAuth2Authenticator.cs - - - Authenticators\OAuth\Extensions\CollectionExtensions.cs - - - Authenticators\OAuth\Extensions\OAuthExtensions.cs - - - Authenticators\OAuth\Extensions\StringExtensions.cs - - - Authenticators\OAuth\Extensions\TimeExtensions.cs - - - Authenticators\OAuth\HttpPostParameter.cs - - - Authenticators\OAuth\HttpPostParameterType.cs - - - Authenticators\OAuth\OAuthParameterHandling.cs - - - Authenticators\OAuth\OAuthSignatureMethod.cs - - - Authenticators\OAuth\OAuthSignatureTreatment.cs - - - Authenticators\OAuth\OAuthTools.cs - - - Authenticators\OAuth\OAuthType.cs - - - Authenticators\OAuth\OAuthWebQueryInfo.cs - - - Authenticators\OAuth\OAuthWorkflow.cs - - - Authenticators\OAuth\WebPair.cs - - - Authenticators\OAuth\WebPairCollection.cs - - - Authenticators\OAuth\WebParameter.cs - - - Authenticators\OAuth\WebParameterCollection.cs - - - Authenticators\SimpleAuthenticator.cs - - - Deserializers\DeserializeAsAttribute.cs - - - Deserializers\DotNetXmlDeserializer.cs - - - Deserializers\IDeserializer.cs - - - Deserializers\JsonDeserializer.cs - - - Deserializers\XmlAttributeDeserializer.cs - - - Deserializers\XmlDeserializer.cs - - - Enum.cs - - - Extensions\MiscExtensions.cs - - - Extensions\ReflectionExtensions.cs - - - Extensions\ResponseExtensions.cs - - - Extensions\StringExtensions.cs - - - Extensions\XmlExtensions.cs - - - FileParameter.cs - - - Http.Async.cs - - - Http.cs - - - HttpCookie.cs - - - HttpFile.cs - - - HttpHeader.cs - - - HttpParameter.cs - - - HttpResponse.cs - - - IHttp.cs - - - IHttpFactory.cs - - - IHttpResponse.cs - - - IRestClient.cs - - - IRestRequest.cs - - - IRestResponse.cs - - - Parameter.cs - - - RestClient.Async.cs - - - RestClient.cs - - - RestClientExtensions.cs - - - RestRequest.cs - - - RestResponse.cs - - - Serializers\DotNetXmlSerializer.cs - - - Serializers\ISerializer.cs - - - Serializers\JsonSerializer.cs - - - Serializers\SerializeAsAttribute.cs - - - Serializers\XmlSerializer.cs - - - SharedAssemblyInfo.cs - - - SimpleJson.cs - - - Validation\Require.cs - - - Validation\Validate.cs - - - RestResponseCookie.cs - - - RestRequestAsyncHandle.cs - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Serializers/DotNetXmlSerializer.cs b/Backup/RestSharp.Silverlight/Serializers/DotNetXmlSerializer.cs deleted file mode 100644 index 8b3d2bed2..000000000 --- a/Backup/RestSharp.Silverlight/Serializers/DotNetXmlSerializer.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System.IO; -using System.Text; -using System.Xml.Serialization; - -namespace RestSharp.Serializers -{ - /// - /// Wrapper for System.Xml.Serialization.XmlSerializer. - /// - public class DotNetXmlSerializer : ISerializer - { - /// - /// Default constructor, does not specify namespace - /// - public DotNetXmlSerializer() - { - ContentType = "application/xml"; - Encoding = Encoding.UTF8; - } - - /// - /// Specify the namespaced to be used when serializing - /// - /// XML namespace - public DotNetXmlSerializer(string @namespace) : this() - { - Namespace = @namespace; - } - - /// - /// Serialize the object as XML - /// - /// Object to serialize - /// XML as string - public string Serialize(object obj) - { - var ns = new XmlSerializerNamespaces(); - ns.Add(string.Empty, Namespace); - var serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType()); - var writer = new EncodingStringWriter(Encoding); - serializer.Serialize(writer, obj, ns); - - return writer.ToString(); - } - - /// - /// Name of the root element to use when serializing - /// - public string RootElement { get; set; } - - /// - /// XML namespace to use when serializing - /// - public string Namespace { get; set; } - - /// - /// Format string to use when serializing dates - /// - public string DateFormat { get; set; } - - /// - /// Content type for serialized content - /// - public string ContentType { get; set; } - - /// - /// Encoding for serialized content - /// - public Encoding Encoding { get; set; } - - /// - /// Need to subclass StringWriter in order to override Encoding - /// - private class EncodingStringWriter : StringWriter - { - private readonly Encoding encoding; - - public EncodingStringWriter(Encoding encoding) - { - this.encoding = encoding; - } - - public override Encoding Encoding - { - get { return encoding; } - } - } - } -} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Serializers/ISerializer.cs b/Backup/RestSharp.Silverlight/Serializers/ISerializer.cs deleted file mode 100644 index 0ca2a4dc3..000000000 --- a/Backup/RestSharp.Silverlight/Serializers/ISerializer.cs +++ /dev/null @@ -1,27 +0,0 @@ -#region License -// Copyright 2010 John Sheehan -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -namespace RestSharp.Serializers -{ - public interface ISerializer - { - string Serialize(object obj); - string RootElement { get; set; } - string Namespace { get; set; } - string DateFormat { get; set; } - string ContentType { get; set; } - } -} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Serializers/JsonSerializer.cs b/Backup/RestSharp.Silverlight/Serializers/JsonSerializer.cs deleted file mode 100644 index 191e7c4ca..000000000 --- a/Backup/RestSharp.Silverlight/Serializers/JsonSerializer.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.IO; - -namespace RestSharp.Serializers -{ - /// - /// Default JSON serializer for request bodies - /// Doesn't currently use the SerializeAs attribute, defers to Newtonsoft's attributes - /// - public class JsonSerializer : ISerializer - { - /// - /// Default serializer - /// - public JsonSerializer() - { - ContentType = "application/json"; - } - - /// - /// Serialize the object as JSON - /// - /// Object to serialize - /// JSON as String - public string Serialize(object obj) - { - return SimpleJson.SerializeObject(obj); - } - - /// - /// Unused for JSON Serialization - /// - public string DateFormat { get; set; } - /// - /// Unused for JSON Serialization - /// - public string RootElement { get; set; } - /// - /// Unused for JSON Serialization - /// - public string Namespace { get; set; } - /// - /// Content type for serialized content - /// - public string ContentType { get; set; } - } -} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/Serializers/SerializeAsAttribute.cs b/Backup/RestSharp.Silverlight/Serializers/SerializeAsAttribute.cs deleted file mode 100644 index 98a89a74d..000000000 --- a/Backup/RestSharp.Silverlight/Serializers/SerializeAsAttribute.cs +++ /dev/null @@ -1,92 +0,0 @@ -#region License -// Copyright 2010 John Sheehan -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -using System; -using RestSharp.Extensions; -using System.Globalization; - -namespace RestSharp.Serializers -{ - /// - /// Allows control how class and property names and values are serialized by XmlSerializer - /// Currently not supported with the JsonSerializer - /// When specified at the property level the class-level specification is overridden - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] - public sealed class SerializeAsAttribute : Attribute - { - public SerializeAsAttribute() { - NameStyle = NameStyle.AsIs; - Index = int.MaxValue; - Culture = CultureInfo.InvariantCulture; - } - - /// - /// The name to use for the serialized element - /// - public string Name { get; set; } - - /// - /// Sets the value to be serialized as an Attribute instead of an Element - /// - public bool Attribute { get; set; } - - /// - /// The culture to use when serializing - /// - public CultureInfo Culture { get; set; } - - /// - /// Transforms the casing of the name based on the selected value. - /// - public NameStyle NameStyle { get; set; } - - /// - /// The order to serialize the element. Default is int.MaxValue. - /// - public int Index { get; set; } - - /// - /// Called by the attribute when NameStyle is speficied - /// - /// The string to transform - /// String - public string TransformName(string input) { - var name = Name ?? input; - switch (NameStyle) { - case NameStyle.CamelCase: - return name.ToCamelCase(Culture); - case NameStyle.PascalCase: - return name.ToPascalCase(Culture); - case NameStyle.LowerCase: - return name.ToLower(); - } - - return input; - } - } - - /// - /// Options for transforming casing of element names - /// - public enum NameStyle - { - AsIs, - CamelCase, - LowerCase, - PascalCase - } -} diff --git a/Backup/RestSharp.Silverlight/Serializers/XmlSerializer.cs b/Backup/RestSharp.Silverlight/Serializers/XmlSerializer.cs deleted file mode 100644 index a6fcca2d6..000000000 --- a/Backup/RestSharp.Silverlight/Serializers/XmlSerializer.cs +++ /dev/null @@ -1,245 +0,0 @@ -#region License -// Copyright 2010 John Sheehan -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -using System; -using System.Collections; -using System.Globalization; -using System.Linq; -using System.Xml.Linq; -using RestSharp.Extensions; - -namespace RestSharp.Serializers -{ - /// - /// Default XML Serializer - /// - public class XmlSerializer : ISerializer - { - /// - /// Default constructor, does not specify namespace - /// - public XmlSerializer() { - ContentType = "text/xml"; - } - - /// - /// Specify the namespaced to be used when serializing - /// - /// XML namespace - public XmlSerializer(string @namespace) { - Namespace = @namespace; - ContentType = "text/xml"; - } - - /// - /// Serialize the object as XML - /// - /// Object to serialize - /// XML as string - public string Serialize(object obj) { - var doc = new XDocument(); - - var t = obj.GetType(); - var name = t.Name; - - var options = t.GetAttribute(); - if (options != null) { - name = options.TransformName(options.Name ?? name); - } - - var root = new XElement(name.AsNamespaced(Namespace)); - - if (obj is IList) - { - var itemTypeName = ""; - foreach (var item in (IList)obj) - { - var type = item.GetType(); - var opts = type.GetAttribute(); - if (opts != null) - { - itemTypeName = opts.TransformName(opts.Name ?? name); - } - if (itemTypeName == "") - { - itemTypeName = type.Name; - } - var instance = new XElement(itemTypeName.AsNamespaced(Namespace)); - Map(instance, item); - root.Add(instance); - } - } - else - Map(root, obj); - - if (RootElement.HasValue()) { - var wrapper = new XElement(RootElement.AsNamespaced(Namespace), root); - doc.Add(wrapper); - } - else { - doc.Add(root); - } - - return doc.ToString(); - } - - private void Map(XElement root, object obj) { - var objType = obj.GetType(); - - var props = from p in objType.GetProperties() - let indexAttribute = p.GetAttribute() - where p.CanRead && p.CanWrite - orderby indexAttribute == null ? int.MaxValue : indexAttribute.Index - select p; - - var globalOptions = objType.GetAttribute(); - - foreach (var prop in props) { - var name = prop.Name; - var rawValue = prop.GetValue(obj, null); - - if (rawValue == null) { - continue; - } - - var value = GetSerializedValue(rawValue); - var propType = prop.PropertyType; - - var useAttribute = false; - var settings = prop.GetAttribute(); - if (settings != null) { - name = settings.Name.HasValue() ? settings.Name : name; - useAttribute = settings.Attribute; - } - - var options = prop.GetAttribute(); - if (options != null) { - name = options.TransformName(name); - } - else if (globalOptions != null) { - name = globalOptions.TransformName(name); - } - - var nsName = name.AsNamespaced(Namespace); - var element = new XElement(nsName); - - if (propType.IsPrimitive || propType.IsValueType || propType == typeof(string)) { - if (useAttribute) { - root.Add(new XAttribute(name, value)); - continue; - } - - element.Value = value; - } - else if (rawValue is IList) { - var itemTypeName = ""; - foreach (var item in (IList)rawValue) { - if (itemTypeName == "") - { - var type = item.GetType(); - var setting = type.GetAttribute(); - itemTypeName = setting != null && setting.Name.HasValue() - ? setting.Name - : type.Name; - } - var instance = new XElement(itemTypeName.AsNamespaced(Namespace)); - Map(instance, item); - element.Add(instance); - } - } - else { - Map(element, rawValue); - } - - root.Add(element); - } - } - - private string GetSerializedValue(object obj) { - var output = obj; - - if (obj is DateTime && DateFormat.HasValue()) - { - output = ((DateTime) obj).ToString(DateFormat, CultureInfo.InvariantCulture); - } - if (obj is bool) - { - output = ((bool)obj).ToString(CultureInfo.InvariantCulture).ToLower(); - } - if (IsNumeric(obj)) - { - return SerializeNumber(obj); - } - - return output.ToString(); - } - - static string SerializeNumber(object number) - { - if (number is long) - return ((long)number).ToString(CultureInfo.InvariantCulture); - else if (number is ulong) - return ((ulong)number).ToString(CultureInfo.InvariantCulture); - else if (number is int) - return ((int)number).ToString(CultureInfo.InvariantCulture); - else if (number is uint) - return ((uint)number).ToString(CultureInfo.InvariantCulture); - else if (number is decimal) - return ((decimal)number).ToString(CultureInfo.InvariantCulture); - else if (number is float) - return ((float)number).ToString(CultureInfo.InvariantCulture); - else - return (Convert.ToDouble(number, CultureInfo.InvariantCulture).ToString("r", CultureInfo.InvariantCulture)); - } - - /// - /// Determines if a given object is numeric in any way - /// (can be integer, double, null, etc). - /// - static bool IsNumeric(object value) - { - if (value is sbyte) return true; - if (value is byte) return true; - if (value is short) return true; - if (value is ushort) return true; - if (value is int) return true; - if (value is uint) return true; - if (value is long) return true; - if (value is ulong) return true; - if (value is float) return true; - if (value is double) return true; - if (value is decimal) return true; - return false; - } - - /// - /// Name of the root element to use when serializing - /// - public string RootElement { get; set; } - /// - /// XML namespace to use when serializing - /// - public string Namespace { get; set; } - /// - /// Format string to use when serializing dates - /// - public string DateFormat { get; set; } - /// - /// Content type for serialized content - /// - public string ContentType { get; set; } - } -} \ No newline at end of file diff --git a/Backup/RestSharp.Silverlight/SharedAssemblyInfo.cs b/Backup/RestSharp.Silverlight/SharedAssemblyInfo.cs deleted file mode 100644 index c7f7ed61b..000000000 --- a/Backup/RestSharp.Silverlight/SharedAssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyDescription("Simple REST and HTTP API Client")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("John Sheehan, RestSharp Community")] -[assembly: AssemblyProduct("RestSharp")] -[assembly: AssemblyCopyright("Copyright © RestSharp Project 2009-2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: CLSCompliant(true)] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion(SharedAssembylInfo.Version + ".0")] -[assembly: AssemblyInformationalVersion(SharedAssembylInfo.Version)] - -#if !PocketPC -[assembly: AssemblyFileVersion(SharedAssembylInfo.Version + ".0")] -#endif - -class SharedAssembylInfo -{ - public const string Version = "104.4.0"; -} diff --git a/Backup/RestSharp.Silverlight/SimpleJson.cs b/Backup/RestSharp.Silverlight/SimpleJson.cs deleted file mode 100644 index e5fc1066f..000000000 --- a/Backup/RestSharp.Silverlight/SimpleJson.cs +++ /dev/null @@ -1,2094 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2011, The Outercurve Foundation. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.opensource.org/licenses/mit-license.php -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Nathan Totten (ntotten.com), Jim Zimmerman (jimzimmerman.com) and Prabir Shrestha (prabir.me) -// https://github.com/facebook-csharp-sdk/simple-json -//----------------------------------------------------------------------- - -// VERSION: 0.26.0 - -// NOTE: uncomment the following line to make SimpleJson class internal. -//#define SIMPLE_JSON_INTERNAL - -// NOTE: uncomment the following line to make JsonArray and JsonObject class internal. -//#define SIMPLE_JSON_OBJARRAYINTERNAL - -// NOTE: uncomment the following line to enable dynamic support. -//#define SIMPLE_JSON_DYNAMIC - -// NOTE: uncomment the following line to enable DataContract support. -//#define SIMPLE_JSON_DATACONTRACT - -// NOTE: uncomment the following line to disable linq expressions/compiled lambda (better performance) instead of method.invoke(). -// define if you are using .net framework <= 3.0 or < WP7.5 -//#define SIMPLE_JSON_NO_LINQ_EXPRESSION - -// NOTE: uncomment the following line if you are compiling under Window Metro style application/library. -// usually already defined in properties -//#define NETFX_CORE; - -// If you are targetting WinStore, WP8 and NET4.5+ PCL make sure to #define SIMPLE_JSON_TYPEINFO; - -// original json parsing code from http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html - -#if NETFX_CORE -#define SIMPLE_JSON_TYPEINFO -#endif - -using System; -using System.CodeDom.Compiler; -using System.Collections; -using System.Collections.Generic; -#if !SIMPLE_JSON_NO_LINQ_EXPRESSION -using System.Linq.Expressions; -#endif -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; -#if SIMPLE_JSON_DYNAMIC -using System.Dynamic; -#endif -using System.Globalization; -using System.Reflection; -using System.Runtime.Serialization; -using System.Text; -using RestSharp.Reflection; - -// ReSharper disable LoopCanBeConvertedToQuery -// ReSharper disable RedundantExplicitArrayCreation -// ReSharper disable SuggestUseVarKeywordEvident -namespace RestSharp -{ - /// - /// Represents the json array. - /// - [GeneratedCode("simple-json", "1.0.0")] - [EditorBrowsable(EditorBrowsableState.Never)] - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] -#if SIMPLE_JSON_OBJARRAYINTERNAL - internal -#else - public -#endif - class JsonArray : List - { - /// - /// Initializes a new instance of the class. - /// - public JsonArray() { } - - /// - /// Initializes a new instance of the class. - /// - /// The capacity of the json array. - public JsonArray(int capacity) : base(capacity) { } - - /// - /// The json representation of the array. - /// - /// The json representation of the array. - public override string ToString() - { - return SimpleJson.SerializeObject(this) ?? string.Empty; - } - } - - /// - /// Represents the json object. - /// - [GeneratedCode("simple-json", "1.0.0")] - [EditorBrowsable(EditorBrowsableState.Never)] - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] -#if SIMPLE_JSON_OBJARRAYINTERNAL - internal -#else - public -#endif - class JsonObject : -#if SIMPLE_JSON_DYNAMIC - DynamicObject, -#endif - IDictionary - { - /// - /// The internal member dictionary. - /// - private readonly Dictionary _members; - - /// - /// Initializes a new instance of . - /// - public JsonObject() - { - _members = new Dictionary(); - } - - /// - /// Initializes a new instance of . - /// - /// The implementation to use when comparing keys, or null to use the default for the type of the key. - public JsonObject(IEqualityComparer comparer) - { - _members = new Dictionary(comparer); - } - - /// - /// Gets the at the specified index. - /// - /// - public object this[int index] - { - get { return GetAtIndex(_members, index); } - } - - internal static object GetAtIndex(IDictionary obj, int index) - { - if (obj == null) - throw new ArgumentNullException("obj"); - if (index >= obj.Count) - throw new ArgumentOutOfRangeException("index"); - int i = 0; - foreach (KeyValuePair o in obj) - if (i++ == index) return o.Value; - return null; - } - - /// - /// Adds the specified key. - /// - /// The key. - /// The value. - public void Add(string key, object value) - { - _members.Add(key, value); - } - - /// - /// Determines whether the specified key contains key. - /// - /// The key. - /// - /// true if the specified key contains key; otherwise, false. - /// - public bool ContainsKey(string key) - { - return _members.ContainsKey(key); - } - - /// - /// Gets the keys. - /// - /// The keys. - public ICollection Keys - { - get { return _members.Keys; } - } - - /// - /// Removes the specified key. - /// - /// The key. - /// - public bool Remove(string key) - { - return _members.Remove(key); - } - - /// - /// Tries the get value. - /// - /// The key. - /// The value. - /// - public bool TryGetValue(string key, out object value) - { - return _members.TryGetValue(key, out value); - } - - /// - /// Gets the values. - /// - /// The values. - public ICollection Values - { - get { return _members.Values; } - } - - /// - /// Gets or sets the with the specified key. - /// - /// - public object this[string key] - { - get { return _members[key]; } - set { _members[key] = value; } - } - - /// - /// Adds the specified item. - /// - /// The item. - public void Add(KeyValuePair item) - { - _members.Add(item.Key, item.Value); - } - - /// - /// Clears this instance. - /// - public void Clear() - { - _members.Clear(); - } - - /// - /// Determines whether [contains] [the specified item]. - /// - /// The item. - /// - /// true if [contains] [the specified item]; otherwise, false. - /// - public bool Contains(KeyValuePair item) - { - return _members.ContainsKey(item.Key) && _members[item.Key] == item.Value; - } - - /// - /// Copies to. - /// - /// The array. - /// Index of the array. - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - if (array == null) throw new ArgumentNullException("array"); - int num = Count; - foreach (KeyValuePair kvp in this) - { - array[arrayIndex++] = kvp; - if (--num <= 0) - return; - } - } - - /// - /// Gets the count. - /// - /// The count. - public int Count - { - get { return _members.Count; } - } - - /// - /// Gets a value indicating whether this instance is read only. - /// - /// - /// true if this instance is read only; otherwise, false. - /// - public bool IsReadOnly - { - get { return false; } - } - - /// - /// Removes the specified item. - /// - /// The item. - /// - public bool Remove(KeyValuePair item) - { - return _members.Remove(item.Key); - } - - /// - /// Gets the enumerator. - /// - /// - public IEnumerator> GetEnumerator() - { - return _members.GetEnumerator(); - } - - /// - /// Returns an enumerator that iterates through a collection. - /// - /// - /// An object that can be used to iterate through the collection. - /// - IEnumerator IEnumerable.GetEnumerator() - { - return _members.GetEnumerator(); - } - - /// - /// Returns a json that represents the current . - /// - /// - /// A json that represents the current . - /// - public override string ToString() - { - return SimpleJson.SerializeObject(this); - } - -#if SIMPLE_JSON_DYNAMIC - /// - /// Provides implementation for type conversion operations. Classes derived from the class can override this method to specify dynamic behavior for operations that convert an object from one type to another. - /// - /// Provides information about the conversion operation. The binder.Type property provides the type to which the object must be converted. For example, for the statement (String)sampleObject in C# (CType(sampleObject, Type) in Visual Basic), where sampleObject is an instance of the class derived from the class, binder.Type returns the type. The binder.Explicit property provides information about the kind of conversion that occurs. It returns true for explicit conversion and false for implicit conversion. - /// The result of the type conversion operation. - /// - /// Alwasy returns true. - /// - public override bool TryConvert(ConvertBinder binder, out object result) - { - // - if (binder == null) - throw new ArgumentNullException("binder"); - // - Type targetType = binder.Type; - - if ((targetType == typeof(IEnumerable)) || - (targetType == typeof(IEnumerable>)) || - (targetType == typeof(IDictionary)) || - (targetType == typeof(IDictionary))) - { - result = this; - return true; - } - - return base.TryConvert(binder, out result); - } - - /// - /// Provides the implementation for operations that delete an object member. This method is not intended for use in C# or Visual Basic. - /// - /// Provides information about the deletion. - /// - /// Alwasy returns true. - /// - public override bool TryDeleteMember(DeleteMemberBinder binder) - { - // - if (binder == null) - throw new ArgumentNullException("binder"); - // - return _members.Remove(binder.Name); - } - - /// - /// Provides the implementation for operations that get a value by index. Classes derived from the class can override this method to specify dynamic behavior for indexing operations. - /// - /// Provides information about the operation. - /// The indexes that are used in the operation. For example, for the sampleObject[3] operation in C# (sampleObject(3) in Visual Basic), where sampleObject is derived from the DynamicObject class, is equal to 3. - /// The result of the index operation. - /// - /// Alwasy returns true. - /// - public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) - { - if (indexes == null) throw new ArgumentNullException("indexes"); - if (indexes.Length == 1) - { - result = ((IDictionary)this)[(string)indexes[0]]; - return true; - } - result = null; - return true; - } - - /// - /// Provides the implementation for operations that get member values. Classes derived from the class can override this method to specify dynamic behavior for operations such as getting a value for a property. - /// - /// Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive. - /// The result of the get operation. For example, if the method is called for a property, you can assign the property value to . - /// - /// Alwasy returns true. - /// - public override bool TryGetMember(GetMemberBinder binder, out object result) - { - object value; - if (_members.TryGetValue(binder.Name, out value)) - { - result = value; - return true; - } - result = null; - return true; - } - - /// - /// Provides the implementation for operations that set a value by index. Classes derived from the class can override this method to specify dynamic behavior for operations that access objects by a specified index. - /// - /// Provides information about the operation. - /// The indexes that are used in the operation. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the class, is equal to 3. - /// The value to set to the object that has the specified index. For example, for the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject is derived from the class, is equal to 10. - /// - /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown. - /// - public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) - { - if (indexes == null) throw new ArgumentNullException("indexes"); - if (indexes.Length == 1) - { - ((IDictionary)this)[(string)indexes[0]] = value; - return true; - } - return base.TrySetIndex(binder, indexes, value); - } - - /// - /// Provides the implementation for operations that set member values. Classes derived from the class can override this method to specify dynamic behavior for operations such as setting a value for a property. - /// - /// Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member to which the value is being assigned. For example, for the statement sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive. - /// The value to set to the member. For example, for sampleObject.SampleProperty = "Test", where sampleObject is an instance of the class derived from the class, the is "Test". - /// - /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.) - /// - public override bool TrySetMember(SetMemberBinder binder, object value) - { - // - if (binder == null) - throw new ArgumentNullException("binder"); - // - _members[binder.Name] = value; - return true; - } - - /// - /// Returns the enumeration of all dynamic member names. - /// - /// - /// A sequence that contains dynamic member names. - /// - public override IEnumerable GetDynamicMemberNames() - { - foreach (var key in Keys) - yield return key; - } -#endif - } -} - -namespace RestSharp -{ - /// - /// This class encodes and decodes JSON strings. - /// Spec. details, see http://www.json.org/ - /// - /// JSON uses Arrays and Objects. These correspond here to the datatypes JsonArray(IList<object>) and JsonObject(IDictionary<string,object>). - /// All numbers are parsed to doubles. - /// - [GeneratedCode("simple-json", "1.0.0")] -#if SIMPLE_JSON_INTERNAL - internal -#else - public -#endif - static class SimpleJson - { - private const int TOKEN_NONE = 0; - private const int TOKEN_CURLY_OPEN = 1; - private const int TOKEN_CURLY_CLOSE = 2; - private const int TOKEN_SQUARED_OPEN = 3; - private const int TOKEN_SQUARED_CLOSE = 4; - private const int TOKEN_COLON = 5; - private const int TOKEN_COMMA = 6; - private const int TOKEN_STRING = 7; - private const int TOKEN_NUMBER = 8; - private const int TOKEN_TRUE = 9; - private const int TOKEN_FALSE = 10; - private const int TOKEN_NULL = 11; - private const int BUILDER_CAPACITY = 2000; - - /// - /// Parses the string json into a value - /// - /// A JSON string. - /// An IList<object>, a IDictionary<string,object>, a double, a string, null, true, or false - public static object DeserializeObject(string json) - { - object obj; - if (TryDeserializeObject(json, out obj)) - return obj; - throw new SerializationException("Invalid JSON string"); - } - - /// - /// Try parsing the json string into a value. - /// - /// - /// A JSON string. - /// - /// - /// The object. - /// - /// - /// Returns true if successfull otherwise false. - /// - [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] - public static bool TryDeserializeObject(string json, out object obj) - { - bool success = true; - if (json != null) - { - char[] charArray = json.ToCharArray(); - int index = 0; - obj = ParseValue(charArray, ref index, ref success); - } - else - obj = null; - - return success; - } - - public static object DeserializeObject(string json, Type type, IJsonSerializerStrategy jsonSerializerStrategy) - { - object jsonObject = DeserializeObject(json); - return type == null || jsonObject != null && ReflectionUtils.IsAssignableFrom(jsonObject.GetType(), type) - ? jsonObject - : (jsonSerializerStrategy ?? CurrentJsonSerializerStrategy).DeserializeObject(jsonObject, type); - } - - public static object DeserializeObject(string json, Type type) - { - return DeserializeObject(json, type, null); - } - - public static T DeserializeObject(string json, IJsonSerializerStrategy jsonSerializerStrategy) - { - return (T)DeserializeObject(json, typeof(T), jsonSerializerStrategy); - } - - public static T DeserializeObject(string json) - { - return (T)DeserializeObject(json, typeof(T), null); - } - - /// - /// Converts a IDictionary<string,object> / IList<object> object into a JSON string - /// - /// A IDictionary<string,object> / IList<object> - /// Serializer strategy to use - /// A JSON encoded string, or null if object 'json' is not serializable - public static string SerializeObject(object json, IJsonSerializerStrategy jsonSerializerStrategy) - { - StringBuilder builder = new StringBuilder(BUILDER_CAPACITY); - bool success = SerializeValue(jsonSerializerStrategy, json, builder); - return (success ? builder.ToString() : null); - } - - public static string SerializeObject(object json) - { - return SerializeObject(json, CurrentJsonSerializerStrategy); - } - - public static string EscapeToJavascriptString(string jsonString) - { - if (string.IsNullOrEmpty(jsonString)) - return jsonString; - - StringBuilder sb = new StringBuilder(); - char c; - - for (int i = 0; i < jsonString.Length; ) - { - c = jsonString[i++]; - - if (c == '\\') - { - int remainingLength = jsonString.Length - i; - if (remainingLength >= 2) - { - char lookahead = jsonString[i]; - if (lookahead == '\\') - { - sb.Append('\\'); - ++i; - } - else if (lookahead == '"') - { - sb.Append("\""); - ++i; - } - else if (lookahead == 't') - { - sb.Append('\t'); - ++i; - } - else if (lookahead == 'b') - { - sb.Append('\b'); - ++i; - } - else if (lookahead == 'n') - { - sb.Append('\n'); - ++i; - } - else if (lookahead == 'r') - { - sb.Append('\r'); - ++i; - } - } - } - else - { - sb.Append(c); - } - } - return sb.ToString(); - } - - static IDictionary ParseObject(char[] json, ref int index, ref bool success) - { - IDictionary table = new JsonObject(); - int token; - - // { - NextToken(json, ref index); - - bool done = false; - while (!done) - { - token = LookAhead(json, index); - if (token == TOKEN_NONE) - { - success = false; - return null; - } - else if (token == TOKEN_COMMA) - NextToken(json, ref index); - else if (token == TOKEN_CURLY_CLOSE) - { - NextToken(json, ref index); - return table; - } - else - { - // name - string name = ParseString(json, ref index, ref success); - if (!success) - { - success = false; - return null; - } - // : - token = NextToken(json, ref index); - if (token != TOKEN_COLON) - { - success = false; - return null; - } - // value - object value = ParseValue(json, ref index, ref success); - if (!success) - { - success = false; - return null; - } - table[name] = value; - } - } - return table; - } - - static JsonArray ParseArray(char[] json, ref int index, ref bool success) - { - JsonArray array = new JsonArray(); - - // [ - NextToken(json, ref index); - - bool done = false; - while (!done) - { - int token = LookAhead(json, index); - if (token == TOKEN_NONE) - { - success = false; - return null; - } - else if (token == TOKEN_COMMA) - NextToken(json, ref index); - else if (token == TOKEN_SQUARED_CLOSE) - { - NextToken(json, ref index); - break; - } - else - { - object value = ParseValue(json, ref index, ref success); - if (!success) - return null; - array.Add(value); - } - } - return array; - } - - static object ParseValue(char[] json, ref int index, ref bool success) - { - switch (LookAhead(json, index)) - { - case TOKEN_STRING: - return ParseString(json, ref index, ref success); - case TOKEN_NUMBER: - return ParseNumber(json, ref index, ref success); - case TOKEN_CURLY_OPEN: - return ParseObject(json, ref index, ref success); - case TOKEN_SQUARED_OPEN: - return ParseArray(json, ref index, ref success); - case TOKEN_TRUE: - NextToken(json, ref index); - return true; - case TOKEN_FALSE: - NextToken(json, ref index); - return false; - case TOKEN_NULL: - NextToken(json, ref index); - return null; - case TOKEN_NONE: - break; - } - success = false; - return null; - } - - static string ParseString(char[] json, ref int index, ref bool success) - { - StringBuilder s = new StringBuilder(BUILDER_CAPACITY); - char c; - - EatWhitespace(json, ref index); - - // " - c = json[index++]; - bool complete = false; - while (!complete) - { - if (index == json.Length) - break; - - c = json[index++]; - if (c == '"') - { - complete = true; - break; - } - else if (c == '\\') - { - if (index == json.Length) - break; - c = json[index++]; - if (c == '"') - s.Append('"'); - else if (c == '\\') - s.Append('\\'); - else if (c == '/') - s.Append('/'); - else if (c == 'b') - s.Append('\b'); - else if (c == 'f') - s.Append('\f'); - else if (c == 'n') - s.Append('\n'); - else if (c == 'r') - s.Append('\r'); - else if (c == 't') - s.Append('\t'); - else if (c == 'u') - { - int remainingLength = json.Length - index; - if (remainingLength >= 4) - { - // parse the 32 bit hex into an integer codepoint - uint codePoint; - -#if PocketPC - try { - codePoint = UInt32.Parse(new string(json, index, 4), NumberStyles.HexNumber); - } catch (Exception ex) { - return ""; - } -#else - if (!(success = UInt32.TryParse(new string(json, index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codePoint))) - return ""; -#endif - // convert the integer codepoint to a unicode char and add to string - if (0xD800 <= codePoint && codePoint <= 0xDBFF) // if high surrogate - { - index += 4; // skip 4 chars - remainingLength = json.Length - index; - if (remainingLength >= 6) - { - uint lowCodePoint = 0; - -#if PocketPC - bool lowCodePointPassed = false; - try { - lowCodePoint = UInt32.Parse(new string(json, index + 2, 4), NumberStyles.HexNumber); - lowCodePointPassed = true; - } catch (Exception) { } - if (new string(json, index, 2) == "\\u" && lowCodePointPassed) -#else - if (new string(json, index, 2) == "\\u" && UInt32.TryParse(new string(json, index + 2, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out lowCodePoint)) -#endif - { - if (0xDC00 <= lowCodePoint && lowCodePoint <= 0xDFFF) // if low surrogate - { - s.Append((char)codePoint); - s.Append((char)lowCodePoint); - index += 6; // skip 6 chars - continue; - } - } - } - success = false; // invalid surrogate pair - return ""; - } - s.Append(ConvertFromUtf32((int)codePoint)); - // skip 4 chars - index += 4; - } - else - break; - } - } - else - s.Append(c); - } - if (!complete) - { - success = false; - return null; - } - return s.ToString(); - } - - private static string ConvertFromUtf32(int utf32) - { - // http://www.java2s.com/Open-Source/CSharp/2.6.4-mono-.net-core/System/System/Char.cs.htm - if (utf32 < 0 || utf32 > 0x10FFFF) - throw new ArgumentOutOfRangeException("utf32", "The argument must be from 0 to 0x10FFFF."); - if (0xD800 <= utf32 && utf32 <= 0xDFFF) - throw new ArgumentOutOfRangeException("utf32", "The argument must not be in surrogate pair range."); - if (utf32 < 0x10000) - return new string((char)utf32, 1); - utf32 -= 0x10000; - return new string(new char[] { (char)((utf32 >> 10) + 0xD800), (char)(utf32 % 0x0400 + 0xDC00) }); - } - - static object ParseNumber(char[] json, ref int index, ref bool success) - { - EatWhitespace(json, ref index); - int lastIndex = GetLastIndexOfNumber(json, index); - int charLength = (lastIndex - index) + 1; - object returnNumber; - string str = new string(json, index, charLength); - if (str.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || str.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1) - { - double number; -#if PocketPC - try { - number = double.Parse(new string(json, index, charLength), NumberStyles.Any); - success = true; - } catch (Exception) { - number = 0; - success = false; - } -#else - success = double.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); -#endif - returnNumber = number; - } - else - { - long number; -#if PocketPC - try { - number = long.Parse(new string(json, index, charLength), NumberStyles.Any); - success = true; - } catch (Exception) { - number = 0; - success = false; - } -#else - success = long.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); -#endif - returnNumber = number; - } - index = lastIndex + 1; - return returnNumber; - } - - static int GetLastIndexOfNumber(char[] json, int index) - { - int lastIndex; - for (lastIndex = index; lastIndex < json.Length; lastIndex++) - if ("0123456789+-.eE".IndexOf(json[lastIndex]) == -1) break; - return lastIndex - 1; - } - - static void EatWhitespace(char[] json, ref int index) - { - for (; index < json.Length; index++) - if (" \t\n\r\b\f".IndexOf(json[index]) == -1) break; - } - - static int LookAhead(char[] json, int index) - { - int saveIndex = index; - return NextToken(json, ref saveIndex); - } - - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] - static int NextToken(char[] json, ref int index) - { - EatWhitespace(json, ref index); - if (index == json.Length) - return TOKEN_NONE; - char c = json[index]; - index++; - switch (c) - { - case '{': - return TOKEN_CURLY_OPEN; - case '}': - return TOKEN_CURLY_CLOSE; - case '[': - return TOKEN_SQUARED_OPEN; - case ']': - return TOKEN_SQUARED_CLOSE; - case ',': - return TOKEN_COMMA; - case '"': - return TOKEN_STRING; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - return TOKEN_NUMBER; - case ':': - return TOKEN_COLON; - } - index--; - int remainingLength = json.Length - index; - // false - if (remainingLength >= 5) - { - if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e') - { - index += 5; - return TOKEN_FALSE; - } - } - // true - if (remainingLength >= 4) - { - if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') - { - index += 4; - return TOKEN_TRUE; - } - } - // null - if (remainingLength >= 4) - { - if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') - { - index += 4; - return TOKEN_NULL; - } - } - return TOKEN_NONE; - } - - static bool SerializeValue(IJsonSerializerStrategy jsonSerializerStrategy, object value, StringBuilder builder) - { - bool success = true; - string stringValue = value as string; - if (stringValue != null) - success = SerializeString(stringValue, builder); - else - { - IDictionary dict = value as IDictionary; - if (dict != null) - { - success = SerializeObject(jsonSerializerStrategy, dict.Keys, dict.Values, builder); - } - else - { - IDictionary stringDictionary = value as IDictionary; - if (stringDictionary != null) - { - success = SerializeObject(jsonSerializerStrategy, stringDictionary.Keys, stringDictionary.Values, builder); - } - else - { - IEnumerable enumerableValue = value as IEnumerable; - if (enumerableValue != null) - success = SerializeArray(jsonSerializerStrategy, enumerableValue, builder); - else if (IsNumeric(value)) - success = SerializeNumber(value, builder); - else if (value is bool) - builder.Append((bool)value ? "true" : "false"); - else if (value == null) - builder.Append("null"); - else - { - object serializedObject; - success = jsonSerializerStrategy.TrySerializeNonPrimitiveObject(value, out serializedObject); - if (success) - SerializeValue(jsonSerializerStrategy, serializedObject, builder); - } - } - } - } - return success; - } - - static bool SerializeObject(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable keys, IEnumerable values, StringBuilder builder) - { - builder.Append("{"); - IEnumerator ke = keys.GetEnumerator(); - IEnumerator ve = values.GetEnumerator(); - bool first = true; - while (ke.MoveNext() && ve.MoveNext()) - { - object key = ke.Current; - object value = ve.Current; - if (!first) - builder.Append(","); - string stringKey = key as string; - if (stringKey != null) - SerializeString(stringKey, builder); - else - if (!SerializeValue(jsonSerializerStrategy, value, builder)) return false; - builder.Append(":"); - if (!SerializeValue(jsonSerializerStrategy, value, builder)) - return false; - first = false; - } - builder.Append("}"); - return true; - } - - static bool SerializeArray(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable anArray, StringBuilder builder) - { - builder.Append("["); - bool first = true; - foreach (object value in anArray) - { - if (!first) - builder.Append(","); - if (!SerializeValue(jsonSerializerStrategy, value, builder)) - return false; - first = false; - } - builder.Append("]"); - return true; - } - - static bool SerializeString(string aString, StringBuilder builder) - { - builder.Append("\""); - char[] charArray = aString.ToCharArray(); - for (int i = 0; i < charArray.Length; i++) - { - char c = charArray[i]; - if (c == '"') - builder.Append("\\\""); - else if (c == '\\') - builder.Append("\\\\"); - else if (c == '\b') - builder.Append("\\b"); - else if (c == '\f') - builder.Append("\\f"); - else if (c == '\n') - builder.Append("\\n"); - else if (c == '\r') - builder.Append("\\r"); - else if (c == '\t') - builder.Append("\\t"); - else - builder.Append(c); - } - builder.Append("\""); - return true; - } - - static bool SerializeNumber(object number, StringBuilder builder) - { - if (number is long) - builder.Append(((long)number).ToString(CultureInfo.InvariantCulture)); - else if (number is ulong) - builder.Append(((ulong)number).ToString(CultureInfo.InvariantCulture)); - else if (number is int) - builder.Append(((int)number).ToString(CultureInfo.InvariantCulture)); - else if (number is uint) - builder.Append(((uint)number).ToString(CultureInfo.InvariantCulture)); - else if (number is decimal) - builder.Append(((decimal)number).ToString(CultureInfo.InvariantCulture)); - else if (number is float) - builder.Append(((float)number).ToString(CultureInfo.InvariantCulture)); - else - builder.Append(Convert.ToDouble(number, CultureInfo.InvariantCulture).ToString("r", CultureInfo.InvariantCulture)); - return true; - } - - /// - /// Determines if a given object is numeric in any way - /// (can be integer, double, null, etc). - /// - static bool IsNumeric(object value) - { - if (value is sbyte) return true; - if (value is byte) return true; - if (value is short) return true; - if (value is ushort) return true; - if (value is int) return true; - if (value is uint) return true; - if (value is long) return true; - if (value is ulong) return true; - if (value is float) return true; - if (value is double) return true; - if (value is decimal) return true; - return false; - } - - private static IJsonSerializerStrategy _currentJsonSerializerStrategy; - public static IJsonSerializerStrategy CurrentJsonSerializerStrategy - { - get - { - return _currentJsonSerializerStrategy ?? - (_currentJsonSerializerStrategy = -#if SIMPLE_JSON_DATACONTRACT - DataContractJsonSerializerStrategy -#else - PocoJsonSerializerStrategy -#endif -); - } - set - { - _currentJsonSerializerStrategy = value; - } - } - - private static PocoJsonSerializerStrategy _pocoJsonSerializerStrategy; - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static PocoJsonSerializerStrategy PocoJsonSerializerStrategy - { - get - { - return _pocoJsonSerializerStrategy ?? (_pocoJsonSerializerStrategy = new PocoJsonSerializerStrategy()); - } - } - -#if SIMPLE_JSON_DATACONTRACT - - private static DataContractJsonSerializerStrategy _dataContractJsonSerializerStrategy; - [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Advanced)] - public static DataContractJsonSerializerStrategy DataContractJsonSerializerStrategy - { - get - { - return _dataContractJsonSerializerStrategy ?? (_dataContractJsonSerializerStrategy = new DataContractJsonSerializerStrategy()); - } - } - -#endif - } - - [GeneratedCode("simple-json", "1.0.0")] -#if SIMPLE_JSON_INTERNAL - internal -#else - public -#endif - interface IJsonSerializerStrategy - { - [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] - bool TrySerializeNonPrimitiveObject(object input, out object output); - object DeserializeObject(object value, Type type); - } - - [GeneratedCode("simple-json", "1.0.0")] -#if SIMPLE_JSON_INTERNAL - internal -#else - public -#endif - class PocoJsonSerializerStrategy : IJsonSerializerStrategy - { - internal IDictionary ConstructorCache; - internal IDictionary> GetCache; - internal IDictionary>> SetCache; - - internal static readonly Type[] EmptyTypes = new Type[0]; - internal static readonly Type[] ArrayConstructorParameterTypes = new Type[] { typeof(int) }; - - private static readonly string[] Iso8601Format = new string[] - { - @"yyyy-MM-dd\THH:mm:ss.FFFFFFF\Z", - @"yyyy-MM-dd\THH:mm:ss\Z", - @"yyyy-MM-dd\THH:mm:ssK" - }; - - public PocoJsonSerializerStrategy() - { - ConstructorCache = new ReflectionUtils.ThreadSafeDictionary(ContructorDelegateFactory); - GetCache = new ReflectionUtils.ThreadSafeDictionary>(GetterValueFactory); - SetCache = new ReflectionUtils.ThreadSafeDictionary>>(SetterValueFactory); - } - - protected virtual string MapClrMemberNameToJsonFieldName(string clrPropertyName) - { - return clrPropertyName; - } - - internal virtual ReflectionUtils.ConstructorDelegate ContructorDelegateFactory(Type key) - { - return ReflectionUtils.GetContructor(key, key.IsArray ? ArrayConstructorParameterTypes : EmptyTypes); - } - - internal virtual IDictionary GetterValueFactory(Type type) - { - IDictionary result = new Dictionary(); - foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) - { - if (propertyInfo.CanRead) - { - MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); - if (getMethod.IsStatic || !getMethod.IsPublic) - continue; - result[MapClrMemberNameToJsonFieldName(propertyInfo.Name)] = ReflectionUtils.GetGetMethod(propertyInfo); - } - } - foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) - { - if (fieldInfo.IsStatic || !fieldInfo.IsPublic) - continue; - result[MapClrMemberNameToJsonFieldName(fieldInfo.Name)] = ReflectionUtils.GetGetMethod(fieldInfo); - } - return result; - } - - internal virtual IDictionary> SetterValueFactory(Type type) - { - IDictionary> result = new Dictionary>(); - foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) - { - if (propertyInfo.CanWrite) - { - MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); - if (setMethod.IsStatic || !setMethod.IsPublic) - continue; - result[MapClrMemberNameToJsonFieldName(propertyInfo.Name)] = new KeyValuePair(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); - } - } - foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) - { - if (fieldInfo.IsInitOnly || fieldInfo.IsStatic || !fieldInfo.IsPublic) - continue; - result[MapClrMemberNameToJsonFieldName(fieldInfo.Name)] = new KeyValuePair(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); - } - return result; - } - - public virtual bool TrySerializeNonPrimitiveObject(object input, out object output) - { - return TrySerializeKnownTypes(input, out output) || TrySerializeUnknownTypes(input, out output); - } - - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] - public virtual object DeserializeObject(object value, Type type) - { - if (type == null) throw new ArgumentNullException("type"); - string str = value as string; - - if (type == typeof (Guid) && string.IsNullOrEmpty(str)) - return default(Guid); - - if (value == null) - return null; - - object obj = null; - - if (str != null) - { - if (str.Length != 0) // We know it can't be null now. - { - if (type == typeof(DateTime) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTime))) - return DateTime.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); -#if !PocketPC - if (type == typeof(DateTimeOffset) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTimeOffset))) - return DateTimeOffset.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); -#endif - if (type == typeof(Guid) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid))) - return new Guid(str); - return str; - } - else - { - if (type == typeof(Guid)) - obj = default(Guid); - else if (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) - obj = null; - else - obj = str; - } - // Empty string case - if (!ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) - return str; - } - else if (value is bool) - return value; - - bool valueIsLong = value is long; - bool valueIsDouble = value is double; - if ((valueIsLong && type == typeof(long)) || (valueIsDouble && type == typeof(double))) - return value; - if ((valueIsDouble && type != typeof(double)) || (valueIsLong && type != typeof(long))) - { - obj = type == typeof(int) || type == typeof(long) || type == typeof(double) || type == typeof(float) || type == typeof(bool) || type == typeof(decimal) || type == typeof(byte) || type == typeof(short) - ? Convert.ChangeType(value, type, CultureInfo.InvariantCulture) - : value; - } - else - { - IDictionary objects = value as IDictionary; - if (objects != null) - { - IDictionary jsonObject = objects; - - if (ReflectionUtils.IsTypeDictionary(type)) - { - // if dictionary then - Type[] types = ReflectionUtils.GetGenericTypeArguments(type); - Type keyType = types[0]; - Type valueType = types[1]; - - Type genericType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); - - IDictionary dict = (IDictionary)ConstructorCache[genericType](); - - foreach (KeyValuePair kvp in jsonObject) - dict.Add(kvp.Key, DeserializeObject(kvp.Value, valueType)); - - obj = dict; - } - else - { - if (type == typeof(object)) - obj = value; - else - { - obj = ConstructorCache[type](); - foreach (KeyValuePair> setter in SetCache[type]) - { - object jsonValue; - if (jsonObject.TryGetValue(setter.Key, out jsonValue)) - { - jsonValue = DeserializeObject(jsonValue, setter.Value.Key); - setter.Value.Value(obj, jsonValue); - } - } - } - } - } - else - { - IList valueAsList = value as IList; - if (valueAsList != null) - { - IList jsonObject = valueAsList; - IList list = null; - - if (type.IsArray) - { - list = (IList)ConstructorCache[type](jsonObject.Count); - int i = 0; - foreach (object o in jsonObject) - list[i++] = DeserializeObject(o, type.GetElementType()); - } - else if (ReflectionUtils.IsTypeGenericeCollectionInterface(type) || ReflectionUtils.IsAssignableFrom(typeof(IList), type)) - { - Type innerType = ReflectionUtils.GetGenericTypeArguments(type)[0]; - Type genericType = typeof(List<>).MakeGenericType(innerType); - list = (IList)ConstructorCache[genericType](jsonObject.Count); - foreach (object o in jsonObject) - list.Add(DeserializeObject(o, innerType)); - } - obj = list; - } - } - return obj; - } - if (ReflectionUtils.IsNullableType(type)) - return ReflectionUtils.ToNullableType(obj, type); - return obj; - } - - protected virtual object SerializeEnum(Enum p) - { - return Convert.ToDouble(p, CultureInfo.InvariantCulture); - } - - [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] - protected virtual bool TrySerializeKnownTypes(object input, out object output) - { - bool returnValue = true; - if (input is DateTime) - output = ((DateTime)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); -#if !PocketPC - else if (input is DateTimeOffset) - output = ((DateTimeOffset)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); -#endif - else if (input is Guid) - output = ((Guid)input).ToString("D"); - else if (input is Uri) - output = input.ToString(); - else - { - Enum inputEnum = input as Enum; - if (inputEnum != null) - output = SerializeEnum(inputEnum); - else - { - returnValue = false; - output = null; - } - } - return returnValue; - } - [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")] - protected virtual bool TrySerializeUnknownTypes(object input, out object output) - { - if (input == null) throw new ArgumentNullException("input"); - output = null; - Type type = input.GetType(); - if (type.FullName == null) - return false; - IDictionary obj = new JsonObject(); - IDictionary getters = GetCache[type]; - foreach (KeyValuePair getter in getters) - { - if (getter.Value != null) - obj.Add(MapClrMemberNameToJsonFieldName(getter.Key), getter.Value(input)); - } - output = obj; - return true; - } - } - -#if SIMPLE_JSON_DATACONTRACT - [GeneratedCode("simple-json", "1.0.0")] -#if SIMPLE_JSON_INTERNAL - internal -#else - public -#endif - class DataContractJsonSerializerStrategy : PocoJsonSerializerStrategy - { - public DataContractJsonSerializerStrategy() - { - GetCache = new ReflectionUtils.ThreadSafeDictionary>(GetterValueFactory); - SetCache = new ReflectionUtils.ThreadSafeDictionary>>(SetterValueFactory); - } - - internal override IDictionary GetterValueFactory(Type type) - { - bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; - if (!hasDataContract) - return base.GetterValueFactory(type); - string jsonKey; - IDictionary result = new Dictionary(); - foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) - { - if (propertyInfo.CanRead) - { - MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo); - if (!getMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) - result[jsonKey] = ReflectionUtils.GetGetMethod(propertyInfo); - } - } - foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) - { - if (!fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) - result[jsonKey] = ReflectionUtils.GetGetMethod(fieldInfo); - } - return result; - } - - internal override IDictionary> SetterValueFactory(Type type) - { - bool hasDataContract = ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute)) != null; - if (!hasDataContract) - return base.SetterValueFactory(type); - string jsonKey; - IDictionary> result = new Dictionary>(); - foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type)) - { - if (propertyInfo.CanWrite) - { - MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo); - if (!setMethod.IsStatic && CanAdd(propertyInfo, out jsonKey)) - result[jsonKey] = new KeyValuePair(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo)); - } - } - foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type)) - { - if (!fieldInfo.IsInitOnly && !fieldInfo.IsStatic && CanAdd(fieldInfo, out jsonKey)) - result[jsonKey] = new KeyValuePair(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo)); - } - // todo implement sorting for DATACONTRACT. - return result; - } - - private static bool CanAdd(MemberInfo info, out string jsonKey) - { - jsonKey = null; - if (ReflectionUtils.GetAttribute(info, typeof(IgnoreDataMemberAttribute)) != null) - return false; - DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)ReflectionUtils.GetAttribute(info, typeof(DataMemberAttribute)); - if (dataMemberAttribute == null) - return false; - jsonKey = string.IsNullOrEmpty(dataMemberAttribute.Name) ? info.Name : dataMemberAttribute.Name; - return true; - } - } - -#endif - - namespace Reflection - { - // This class is meant to be copied into other libraries. So we want to exclude it from Code Analysis rules - // that might be in place in the target project. - [GeneratedCode("reflection-utils", "1.0.0")] -#if SIMPLE_JSON_REFLECTION_UTILS_PUBLIC - public -#else - internal -#endif - class ReflectionUtils - { - private static readonly object[] EmptyObjects = new object[] { }; - - public delegate object GetDelegate(object source); - public delegate void SetDelegate(object source, object value); - public delegate object ConstructorDelegate(params object[] args); - - public delegate TValue ThreadSafeDictionaryValueFactory(TKey key); - - public static Attribute GetAttribute(MemberInfo info, Type type) - { -#if SIMPLE_JSON_TYPEINFO - if (info == null || type == null || !info.IsDefined(type)) - return null; - return info.GetCustomAttribute(type); -#else - if (info == null || type == null || !Attribute.IsDefined(info, type)) - return null; - return Attribute.GetCustomAttribute(info, type); -#endif - } - - public static Attribute GetAttribute(Type objectType, Type attributeType) - { - -#if SIMPLE_JSON_TYPEINFO - if (objectType == null || attributeType == null || !objectType.GetTypeInfo().IsDefined(attributeType)) - return null; - return objectType.GetTypeInfo().GetCustomAttribute(attributeType); -#else - if (objectType == null || attributeType == null || !Attribute.IsDefined(objectType, attributeType)) - return null; - return Attribute.GetCustomAttribute(objectType, attributeType); -#endif - } - - public static Type[] GetGenericTypeArguments(Type type) - { -#if SIMPLE_JSON_TYPEINFO - return type.GetTypeInfo().GenericTypeArguments; -#else - return type.GetGenericArguments(); -#endif - } - - public static bool IsTypeGenericeCollectionInterface(Type type) - { -#if SIMPLE_JSON_TYPEINFO - if (!type.GetTypeInfo().IsGenericType) -#else - if (!type.IsGenericType) -#endif - return false; - - Type genericDefinition = type.GetGenericTypeDefinition(); - - return (genericDefinition == typeof(IList<>) || genericDefinition == typeof(ICollection<>) || genericDefinition == typeof(IEnumerable<>)); - } - - public static bool IsAssignableFrom(Type type1, Type type2) - { -#if SIMPLE_JSON_TYPEINFO - return type1.GetTypeInfo().IsAssignableFrom(type2.GetTypeInfo()); -#else - return type1.IsAssignableFrom(type2); -#endif - } - - public static bool IsTypeDictionary(Type type) - { -#if SIMPLE_JSON_TYPEINFO - if (typeof(IDictionary<,>).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) - return true; - - if (!type.GetTypeInfo().IsGenericType) - return false; -#else - if (typeof(System.Collections.IDictionary).IsAssignableFrom(type)) - return true; - - if (!type.IsGenericType) - return false; -#endif - Type genericDefinition = type.GetGenericTypeDefinition(); - return genericDefinition == typeof(IDictionary<,>); - } - - public static bool IsNullableType(Type type) - { - return -#if SIMPLE_JSON_TYPEINFO - type.GetTypeInfo().IsGenericType -#else - type.IsGenericType -#endif - && type.GetGenericTypeDefinition() == typeof(Nullable<>); - } - - public static object ToNullableType(object obj, Type nullableType) - { - return obj == null ? null : Convert.ChangeType(obj, Nullable.GetUnderlyingType(nullableType), CultureInfo.InvariantCulture); - } - - public static bool IsValueType(Type type) - { -#if SIMPLE_JSON_TYPEINFO - return type.GetTypeInfo().IsValueType; -#else - return type.IsValueType; -#endif - } - - public static IEnumerable GetConstructors(Type type) - { -#if SIMPLE_JSON_TYPEINFO - return type.GetTypeInfo().DeclaredConstructors; -#else - return type.GetConstructors(); -#endif - } - - public static ConstructorInfo GetConstructorInfo(Type type, params Type[] argsType) - { - IEnumerable constructorInfos = GetConstructors(type); - int i; - bool matches; - foreach (ConstructorInfo constructorInfo in constructorInfos) - { - ParameterInfo[] parameters = constructorInfo.GetParameters(); - if (argsType.Length != parameters.Length) - continue; - - i = 0; - matches = true; - foreach (ParameterInfo parameterInfo in constructorInfo.GetParameters()) - { - if (parameterInfo.ParameterType != argsType[i]) - { - matches = false; - break; - } - } - - if (matches) - return constructorInfo; - } - - return null; - } - - public static IEnumerable GetProperties(Type type) - { -#if SIMPLE_JSON_TYPEINFO - return type.GetTypeInfo().DeclaredProperties; -#else - return type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); -#endif - } - - public static IEnumerable GetFields(Type type) - { -#if SIMPLE_JSON_TYPEINFO - return type.GetTypeInfo().DeclaredFields; -#else - return type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); -#endif - } - - public static MethodInfo GetGetterMethodInfo(PropertyInfo propertyInfo) - { -#if SIMPLE_JSON_TYPEINFO - return propertyInfo.GetMethod; -#else - return propertyInfo.GetGetMethod(true); -#endif - } - - public static MethodInfo GetSetterMethodInfo(PropertyInfo propertyInfo) - { -#if SIMPLE_JSON_TYPEINFO - return propertyInfo.SetMethod; -#else - return propertyInfo.GetSetMethod(true); -#endif - } - - public static ConstructorDelegate GetContructor(ConstructorInfo constructorInfo) - { -#if SIMPLE_JSON_NO_LINQ_EXPRESSION - return GetConstructorByReflection(constructorInfo); -#else - return GetConstructorByExpression(constructorInfo); -#endif - } - - public static ConstructorDelegate GetContructor(Type type, params Type[] argsType) - { -#if SIMPLE_JSON_NO_LINQ_EXPRESSION - return GetConstructorByReflection(type, argsType); -#else - return GetConstructorByExpression(type, argsType); -#endif - } - - public static ConstructorDelegate GetConstructorByReflection(ConstructorInfo constructorInfo) - { - return delegate(object[] args) { return constructorInfo.Invoke(args); }; - } - - public static ConstructorDelegate GetConstructorByReflection(Type type, params Type[] argsType) - { - ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); - return constructorInfo == null ? null : GetConstructorByReflection(constructorInfo); - } - -#if !SIMPLE_JSON_NO_LINQ_EXPRESSION - - public static ConstructorDelegate GetConstructorByExpression(ConstructorInfo constructorInfo) - { - ParameterInfo[] paramsInfo = constructorInfo.GetParameters(); - ParameterExpression param = Expression.Parameter(typeof(object[]), "args"); - Expression[] argsExp = new Expression[paramsInfo.Length]; - for (int i = 0; i < paramsInfo.Length; i++) - { - Expression index = Expression.Constant(i); - Type paramType = paramsInfo[i].ParameterType; - Expression paramAccessorExp = Expression.ArrayIndex(param, index); - Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType); - argsExp[i] = paramCastExp; - } - NewExpression newExp = Expression.New(constructorInfo, argsExp); - Expression> lambda = Expression.Lambda>(newExp, param); - Func compiledLambda = lambda.Compile(); - return delegate(object[] args) { return compiledLambda(args); }; - } - - public static ConstructorDelegate GetConstructorByExpression(Type type, params Type[] argsType) - { - ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); - return constructorInfo == null ? null : GetConstructorByExpression(constructorInfo); - } - -#endif - - public static GetDelegate GetGetMethod(PropertyInfo propertyInfo) - { -#if SIMPLE_JSON_NO_LINQ_EXPRESSION || PocketPC - return GetGetMethodByReflection(propertyInfo); -#else - return GetGetMethodByExpression(propertyInfo); -#endif - } - - public static GetDelegate GetGetMethod(FieldInfo fieldInfo) - { -#if SIMPLE_JSON_NO_LINQ_EXPRESSION || PocketPC - return GetGetMethodByReflection(fieldInfo); -#else - return GetGetMethodByExpression(fieldInfo); -#endif - } - - public static GetDelegate GetGetMethodByReflection(PropertyInfo propertyInfo) - { - MethodInfo methodInfo = GetGetterMethodInfo(propertyInfo); - return delegate(object source) { return methodInfo.Invoke(source, EmptyObjects); }; - } - - public static GetDelegate GetGetMethodByReflection(FieldInfo fieldInfo) - { - return delegate(object source) { return fieldInfo.GetValue(source); }; - } - -#if !SIMPLE_JSON_NO_LINQ_EXPRESSION && !PocketPC - - public static GetDelegate GetGetMethodByExpression(PropertyInfo propertyInfo) - { - MethodInfo getMethodInfo = GetGetterMethodInfo(propertyInfo); - ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); - UnaryExpression instanceCast = (!IsValueType(propertyInfo.DeclaringType)) ? Expression.TypeAs(instance, propertyInfo.DeclaringType) : Expression.Convert(instance, propertyInfo.DeclaringType); - Func compiled = Expression.Lambda>(Expression.TypeAs(Expression.Call(instanceCast, getMethodInfo), typeof(object)), instance).Compile(); - return delegate(object source) { return compiled(source); }; - } - - public static GetDelegate GetGetMethodByExpression(FieldInfo fieldInfo) - { - ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); - MemberExpression member = Expression.Field(Expression.Convert(instance, fieldInfo.DeclaringType), fieldInfo); - GetDelegate compiled = Expression.Lambda(Expression.Convert(member, typeof(object)), instance).Compile(); - return delegate(object source) { return compiled(source); }; - } - -#endif - - public static SetDelegate GetSetMethod(PropertyInfo propertyInfo) - { -#if SIMPLE_JSON_NO_LINQ_EXPRESSION - return GetSetMethodByReflection(propertyInfo); -#else - return GetSetMethodByExpression(propertyInfo); -#endif - } - - public static SetDelegate GetSetMethod(FieldInfo fieldInfo) - { -#if SIMPLE_JSON_NO_LINQ_EXPRESSION - return GetSetMethodByReflection(fieldInfo); -#else - return GetSetMethodByExpression(fieldInfo); -#endif - } - - public static SetDelegate GetSetMethodByReflection(PropertyInfo propertyInfo) - { - MethodInfo methodInfo = GetSetterMethodInfo(propertyInfo); - return delegate(object source, object value) { methodInfo.Invoke(source, new object[] { value }); }; - } - - public static SetDelegate GetSetMethodByReflection(FieldInfo fieldInfo) - { - return delegate(object source, object value) { fieldInfo.SetValue(source, value); }; - } - -#if !SIMPLE_JSON_NO_LINQ_EXPRESSION - - public static SetDelegate GetSetMethodByExpression(PropertyInfo propertyInfo) - { - MethodInfo setMethodInfo = GetSetterMethodInfo(propertyInfo); - ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); - ParameterExpression value = Expression.Parameter(typeof(object), "value"); - UnaryExpression instanceCast = (!IsValueType(propertyInfo.DeclaringType)) ? Expression.TypeAs(instance, propertyInfo.DeclaringType) : Expression.Convert(instance, propertyInfo.DeclaringType); - UnaryExpression valueCast = (!IsValueType(propertyInfo.PropertyType)) ? Expression.TypeAs(value, propertyInfo.PropertyType) : Expression.Convert(value, propertyInfo.PropertyType); - Action compiled = Expression.Lambda>(Expression.Call(instanceCast, setMethodInfo, valueCast), new ParameterExpression[] { instance, value }).Compile(); - return delegate(object source, object val) { compiled(source, val); }; - } - - public static SetDelegate GetSetMethodByExpression(FieldInfo fieldInfo) - { - ParameterExpression instance = Expression.Parameter(typeof(object), "instance"); - ParameterExpression value = Expression.Parameter(typeof(object), "value"); - Action compiled = Expression.Lambda>( - Assign(Expression.Field(Expression.Convert(instance, fieldInfo.DeclaringType), fieldInfo), Expression.Convert(value, fieldInfo.FieldType)), instance, value).Compile(); - return delegate(object source, object val) { compiled(source, val); }; - } - - public static BinaryExpression Assign(Expression left, Expression right) - { -#if SIMPLE_JSON_TYPEINFO - return Expression.Assign(left, right); -#else - MethodInfo assign = typeof(Assigner<>).MakeGenericType(left.Type).GetMethod("Assign"); - BinaryExpression assignExpr = Expression.Add(left, right, assign); - return assignExpr; -#endif - } - - private static class Assigner - { - public static T Assign(ref T left, T right) - { - return (left = right); - } - } - -#endif - - public sealed class ThreadSafeDictionary : IDictionary - { - private readonly object _lock = new object(); - private readonly ThreadSafeDictionaryValueFactory _valueFactory; - private Dictionary _dictionary; - - public ThreadSafeDictionary(ThreadSafeDictionaryValueFactory valueFactory) - { - _valueFactory = valueFactory; - } - - private TValue Get(TKey key) - { - if (_dictionary == null) - return AddValue(key); - TValue value; - if (!_dictionary.TryGetValue(key, out value)) - return AddValue(key); - return value; - } - - private TValue AddValue(TKey key) - { - TValue value = _valueFactory(key); - lock (_lock) - { - if (_dictionary == null) - { - _dictionary = new Dictionary(); - _dictionary[key] = value; - } - else - { - TValue val; - if (_dictionary.TryGetValue(key, out val)) - return val; - Dictionary dict = new Dictionary(_dictionary); - dict[key] = value; - _dictionary = dict; - } - } - return value; - } - - public void Add(TKey key, TValue value) - { - throw new NotImplementedException(); - } - - public bool ContainsKey(TKey key) - { - return _dictionary.ContainsKey(key); - } - - public ICollection Keys - { - get { return _dictionary.Keys; } - } - - public bool Remove(TKey key) - { - throw new NotImplementedException(); - } - - public bool TryGetValue(TKey key, out TValue value) - { - value = this[key]; - return true; - } - - public ICollection Values - { - get { return _dictionary.Values; } - } - - public TValue this[TKey key] - { - get { return Get(key); } - set { throw new NotImplementedException(); } - } - - public void Add(KeyValuePair item) - { - throw new NotImplementedException(); - } - - public void Clear() - { - throw new NotImplementedException(); - } - - public bool Contains(KeyValuePair item) - { - throw new NotImplementedException(); - } - - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - throw new NotImplementedException(); - } - - public int Count - { - get { return _dictionary.Count; } - } - - public bool IsReadOnly - { - get { throw new NotImplementedException(); } - } - - public bool Remove(KeyValuePair item) - { - throw new NotImplementedException(); - } - - public IEnumerator> GetEnumerator() - { - return _dictionary.GetEnumerator(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return _dictionary.GetEnumerator(); - } - } - - } - } -} -// ReSharper restore LoopCanBeConvertedToQuery -// ReSharper restore RedundantExplicitArrayCreation -// ReSharper restore SuggestUseVarKeywordEvident diff --git a/Backup/RestSharp.Silverlight/Validation/Require.cs b/Backup/RestSharp.Silverlight/Validation/Require.cs deleted file mode 100644 index 63fa37376..000000000 --- a/Backup/RestSharp.Silverlight/Validation/Require.cs +++ /dev/null @@ -1,37 +0,0 @@ -#region License -// Copyright 2010 John Sheehan -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -using System; - -namespace RestSharp.Validation -{ - /// - /// Helper methods for validating required values - /// - public class Require - { - /// - /// Require a parameter to not be null - /// - /// Name of the parameter - /// Value of the parameter - public static void Argument(string argumentName, object argumentValue) { - if (argumentValue == null) { - throw new ArgumentException("Argument cannot be null.", argumentName); - } - } - } -} diff --git a/Backup/RestSharp.Silverlight/Validation/Validate.cs b/Backup/RestSharp.Silverlight/Validation/Validate.cs deleted file mode 100644 index b23ce975f..000000000 --- a/Backup/RestSharp.Silverlight/Validation/Validate.cs +++ /dev/null @@ -1,52 +0,0 @@ -#region License -// Copyright 2010 John Sheehan -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -using System; - -namespace RestSharp.Validation -{ - /// - /// Helper methods for validating values - /// - public class Validate - { - /// - /// Validate an integer value is between the specified values (exclusive of min/max) - /// - /// Value to validate - /// Exclusive minimum value - /// Exclusive maximum value - public static void IsBetween(int value, int min, int max) { - if (value < min || value > max) { - throw new ArgumentException(string.Format("Value ({0}) is not between {1} and {2}.", value, min, max)); - } - } - - /// - /// Validate a string length - /// - /// String to be validated - /// Maximum length of the string - public static void IsValidLength(string value, int maxSize) { - if (value == null) - return; - - if (value.Length > maxSize) { - throw new ArgumentException(string.Format("String is longer than max allowed size ({0}).", maxSize)); - } - } - } -} diff --git a/Backup/RestSharp.Silverlight/packages.config b/Backup/RestSharp.Silverlight/packages.config deleted file mode 100644 index 6b8deb9c9..000000000 --- a/Backup/RestSharp.Silverlight/packages.config +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/Backup/RestSharp.sln b/Backup/RestSharp.sln deleted file mode 100644 index ffe12b3a3..000000000 --- a/Backup/RestSharp.sln +++ /dev/null @@ -1,123 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp", "RestSharp\RestSharp.csproj", "{2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.Tests", "RestSharp.Tests\RestSharp.Tests.csproj", "{1464E4AC-18BB-4F23-8A0B-68196F9E1871}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.IntegrationTests", "RestSharp.IntegrationTests\RestSharp.IntegrationTests.csproj", "{47D3EBB9-0300-4AF8-BAC5-740D51454A63}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.Silverlight", "RestSharp.Silverlight\RestSharp.Silverlight.csproj", "{11F84600-0978-48B9-A28F-63B3781E54B3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.WindowsPhone", "RestSharp.WindowsPhone\RestSharp.WindowsPhone.csproj", "{F4D48DF6-316E-4963-B5C1-59CA39B431B7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGet", "NuGet", "{E709A928-A45C-4622-A35C-CCD8EE44CA80}" - ProjectSection(SolutionItems) = preProject - package.cmd = package.cmd - readme.txt = readme.txt - restsharp.nuspec = restsharp.nuspec - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.Net4", "RestSharp.Net4\RestSharp.Net4.csproj", "{5FF943A5-260F-4042-B4CE-C4977BAD4EBB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{1B3F12F6-D32B-48C4-98D7-AB448EB78811}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.Build", "RestSharp.Build\RestSharp.Build.csproj", "{CCC30138-3D68-44D8-AF1A-D22F769EE8DC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Meta", "Meta", "{C5B02FAA-6A0A-4BF9-BBD4-82FD2DCBF669}" - ProjectSection(SolutionItems) = preProject - CONTRIBUTING.markdown = CONTRIBUTING.markdown - README.markdown = README.markdown - readme.txt = readme.txt - releasenotes.markdown = releasenotes.markdown - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|x86.ActiveCfg = Debug|Any CPU - {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Any CPU.Build.0 = Release|Any CPU - {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|x86.ActiveCfg = Release|Any CPU - {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|x86.ActiveCfg = Debug|Any CPU - {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Any CPU.Build.0 = Release|Any CPU - {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|x86.ActiveCfg = Release|Any CPU - {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Any CPU.Build.0 = Debug|Any CPU - {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|x86.ActiveCfg = Debug|Any CPU - {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Any CPU.ActiveCfg = Release|Any CPU - {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Any CPU.Build.0 = Release|Any CPU - {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|x86.ActiveCfg = Release|Any CPU - {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|x86.ActiveCfg = Debug|Any CPU - {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Any CPU.Build.0 = Release|Any CPU - {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|x86.ActiveCfg = Release|Any CPU - {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|x86.ActiveCfg = Debug|Any CPU - {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Any CPU.Build.0 = Release|Any CPU - {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|x86.ActiveCfg = Release|Any CPU - {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|x86.ActiveCfg = Debug|Any CPU - {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Any CPU.Build.0 = Release|Any CPU - {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|x86.ActiveCfg = Release|Any CPU - {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|x86.ActiveCfg = Debug|Any CPU - {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Any CPU.Build.0 = Release|Any CPU - {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|x86.ActiveCfg = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/RestSharp.Silverlight/RestSharp.Silverlight.csproj b/RestSharp.Silverlight/RestSharp.Silverlight.csproj index c86523797..0d272963f 100644 --- a/RestSharp.Silverlight/RestSharp.Silverlight.csproj +++ b/RestSharp.Silverlight/RestSharp.Silverlight.csproj @@ -12,18 +12,13 @@ RestSharp.Silverlight RestSharp.Silverlight Silverlight - v5.0 + v4.0 $(TargetFrameworkVersion) false true true ..\ true - - - - - 4.0