11using System.Threading.Tasks;
16#if NETSTANDARD2_0 || NET5_0 || NETCORE3_1
18using Microsoft.AspNetCore;
19using Microsoft.AspNetCore.Mvc;
20using System.Collections.Generic;
32#if NETSTANDARD2_0 || NET5_0 || NETCORE3_1
34 public class HttpPortalController : Controller
41 public bool UseTextSerialization {
get;
set; } =
false;
49 public virtual async Task
PostAsync([FromQuery]
string operation)
51 if (operation.Contains(
"/"))
53 var temp = operation.Split(
'/');
58 if (UseTextSerialization)
59 await InvokeTextPortal(operation, Request.Body, Response.Body).ConfigureAwait(
false);
61 await InvokePortal(operation, Request.Body, Response.Body).ConfigureAwait(
false);
65 private static Dictionary<string, string> routingTagUrls =
new Dictionary<string, string>();
66 private static HttpClient _client;
73 protected static Dictionary<string, string> RoutingTagUrls {
get => routingTagUrls;
set => routingTagUrls = value; }
79 protected int HttpClientTimeout {
get;
set; }
85 protected virtual HttpClient GetHttpClient()
89 _client =
new HttpClient();
90 if (this.HttpClientTimeout > 0)
92 _client.Timeout =
TimeSpan.FromMilliseconds(this.HttpClientTimeout);
104 protected virtual async Task
PostAsync(
string operation,
string routingTag)
106 if (RoutingTagUrls.TryGetValue(routingTag, out
string route) && route !=
"localhost")
108 var httpRequest =
new HttpRequestMessage(HttpMethod.Post, $
"{route}?operation={operation}");
109 using (var buffer =
new MemoryStream())
111 await Request.Body.CopyToAsync(buffer);
112 httpRequest.Content =
new ByteArrayContent(buffer.ToArray());
114 var response = await GetHttpClient().SendAsync(httpRequest);
115 await response.Content.CopyToAsync(Response.Body);
119 await
PostAsync(operation).ConfigureAwait(
false);
124 public class HttpPortalController : Controller
132 public virtual async Task<ActionResult>
PostAsync(
string operation)
134 var requestData = Request.BinaryRead(Request.TotalBytes);
135 var responseData = await InvokePortal(operation, requestData).ConfigureAwait(
false);
136 Response.BinaryWrite(responseData);
137 return new EmptyResult();
147 public virtual async Task<HttpResponseMessage>
PostAsync(
string operation)
149 var requestData = await Request.Content.ReadAsByteArrayAsync().ConfigureAwait(
false);
150 var responseData = await InvokePortal(operation, requestData).ConfigureAwait(
false);
151 var response = Request.CreateResponse();
152 response.Content =
new ByteArrayContent(responseData);
172 set { _portal = value; }
175#if NETSTANDARD2_0 || NET5_0 || NETCORE3_1
186 protected virtual void SetHttpResponseHeaders(Microsoft.AspNetCore.Http.HttpResponse response)
189 private async Task InvokePortal(
string operation, Stream requestStream, Stream responseStream)
191 var serializer = SerializationFormatterFactory.GetFormatter();
194 if (UseTextSerialization)
196 Response.Headers.Add(
"Content-type",
"application/base64,text/plain");
200 Response.Headers.Add(
"Content-type",
"application/octet-stream");
202 SetHttpResponseHeaders(Response);
205 var request = serializer.Deserialize(requestStream);
206 result = await CallPortal(operation, request);
208#pragma warning disable CA1031
213#pragma warning restore CA1031
214 var portalResult =
new DataPortalResponse { ErrorData = errorData, GlobalContext = result.GlobalContext, ObjectData = result.ObjectData };
215 serializer.Serialize(responseStream, portalResult);
218 private async Task InvokeTextPortal(
string operation, Stream requestStream, Stream responseStream)
220 string requestString;
221 using (var reader =
new StreamReader(requestStream))
222 requestString = await reader.ReadToEndAsync();
223 var requestArray = System.Convert.FromBase64String(requestString);
224 var requestBuffer =
new MemoryStream(requestArray);
226 var serializer = SerializationFormatterFactory.GetFormatter();
231 var request = serializer.Deserialize(requestBuffer);
232 result = await CallPortal(operation, request);
234#pragma warning disable CA1031
239#pragma warning restore CA1031
240 var portalResult =
new DataPortalResponse { ErrorData = errorData, GlobalContext = result.GlobalContext, ObjectData = result.ObjectData };
242 var responseBuffer =
new MemoryStream();
243 serializer.Serialize(responseBuffer, portalResult);
244 responseBuffer.Position = 0;
245 using var writer =
new StreamWriter(responseStream)
249 await writer.WriteAsync(System.Convert.ToBase64String(responseBuffer.ToArray()));
253 private async Task<byte[]> InvokePortal(
string operation,
byte[] data)
259 var buffer =
new MemoryStream(data)
263 var request = SerializationFormatterFactory.GetFormatter().Deserialize(buffer.ToArray());
264 result = await CallPortal(operation, request);
266#pragma warning disable CA1031
271#pragma warning restore CA1031
272 var portalResult =
new DataPortalResponse { ErrorData = errorData, GlobalContext = result.GlobalContext, ObjectData = result.ObjectData };
273 var bytes = SerializationFormatterFactory.GetFormatter().Serialize(portalResult);
278 private async Task<DataPortalResponse> CallPortal(
string operation,
object request)
283 "create" => await portal.Create((
CriteriaRequest)request).ConfigureAwait(
false),
284 "fetch" => await portal.Fetch((
CriteriaRequest)request).ConfigureAwait(
false),
285 "update" => await portal.Update((
UpdateRequest)request).ConfigureAwait(
false),
286 "delete" => await portal.Delete((
CriteriaRequest)request).ConfigureAwait(
false),
287 _ =>
throw new InvalidOperationException(operation),
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.
Request message for updating a business object.
Exposes server-side DataPortal functionality through HTTP request/response.
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