CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
HttpProxy.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="HttpProxy.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Implements a data portal proxy to relay data portal</summary>
7//-----------------------------------------------------------------------
9using Csla.Properties;
10using System;
11using System.Net;
12using System.Net.Http;
13using System.Text;
14using System.Threading.Tasks;
15
16namespace Csla.Channels.Http
17{
23 {
31 public HttpProxy(ApplicationContext applicationContext, HttpClient httpClient, HttpProxyOptions options)
32 : base(applicationContext)
33 {
34 _httpClient = httpClient;
36 }
37
38 private static HttpClient _httpClient;
39
44 protected virtual HttpClientHandler GetHttpClientHandler()
45 {
46 return new HttpClientHandler();
47 }
48
53 protected virtual HttpClient GetHttpClient()
54 {
55 if (_httpClient == null)
56 {
57 var handler = GetHttpClientHandler();
59 {
60 handler = new HttpClientHandler();
61 }
62 else
63 {
64 handler = new HttpClientHandler()
65 {
66 AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
67 };
68 }
69 _httpClient = new HttpClient(handler);
70 if (Timeout > 0)
71 {
72 _httpClient.Timeout = TimeSpan.FromMilliseconds(this.Timeout);
73 }
74 }
75
76 return _httpClient;
77 }
78
83 protected virtual WebClient GetWebClient()
84 {
85 return new DefaultWebClient(this.Timeout);
86 }
87
93 public static bool UseTextSerialization { get; set; } = false;
94
103 protected override async Task<byte[]> CallDataPortalServer(byte[] serialized, string operation, string routingToken, bool isSync)
104 {
105 return isSync
106 ? CallViaWebClient(serialized, operation, routingToken)
107 : await CallViaHttpClient(serialized, operation, routingToken);
108 }
109
115 protected virtual void SetHttpRequestHeaders(HttpRequestMessage request)
116 { }
117
118 private async Task<byte[]> CallViaHttpClient(byte[] serialized, string operation, string routingToken)
119 {
120 HttpClient client = GetHttpClient();
121 HttpRequestMessage httpRequest;
122 httpRequest = new HttpRequestMessage(
123 HttpMethod.Post,
124 $"{DataPortalUrl}?operation={CreateOperationTag(operation, ApplicationContext.VersionRoutingTag, routingToken)}");
125 SetHttpRequestHeaders(httpRequest);
127 httpRequest.Content = new StringContent(System.Convert.ToBase64String(serialized));
128 else
129 httpRequest.Content = new ByteArrayContent(serialized);
130 var httpResponse = await client.SendAsync(httpRequest);
131 await VerifyResponseSuccess(httpResponse);
133 serialized = Convert.FromBase64String(await httpResponse.Content.ReadAsStringAsync());
134 else
135 serialized = await httpResponse.Content.ReadAsByteArrayAsync();
136 return serialized;
137 }
138
139 private byte[] CallViaWebClient(byte[] serialized, string operation, string routingToken)
140 {
141 if (!WebCallCapabilities.AreSyncWebClientMethodsSupported())
142 {
143 throw new NotSupportedException(Resources.SyncDataAccessNotSupportedException);
144 }
145 WebClient client = GetWebClient();
146 var url = $"{DataPortalUrl}?operation={CreateOperationTag(operation, ApplicationContext.VersionRoutingTag, routingToken)}";
147 try
148 {
150 {
151 var result = client.UploadString(url, System.Convert.ToBase64String(serialized));
152 serialized = System.Convert.FromBase64String(result);
153 }
154 else
155 {
156 var result = client.UploadData(url, serialized);
157 serialized = result;
158 }
159 return serialized;
160 }
161 catch (WebException ex)
162 {
163 string message;
164 using (var reader = new System.IO.StreamReader(ex.Response.GetResponseStream()))
165 message = reader.ReadToEnd();
166 throw new DataPortalException(message, ex);
167 }
168 }
169
170 private static async Task VerifyResponseSuccess(HttpResponseMessage httpResponse)
171 {
172 if (!httpResponse.IsSuccessStatusCode)
173 {
174 var message = new StringBuilder();
175 message.Append((int)httpResponse.StatusCode);
176 message.Append(": ");
177 message.Append(httpResponse.ReasonPhrase);
178 var content = await httpResponse.Content.ReadAsStringAsync();
179 if (!string.IsNullOrWhiteSpace(content))
180 {
181 message.AppendLine();
182 message.Append(content);
183 }
184 throw new HttpRequestException(message.ToString());
185 }
186 }
187
188 private string CreateOperationTag(string operatation, string versionToken, string routingToken)
189 {
190 if (!string.IsNullOrWhiteSpace(versionToken) || !string.IsNullOrWhiteSpace(routingToken))
191 return $"{operatation}/{routingToken}-{versionToken}";
192 return operatation;
193 }
194
195#pragma warning disable SYSLIB0014
196 private class DefaultWebClient : WebClient
197 {
198 private int Timeout { get; set; }
199
200 public DefaultWebClient(int timeout) => Timeout = timeout;
201
202 protected override WebRequest GetWebRequest(Uri address)
203 {
204 var req = base.GetWebRequest(address) as HttpWebRequest;
205 if (Timeout > 0)
206 req.Timeout = Timeout;
207 return req;
208 }
209 }
210#pragma warning restore SYSLIB0014
211 }
212}
Provides consistent context information between the client and server DataPortal objects.
Implements a data portal proxy to relay data portal calls to a remote application server by using htt...
Definition: HttpProxy.cs:23
virtual WebClient GetWebClient()
Gets an WebClient object for use in communication with the server.
Definition: HttpProxy.cs:83
virtual HttpClientHandler GetHttpClientHandler()
Gets an HttpClientHandler for use in initializing the HttpClient instance.
Definition: HttpProxy.cs:44
override async Task< byte[]> CallDataPortalServer(byte[] serialized, string operation, string routingToken, bool isSync)
Select client to make request based on isSync parameter and return response from server
Definition: HttpProxy.cs:103
virtual void SetHttpRequestHeaders(HttpRequestMessage request)
Override to set headers or other properties of the HttpRequestMessage before it is sent to the server...
Definition: HttpProxy.cs:115
virtual HttpClient GetHttpClient()
Gets an HttpClient object for use in communication with the server.
Definition: HttpProxy.cs:53
static bool UseTextSerialization
Gets or sets a value indicating whether to use text/string serialization instead of the default binar...
Definition: HttpProxy.cs:93
HttpProxy(ApplicationContext applicationContext, HttpClient httpClient, HttpProxyOptions options)
Creates an instance of the type, initializing it to use the supplied HttpClient object and options.
Definition: HttpProxy.cs:31
string DataPortalUrl
Data portal server endpoint URL
Implements a data portal proxy to relay data portal calls to a remote application server.
virtual int Timeout
Gets or sets the Client timeout in milliseconds (0 uses default timeout).
string DataPortalUrl
Gets the URL address for the data portal server used by this proxy instance.
A strongly-typed resource class, for looking up localized strings, etc.
static string SyncDataAccessNotSupportedException
Looks up a localized string similar to Synchronous data access is not supported on this runtime.