11using System.Threading.Tasks;
16#if NETSTANDARD2_0 || NET5_0_OR_GREATER || NETCOREAPP3_1
20using System.Collections.Generic;
32#if NETSTANDARD2_0 || NET5_0_OR_GREATER || NETCOREAPP3_1
34 public class HttpPortalController : Controller
36 private ApplicationContext ApplicationContext {
get;
set; }
44 ApplicationContext = applicationContext;
52 public bool UseTextSerialization {
get;
set; } =
false;
60 public virtual async Task
PostAsync([FromQuery]
string operation)
62 if (operation.Contains(
"/"))
64 var temp = operation.Split(
'/');
69 if (UseTextSerialization)
70 await InvokeTextPortal(operation, Request.Body, Response.Body).ConfigureAwait(
false);
72 await InvokePortal(operation, Request.Body, Response.Body).ConfigureAwait(
false);
76 private static Dictionary<string, string> routingTagUrls =
new Dictionary<string, string>();
77 private static HttpClient _client;
84 protected static Dictionary<string, string> RoutingTagUrls {
get => routingTagUrls;
set => routingTagUrls = value; }
90 protected int HttpClientTimeout {
get;
set; }
96 protected virtual HttpClient GetHttpClient()
100 _client =
new HttpClient();
101 if (this.HttpClientTimeout > 0)
103 _client.Timeout =
TimeSpan.FromMilliseconds(this.HttpClientTimeout);
115 protected virtual async Task
PostAsync(
string operation,
string routingTag)
117 if (RoutingTagUrls.TryGetValue(routingTag, out
string route) && route !=
"localhost")
119 var httpRequest =
new HttpRequestMessage(HttpMethod.Post, $
"{route}?operation={operation}");
120 using (var buffer =
new MemoryStream())
122 await Request.Body.CopyToAsync(buffer);
123 httpRequest.Content =
new ByteArrayContent(buffer.ToArray());
125 var response = await GetHttpClient().SendAsync(httpRequest);
126 await response.Content.CopyToAsync(Response.Body);
130 await
PostAsync(operation).ConfigureAwait(
false);
152 public virtual async Task<HttpResponseMessage>
PostAsync(
string operation)
154 var requestData = await Request.Content.ReadAsByteArrayAsync().ConfigureAwait(
false);
155 var responseData = await InvokePortal(operation, requestData).ConfigureAwait(
false);
156 var response = Request.CreateResponse();
157 response.Content =
new ByteArrayContent(responseData);
177 set { _portal = value; }
180#if NETSTANDARD2_0 || NET5_0_OR_GREATER || NETCOREAPP3_1
191 protected virtual void SetHttpResponseHeaders(
Microsoft.AspNetCore.Http.HttpResponse response)
194 private async Task InvokePortal(
string operation, Stream requestStream, Stream responseStream)
199 if (UseTextSerialization)
201 Response.Headers.Add(
"Content-type",
"application/base64,text/plain");
205 Response.Headers.Add(
"Content-type",
"application/octet-stream");
207 SetHttpResponseHeaders(Response);
210 var request = serializer.Deserialize(requestStream);
211 result = await CallPortal(operation, request);
213#pragma warning disable CA1031
216 errorData = ApplicationContext.CreateInstance<
DataPortalErrorInfo>(ApplicationContext, ex);
218#pragma warning restore CA1031
221 portalResult.ObjectData = result.ObjectData;
222 serializer.Serialize(responseStream, portalResult);
225 private async Task InvokeTextPortal(
string operation, Stream requestStream, Stream responseStream)
227 string requestString;
228 using (var reader =
new StreamReader(requestStream))
229 requestString = await reader.ReadToEndAsync();
230 var requestArray = System.Convert.FromBase64String(requestString);
231 var requestBuffer =
new MemoryStream(requestArray);
233 var serializer = SerializationFormatterFactory.GetFormatter(ApplicationContext);
238 var request = serializer.Deserialize(requestBuffer);
239 result = await CallPortal(operation, request);
241#pragma warning disable CA1031
244 errorData = ApplicationContext.CreateInstance<
DataPortalErrorInfo>(ApplicationContext, ex);
246#pragma warning restore CA1031
249 portalResult.ObjectData = result.ObjectData;
251 var responseBuffer =
new MemoryStream();
252 serializer.Serialize(responseBuffer, portalResult);
253 responseBuffer.Position = 0;
254 using var writer =
new StreamWriter(responseStream)
258 await writer.WriteAsync(System.Convert.ToBase64String(responseBuffer.ToArray()));
262 private async Task<byte[]> InvokePortal(
string operation,
byte[] data)
268 var buffer =
new MemoryStream(data)
272 var request = SerializationFormatterFactory.GetFormatter(ApplicationContext).Deserialize(buffer.ToArray());
273 result = await CallPortal(operation, request);
275#pragma warning disable CA1031
278 errorData = ApplicationContext.CreateInstance<
DataPortalErrorInfo>(ApplicationContext, ex);
280#pragma warning restore CA1031
283 portalResult.ObjectData = result.ObjectData;
284 var bytes = SerializationFormatterFactory.GetFormatter(ApplicationContext).Serialize(portalResult);
289 private async Task<DataPortalResponse> CallPortal(
string operation,
object request)
294 "create" => await portal.Create((
CriteriaRequest)request).ConfigureAwait(
false),
295 "fetch" => await portal.Fetch((
CriteriaRequest)request).ConfigureAwait(
false),
296 "update" => await portal.Update((
UpdateRequest)request).ConfigureAwait(
false),
297 "delete" => await portal.Delete((
CriteriaRequest)request).ConfigureAwait(
false),
298 _ =>
throw new InvalidOperationException(operation),
Provides consistent context information between the client and server DataPortal objects.
object CreateInstanceDI(Type objectType, params object[] parameters)
Creates an object using 'Activator.CreateInstance' using service provider (if one is available) to po...
Message sent to the WCF data portal.
Message containing details about any server-side exception.
Response message for returning the results of a data portal call.
DataPortalErrorInfo ErrorData
Server-side exception data if an exception occurred on the server.
Request message for updating a business object.
Exposes server-side DataPortal functionality through HTTP request/response.
HttpPortalController(ApplicationContext applicationContext)
Creates an instance of the type.
HttpPortal Portal
Gets or sets the HttpPortal implementation used to coordinate the data portal operations.
virtual async Task< HttpResponseMessage > PostAsync(string operation)
Entry point for all data portal operations.
Exposes server-side DataPortal functionality through HTTP request/response.
@ TimeSpan
TimeSpan - time span