Skip to content

Commit

Permalink
Merge pull request #1112 from rockfordlhotka/1059-httpproxy
Browse files Browse the repository at this point in the history
Enhance HttpProxy to support sync operations, closes #1059
  • Loading branch information
rockfordlhotka committed Apr 4, 2019
2 parents 585b21a + 11b6f13 commit 2a08741
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 5,309 deletions.
121 changes: 71 additions & 50 deletions Source/Csla.Shared/DataPortalClient/HttpProxy.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#if !NETFX_PHONE && !PCL259 || PCL46
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// <copyright file="HttpProxy.cs" company="Marimer LLC">
// Copyright (c) Marimer LLC. All rights reserved.
// Website: http://www.lhotka.net/cslanet/
Expand All @@ -10,10 +9,9 @@
using Csla.Serialization.Mobile;
using Csla.Server;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -25,17 +23,11 @@ namespace Csla.DataPortalClient
/// </summary>
public class HttpProxy : IDataPortalProxy
{
private int _timeoutInMilliseconds = 0;

/// <summary>
/// Gets or sets the HttpClient timeout
/// in milliseconds (0 uses default HttpClient timeout).
/// in milliseconds (0 uses default HttpClient/WebClient timeout).
/// </summary>
public int Timeout
{
get { return _timeoutInMilliseconds; }
set { _timeoutInMilliseconds = value; }
}
public int Timeout { get; set; }

/// <summary>
/// Gets or sets the default URL address
Expand Down Expand Up @@ -85,22 +77,22 @@ public bool IsServerRemote
/// </summary>
public string DataPortalUrl { get; protected set; }

private static HttpClient _client;
private static HttpClient _httpClient;

/// <summary>
/// Gets an HttpClient object for use in
/// communication with the server.
/// </summary>
protected virtual HttpClient GetClient()
protected virtual HttpClient GetHttpClient()
{
if (_client == null) {
_client = new HttpClient();
if (_httpClient == null) {
_httpClient = new HttpClient();
if (this.Timeout > 0) {
_client.Timeout = TimeSpan.FromMilliseconds(this.Timeout);
_httpClient.Timeout = TimeSpan.FromMilliseconds(this.Timeout);
}
}

return _client;
return _httpClient;
}

/// <summary>
Expand All @@ -109,7 +101,16 @@ protected virtual HttpClient GetClient()
/// <param name="client">HttpClient instance.</param>
public static void SetHttpClient(HttpClient client)
{
_client = client;
_httpClient = client;
}

/// <summary>
/// Gets an WebClient object for use in
/// communication with the server.
/// </summary>
protected virtual WebClient GetWebClient()
{
return new DefaultWebClient(this.Timeout);
}

/// <summary>
Expand Down Expand Up @@ -154,17 +155,8 @@ private Csla.Server.Hosts.HttpChannel.UpdateRequest GetBaseUpdateCriteriaRequest
{
request.Principal = MobileFormatter.Serialize(ApplicationContext.User);
}
#if NETCORE || PCL46 || PCL259
request.ClientCulture = System.Globalization.CultureInfo.CurrentCulture.Name;
request.ClientUICulture = System.Globalization.CultureInfo.CurrentUICulture.Name;
#elif NETFX_CORE || NETFX_PHONE
var language = Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Languages[0];
request.ClientCulture = language;
request.ClientUICulture = language;
#else
request.ClientCulture = Thread.CurrentThread.CurrentCulture.Name;
request.ClientUICulture = Thread.CurrentThread.CurrentUICulture.Name;
#endif
return request;
}

Expand All @@ -185,9 +177,6 @@ public async Task<DataPortalResult> Create(Type objectType, object criteria, Dat
DataPortalResult result = null;
try
{
if (isSync)
throw new NotSupportedException("isSync == true");
var client = GetClient();
var request = GetBaseCriteriaRequest();
request.TypeName = AssemblyNameTranslator.GetAssemblyQualifiedName(objectType.AssemblyQualifiedName);
if (!(criteria is IMobileObject))
Expand All @@ -199,7 +188,7 @@ public async Task<DataPortalResult> Create(Type objectType, object criteria, Dat

var serialized = MobileFormatter.Serialize(request);

serialized = await CallDataPortalServer(client, serialized, "create", GetRoutingToken(objectType));
serialized = await CallDataPortalServer(serialized, "create", GetRoutingToken(objectType), isSync);

var response = (Csla.Server.Hosts.HttpChannel.HttpResponse)MobileFormatter.Deserialize(serialized);
response = ConvertResponse(response);
Expand Down Expand Up @@ -245,9 +234,6 @@ public async Task<DataPortalResult> Fetch(Type objectType, object criteria, Data
DataPortalResult result = null;
try
{
if (isSync)
throw new NotSupportedException("isSync == true");
var client = GetClient();
var request = GetBaseCriteriaRequest();
request.TypeName = AssemblyNameTranslator.GetAssemblyQualifiedName(objectType.AssemblyQualifiedName);
if (!(criteria is IMobileObject))
Expand All @@ -259,7 +245,7 @@ public async Task<DataPortalResult> Fetch(Type objectType, object criteria, Data

var serialized = MobileFormatter.Serialize(request);

serialized = await CallDataPortalServer(client, serialized, "fetch", GetRoutingToken(objectType));
serialized = await CallDataPortalServer(serialized, "fetch", GetRoutingToken(objectType), isSync);

var response = (Csla.Server.Hosts.HttpChannel.HttpResponse)MobileFormatter.Deserialize(serialized);
response = ConvertResponse(response);
Expand Down Expand Up @@ -304,16 +290,13 @@ public async Task<DataPortalResult> Update(object obj, DataPortalContext context
DataPortalResult result = null;
try
{
if (isSync)
throw new NotSupportedException("isSync == true");
var client = GetClient();
var request = GetBaseUpdateCriteriaRequest();
request.ObjectData = MobileFormatter.Serialize(obj);
request = ConvertRequest(request);

var serialized = MobileFormatter.Serialize(request);

serialized = await CallDataPortalServer(client, serialized, "update", GetRoutingToken(obj.GetType()));
serialized = await CallDataPortalServer(serialized, "update", GetRoutingToken(obj.GetType()), isSync);

var response = (Csla.Server.Hosts.HttpChannel.HttpResponse)MobileFormatter.Deserialize(serialized);
response = ConvertResponse(response);
Expand Down Expand Up @@ -359,9 +342,7 @@ public async Task<DataPortalResult> Delete(Type objectType, object criteria, Dat
DataPortalResult result = null;
try
{
if (isSync)
throw new NotSupportedException("isSync == true");
var client = GetClient();

var request = GetBaseCriteriaRequest();
request.TypeName = AssemblyNameTranslator.GetAssemblyQualifiedName(objectType.AssemblyQualifiedName);
if (!(criteria is IMobileObject))
Expand All @@ -373,7 +354,7 @@ public async Task<DataPortalResult> Delete(Type objectType, object criteria, Dat

var serialized = MobileFormatter.Serialize(request);

serialized = await CallDataPortalServer(client, serialized, "delete", GetRoutingToken(objectType));
serialized = await CallDataPortalServer(serialized, "delete", GetRoutingToken(objectType), isSync);

var response = (Csla.Server.Hosts.HttpChannel.HttpResponse)MobileFormatter.Deserialize(serialized);
response = ConvertResponse(response);
Expand Down Expand Up @@ -401,8 +382,18 @@ public async Task<DataPortalResult> Delete(Type objectType, object criteria, Dat
return result;
}

private async Task<byte[]> CallDataPortalServer(HttpClient client, byte[] serialized, string operation, string routingToken)
private async Task<byte[]> CallDataPortalServer(byte[] serialized, string operation, string routingToken, bool isSync)
{
if (isSync)
serialized = CallViaWebClient(serialized, operation, routingToken);
else
serialized = await CallViaHttpClient(serialized, operation, routingToken);
return serialized;
}

private async Task<byte[]> CallViaHttpClient(byte[] serialized, string operation, string routingToken)
{
HttpClient client = GetHttpClient();
HttpRequestMessage httpRequest = null;
httpRequest = new HttpRequestMessage(
HttpMethod.Post,
Expand All @@ -420,6 +411,23 @@ private async Task<byte[]> CallDataPortalServer(HttpClient client, byte[] serial
return serialized;
}

private byte[] CallViaWebClient(byte[] serialized, string operation, string routingToken)
{
WebClient client = GetWebClient();
var url = $"{DataPortalUrl}?operation={CreateOperationTag(operation, ApplicationContext.VersionRoutingTag, routingToken)}";
if (UseTextSerialization)
{
var result = client.UploadString(url, System.Convert.ToBase64String(serialized));
serialized = System.Convert.FromBase64String(result);
}
else
{
var result = client.UploadData(url, serialized);
serialized = result;
}
return serialized;
}

private string CreateOperationTag(string operatation, string versionToken, string routingToken)
{
if (!string.IsNullOrWhiteSpace(versionToken) || !string.IsNullOrWhiteSpace(routingToken))
Expand All @@ -437,8 +445,6 @@ private string GetRoutingToken(Type objectType)
return result;
}

#region Extension Method for Requests

/// <summary>
/// Override this method to manipulate the message
/// request data sent to the server.
Expand Down Expand Up @@ -469,7 +475,22 @@ protected virtual Csla.Server.Hosts.HttpChannel.HttpResponse ConvertResponse(Csl
return response;
}

#endregion
private class DefaultWebClient : WebClient
{
private int Timeout { get; set; }

public DefaultWebClient(int timeout)
{
Timeout = timeout;
}

protected override WebRequest GetWebRequest(Uri address)
{
var req = base.GetWebRequest(address);
if (Timeout > 0)
req.Timeout = Timeout;
return req;
}
}
}
}
#endif
}
5 changes: 0 additions & 5 deletions Source/Csla.Shared/Threading/ContextParams.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,8 @@ internal void SetThreadContext()
{
Csla.ApplicationContext.User = User;
Csla.ApplicationContext.SetContext(ClientContext, GlobalContext);
#if NETFX_CORE
// do nothing because we can't set the context on a non-UI thread
// in WinRT or UWP
#else
Thread.CurrentThread.CurrentUICulture = UICulture;
Thread.CurrentThread.CurrentCulture = Culture;
#endif
}
}
}
Binary file removed Source/UpgradeLog2.htm
Binary file not shown.
Loading

0 comments on commit 2a08741

Please sign in to comment.