Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge SL and non-SL sections. Add HandleCallbackonUIThread option - e…

…nabled by default.
  • Loading branch information...
commit fb78557d410376b3dc4f5808c6450780d90a9508 1 parent b5a86e5
@mj1856 mj1856 authored
View
47 src/ServiceStack.Common/ServiceClient.Web/AsyncServiceClient.cs
@@ -69,12 +69,38 @@ public RequestState()
public Action<TResponse, Exception> OnError;
+#if SILVERLIGHT
+ public bool HandleCallbackOnUIThread { get; set; }
+#endif
+
+ public void HandleSuccess(TResponse response)
+ {
+ if (this.OnSuccess == null)
+ return;
+
+#if SILVERLIGHT
+ if (this.HandleCallbackOnUIThread)
+ System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => this.OnSuccess(response));
+ else
+ this.OnSuccess(response);
+#else
+ this.OnSuccess(response);
+#endif
+ }
+
public void HandleError(TResponse response, Exception ex)
{
- if (OnError != null)
- {
- OnError(response, ex);
- }
+ if (this.OnError == null)
+ return;
+
+#if SILVERLIGHT
+ if (this.HandleCallbackOnUIThread)
+ System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => this.OnError(response, ex));
+ else
+ this.OnError(response, ex);
+#else
+ OnError(response, ex);
+#endif
}
public void StartTimer(TimeSpan timeOut)
@@ -122,6 +148,10 @@ public void SetCredentials(string userName, string password)
public StreamDeserializerDelegate StreamDeserializer { get; set; }
+#if SILVERLIGHT
+ public bool HandleCallbackOnUIThread { get; set; }
+#endif
+
public void SendAsync<TResponse>(string httpMethod, string absoluteUrl, object request,
Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
{
@@ -160,6 +190,9 @@ public void SetCredentials(string userName, string password)
Request = request,
OnSuccess = onSuccess,
OnError = onError,
+#if SILVERLIGHT
+ HandleCallbackOnUIThread = HandleCallbackOnUIThread,
+#endif
};
requestState.StartTimer(this.Timeout.GetValueOrDefault(DefaultTimeout));
@@ -301,10 +334,7 @@ private void ReadCallBack<T>(IAsyncResult asyncResult)
response = (T)this.StreamDeserializer(typeof(T), reader);
}
- if (requestState.OnSuccess != null)
- {
- requestState.OnSuccess(response);
- }
+ requestState.HandleSuccess(response);
}
catch (Exception ex)
{
@@ -381,4 +411,5 @@ private void HandleResponseError<TResponse>(Exception exception, RequestState<TR
public void Dispose() { }
}
+
}
View
495 src/ServiceStack.Common/ServiceClient.Web/ServiceClientBase.cs
@@ -1,8 +1,6 @@
using System;
using System.IO;
using System.Net;
-using System.Text;
-using ServiceStack.Common.Web;
using ServiceStack.Logging;
using ServiceStack.Service;
using ServiceStack.ServiceHost;
@@ -10,14 +8,17 @@
namespace ServiceStack.ServiceClient.Web
{
-#if !SILVERLIGHT
/**
* Need to provide async request options
* http://msdn.microsoft.com/en-us/library/86wf6409(VS.71).aspx
*/
public abstract class ServiceClientBase
+#if !SILVERLIGHT
: IServiceClient, IRestClient
+#else
+ : IServiceClient
+#endif
{
private static readonly ILog log = LogManager.GetLogger(typeof(ServiceClientBase));
@@ -41,6 +42,10 @@ protected ServiceClientBase()
StreamDeserializer = StreamDeserializer,
CookieContainer = this.CookieContainer,
};
+
+#if SILVERLIGHT
+ asyncClient.HandleCallbackOnUIThread = this.HandleCallbackOnUIThread = true;
+#endif
this.StoreCookies = true;
}
@@ -98,7 +103,18 @@ public void SetCredentials(string userName, string password)
public string HttpMethod { get; set; }
+#if !SILVERLIGHT
public IWebProxy Proxy { get; set; }
+#endif
+
+#if SILVERLIGHT
+ private bool _handleCallbackOnUiThread;
+ public bool HandleCallbackOnUIThread
+ {
+ get { return this._handleCallbackOnUiThread; }
+ set { asyncClient.HandleCallbackOnUIThread = this._handleCallbackOnUiThread = value; }
+ }
+#endif
private ICredentials credentials;
@@ -147,6 +163,7 @@ public bool StoreCookies
public abstract StreamDeserializerDelegate StreamDeserializer { get; }
+#if !SILVERLIGHT
public virtual TResponse Send<TResponse>(object request)
{
var requestUri = this.SyncReplyBaseUri.WithTrailingSlash() + request.GetType().Name;
@@ -313,6 +330,67 @@ private WebRequest SendRequest(string httpMethod, string requestUri, object requ
}
return client;
}
+#else
+ private void SendRequest(string requestUri, object request, Action<WebRequest> callback)
+ {
+ var isHttpGet = HttpMethod != null && HttpMethod.ToUpper() == "GET";
+ if (isHttpGet)
+ {
+ var queryString = QueryStringSerializer.SerializeToString(request);
+ if (!string.IsNullOrEmpty(queryString))
+ {
+ requestUri += "?" + queryString;
+ }
+ }
+
+ SendRequest(HttpMethod ?? DefaultHttpMethod, requestUri, request, callback);
+ }
+
+ private void SendRequest(string httpMethod, string requestUri, object request, Action<WebRequest> callback)
+ {
+ if (httpMethod == null)
+ throw new ArgumentNullException("httpMethod");
+
+ var client = (HttpWebRequest)WebRequest.Create(requestUri);
+ try
+ {
+ client.Accept = ContentType;
+ client.Method = httpMethod;
+
+ if (this.credentials != null) client.Credentials = this.credentials;
+ if (this.AlwaysSendBasicAuthHeader) client.AddBasicAuth(this.UserName, this.Password);
+
+ if (StoreCookies)
+ {
+ client.CookieContainer = CookieContainer;
+ }
+
+ if (this.LocalHttpWebRequestFilter != null)
+ LocalHttpWebRequestFilter(client);
+
+ if (HttpWebRequestFilter != null)
+ HttpWebRequestFilter(client);
+
+ if (httpMethod != Web.HttpMethod.Get
+ && httpMethod != Web.HttpMethod.Delete)
+ {
+ client.ContentType = ContentType;
+
+ client.BeginGetRequestStream(delegate(IAsyncResult target)
+ {
+ var webReq = (HttpWebRequest)target.AsyncState;
+ var requestStream = webReq.EndGetRequestStream(target);
+ SerializeToStream(null, request, requestStream);
+ callback(client);
+ }, null);
+ }
+ }
+ catch (AuthenticationException ex)
+ {
+ throw WebRequestUtils.CreateCustomException(requestUri, ex) ?? ex;
+ }
+ }
+#endif
private string GetUrl(string relativeOrAbsoluteUrl)
{
@@ -322,6 +400,7 @@ private string GetUrl(string relativeOrAbsoluteUrl)
: this.BaseUri + relativeOrAbsoluteUrl;
}
+#if !SILVERLIGHT
private byte[] DownloadBytes(string requestUri, object request)
{
var webRequest = SendRequest(requestUri, request);
@@ -329,6 +408,24 @@ private byte[] DownloadBytes(string requestUri, object request)
using (var stream = response.GetResponseStream())
return stream.ReadFully();
}
+#else
+ private void DownloadBytes(string requestUri, object request, Action<byte[]> callback = null)
+ {
+ SendRequest(requestUri, request, webRequest => webRequest.BeginGetResponse(delegate(IAsyncResult result)
+ {
+ var webReq = (HttpWebRequest)result.AsyncState;
+ var response = (HttpWebResponse)webReq.EndGetResponse(result);
+ using (var stream = response.GetResponseStream())
+ {
+ var bytes = stream.ReadFully();
+ if (callback != null)
+ {
+ callback(bytes);
+ }
+ }
+ }, null));
+ }
+#endif
public void SendOneWay(object request)
{
@@ -368,7 +465,7 @@ public void PutAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Ac
asyncClient.SendAsync(Web.HttpMethod.Put, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
}
-
+#if !SILVERLIGHT
public virtual TResponse Send<TResponse>(string httpMethod, string relativeOrAbsoluteUrl, object request)
{
var requestUri = GetUrl(relativeOrAbsoluteUrl);
@@ -473,396 +570,8 @@ public TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, Stream fileTo
throw;
}
}
+#endif
public void Dispose() { }
}
-#else
- public abstract class ServiceClientBase
- : IServiceClient, IRestClient
- {
- private static readonly ILog log = LogManager.GetLogger(typeof(ServiceClientBase));
-
- /// <summary>
- /// The request filter is called before any request.
- /// This request filter is executed globally.
- /// </summary>
- public static Action<HttpWebRequest> HttpWebRequestFilter { get; set; }
-
- public const string DefaultHttpMethod = "POST";
-
- readonly AsyncServiceClient asyncClient;
-
- protected ServiceClientBase()
- {
- this.HttpMethod = DefaultHttpMethod;
- this.CookieContainer = new CookieContainer();
- asyncClient = new AsyncServiceClient {
- ContentType = ContentType,
- StreamSerializer = SerializeToStream,
- StreamDeserializer = StreamDeserializer,
- CookieContainer = this.CookieContainer,
- };
- this.StoreCookies = true;
- }
-
- protected ServiceClientBase(string syncReplyBaseUri, string asyncOneWayBaseUri)
- : this()
- {
- this.SyncReplyBaseUri = syncReplyBaseUri;
- this.AsyncOneWayBaseUri = asyncOneWayBaseUri;
- }
-
- public void SetBaseUri(string baseUri, string format)
- {
- this.BaseUri = baseUri;
- this.SyncReplyBaseUri = baseUri.WithTrailingSlash() + format + "/syncreply/";
- this.AsyncOneWayBaseUri = baseUri.WithTrailingSlash() + format + "/asynconeway/";
- }
-
- /// <summary>
- /// The user name for basic authentication
- /// </summary>
- public string UserName { get; set; }
-
- /// <summary>
- /// The password for basic authentication
- /// </summary>
- public string Password { get; set; }
-
- /// <summary>
- /// Sets the username and the password for basic authentication.
- /// </summary>
- public void SetCredentials(string userName, string password)
- {
- this.UserName = userName;
- this.Password = password;
- }
-
- public string BaseUri { get; set; }
-
- public string SyncReplyBaseUri { get; set; }
-
- public string AsyncOneWayBaseUri { get; set; }
-
- private TimeSpan? timeout;
- public TimeSpan? Timeout
- {
- get { return this.timeout; }
- set
- {
- this.timeout = value;
- this.asyncClient.Timeout = value;
- }
- }
-
- public abstract string ContentType { get; }
-
- public string HttpMethod { get; set; }
-
- //public IWebProxy Proxy { get; set; }
-
- private ICredentials credentials;
-
- /// <summary>
- /// Gets or sets authentication information for the request.
- /// Warning: It's recommened to use <see cref="UserName"/> and <see cref="Password"/> for basic auth.
- /// This property is only used for IIS level authentication.
- /// </summary>
- public ICredentials Credentials
- {
- set
- {
- this.credentials = value;
- this.asyncClient.Credentials = value;
- }
- }
-
- /// <summary>
- /// Determines if the basic auth header should be sent with every request.
- /// By default, the basic auth header is only sent when "401 Unauthorized" is returned.
- /// </summary>
- public bool AlwaysSendBasicAuthHeader { get; set; }
-
- /// <summary>
- /// Specifies if cookies should be stored
- /// </summary>
- private bool storeCookies;
- public bool StoreCookies
- {
- get { return storeCookies; }
- set { asyncClient.StoreCookies = storeCookies = value; }
- }
-
- public CookieContainer CookieContainer { get; set; }
-
- /// <summary>
- /// The request filter is called before any request.
- /// This request filter only works with the instance where it was set (not global).
- /// </summary>
- public Action<HttpWebRequest> LocalHttpWebRequestFilter { get; set; }
-
- public abstract void SerializeToStream(IRequestContext requestContext, object request, Stream stream);
-
- public abstract T DeserializeFromStream<T>(Stream stream);
-
- public abstract StreamDeserializerDelegate StreamDeserializer { get; }
-
- public void Dispose() { }
-
- /*
- private bool HandleResponseException<TResponse>(Exception ex, string httpMethod, string requestUri, object request, out TResponse response)
- {
- try
- {
- if (WebRequestUtils.ShouldAuthenticate(ex, this.UserName, this.Password))
- {
- var client = SendRequest(httpMethod, requestUri, request);
- client.AddBasicAuth(this.UserName, this.Password);
-
- try
- {
- using (var responseStream = client.GetResponse().GetResponseStream())
- {
- response = DeserializeFromStream<TResponse>(responseStream);
- return true;
- }
- }
- catch {
- // Ignore deserializing error exceptions
- }
- }
- }
- catch (Exception subEx)
- {
- // Since we are effectively re-executing the call,
- // the new exception should be shown to the caller rather
- // than the old one.
- // The new exception is either this one or the one thrown
- // by the following method.
- HandleResponseException<TResponse>(subEx, requestUri);
- throw;
- }
-
- // If this doesn't throw, the calling method
- // should rethrow the original exception upon
- // return value of false.
- HandleResponseException<TResponse>(ex, requestUri);
-
- response = default(TResponse);
- return false;
- }
-
- private void HandleResponseException<TResponse>(Exception ex, string requestUri)
- {
- var webEx = ex as WebException;
- if (webEx != null
- // && webEx.Status == WebExceptionStatus.ProtocolError
- )
- {
- var errorResponse = ((HttpWebResponse)webEx.Response);
- log.Error(webEx);
- log.DebugFormat("Status Code : {0}", errorResponse.StatusCode);
- log.DebugFormat("Status Description : {0}", errorResponse.StatusDescription);
-
- var serviceEx = new WebServiceException(errorResponse.StatusDescription)
- {
- StatusCode = (int)errorResponse.StatusCode,
- StatusDescription = errorResponse.StatusDescription,
- };
-
- try
- {
- using (var stream = errorResponse.GetResponseStream())
- {
- serviceEx.ResponseDto = DeserializeFromStream<TResponse>(stream);
- }
- }
- catch (Exception innerEx)
- {
- // Oh, well, we tried
- throw new WebServiceException(errorResponse.StatusDescription, innerEx)
- {
- StatusCode = (int)errorResponse.StatusCode,
- StatusDescription = errorResponse.StatusDescription,
- };
- }
-
- //Escape deserialize exception handling and throw here
- throw serviceEx;
- }
-
- var authEx = ex as AuthenticationException;
- if (authEx != null)
- {
- throw WebRequestUtils.CreateCustomException(requestUri, authEx);
- }
- }
-*/
-
- private void SendRequest(string requestUri, object request, Action<WebRequest> callback)
- {
- var isHttpGet = HttpMethod != null && HttpMethod.ToUpper() == "GET";
- if (isHttpGet)
- {
- var queryString = QueryStringSerializer.SerializeToString(request);
- if (!string.IsNullOrEmpty(queryString))
- {
- requestUri += "?" + queryString;
- }
- }
-
- SendRequest(HttpMethod ?? DefaultHttpMethod, requestUri, request, callback);
- }
-
- private void SendRequest(string httpMethod, string requestUri, object request, Action<WebRequest> callback)
- {
- if (httpMethod == null)
- throw new ArgumentNullException("httpMethod");
-
- var client = (HttpWebRequest)WebRequest.Create(requestUri);
- try
- {
- client.Accept = ContentType;
- client.Method = httpMethod;
-
- if (this.credentials != null) client.Credentials = this.credentials;
- if (this.AlwaysSendBasicAuthHeader) client.AddBasicAuth(this.UserName, this.Password);
-
- if (StoreCookies)
- {
- client.CookieContainer = CookieContainer;
- }
-
- if (this.LocalHttpWebRequestFilter != null)
- LocalHttpWebRequestFilter(client);
-
- if (HttpWebRequestFilter != null)
- HttpWebRequestFilter(client);
-
- if (httpMethod != Web.HttpMethod.Get
- && httpMethod != Web.HttpMethod.Delete)
- {
- client.ContentType = ContentType;
-
- client.BeginGetRequestStream(delegate(IAsyncResult target)
- {
- var webReq = (HttpWebRequest)target.AsyncState;
- var requestStream = webReq.EndGetRequestStream(target);
- SerializeToStream(null, request, requestStream);
- callback(client);
- }, null);
- }
- }
- catch (AuthenticationException ex)
- {
- throw WebRequestUtils.CreateCustomException(requestUri, ex) ?? ex;
- }
- }
-
- private string GetUrl(string relativeOrAbsoluteUrl)
- {
- return relativeOrAbsoluteUrl.StartsWith("http:")
- || relativeOrAbsoluteUrl.StartsWith("https:")
- ? relativeOrAbsoluteUrl
- : this.BaseUri + relativeOrAbsoluteUrl;
- }
-
- private void DownloadBytes(string requestUri, object request, Action<byte[]> callback = null)
- {
- SendRequest(requestUri, request, webRequest => webRequest.BeginGetResponse(delegate(IAsyncResult result)
- {
- var webReq = (HttpWebRequest)result.AsyncState;
- var response = (HttpWebResponse)webReq.EndGetResponse(result);
- using (var stream = response.GetResponseStream())
- {
- var bytes = stream.ReadFully();
- if (callback != null)
- {
- callback(bytes);
- }
- }
- }, null));
- }
-
- public void SendOneWay(object request)
- {
- var requestUri = this.AsyncOneWayBaseUri.WithTrailingSlash() + request.GetType().Name;
- DownloadBytes(requestUri, request);
- }
-
- public void SendOneWay(string relativeOrAbsoluteUrl, object request)
- {
- var requestUri = GetUrl(relativeOrAbsoluteUrl);
- DownloadBytes(requestUri, request);
- }
-
- public void SendAsync<TResponse>(object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
- {
- var requestUri = this.SyncReplyBaseUri.WithTrailingSlash() + request.GetType().Name;
- asyncClient.SendAsync(Web.HttpMethod.Post, requestUri, request, onSuccess, onError);
- }
-
- public void GetAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
- {
- asyncClient.SendAsync(Web.HttpMethod.Get, GetUrl(relativeOrAbsoluteUrl), null, onSuccess, onError);
- }
-
- public void DeleteAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
- {
- asyncClient.SendAsync(Web.HttpMethod.Delete, GetUrl(relativeOrAbsoluteUrl), null, onSuccess, onError);
- }
-
- public void PostAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
- {
- asyncClient.SendAsync(Web.HttpMethod.Post, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
- }
-
- public void PutAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
- {
- asyncClient.SendAsync(Web.HttpMethod.Put, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
- }
-
-
- public TResponse Send<TResponse>(object request)
- {
- throw new NotImplementedException();
- }
-
- public TResponse Get<TResponse>(string relativeOrAbsoluteUrl)
- {
- throw new NotImplementedException();
- }
-
- public TResponse Delete<TResponse>(string relativeOrAbsoluteUrl)
- {
- throw new NotImplementedException();
- }
-
- public TResponse Post<TResponse>(string relativeOrAbsoluteUrl, object request)
- {
- throw new NotImplementedException();
- }
-
- public TResponse Put<TResponse>(string relativeOrAbsoluteUrl, object request)
- {
- throw new NotImplementedException();
- }
-
- TResponse IRestClient.PostFile<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, string mimeType)
- {
- throw new NotImplementedException();
- }
-
- TResponse IReplyClient.PostFile<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, string mimeType)
- {
- throw new NotImplementedException();
- }
-
- public TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, string mimeType)
- {
- throw new NotImplementedException();
- }
- }
-
-#endif
}
View
6 src/ServiceStack.Interfaces/Service/IServiceClient.cs
@@ -1,9 +1,11 @@
using System;
-using System.IO;
namespace ServiceStack.Service
{
- public interface IServiceClient : IServiceClientAsync, IOneWayClient, IReplyClient
+ public interface IServiceClient : IServiceClientAsync, IOneWayClient
+#if !SILVERLIGHT
+ , IReplyClient
+#endif
{
}
Please sign in to comment.
Something went wrong with that request. Please try again.