Feature/send http request (#3355)
* Implemented send http request activity * Implemented checkbox input and updated send http request activity * Updated value of mime types constants
This commit is contained in:
parent
b9864a25fa
commit
0cd01c687b
|
|
@ -67,6 +67,7 @@ services
|
|||
.AddActivity<Switch>()
|
||||
.AddActivity<RunJavaScript>()
|
||||
.AddActivity<Event>()
|
||||
.AddActivity<SendHttpRequest>()
|
||||
)
|
||||
.Use<IdentityFeature>(identity =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -79,6 +79,9 @@ export namespace Components {
|
|||
interface ElsaCheckListInput {
|
||||
"inputContext": ActivityInputContext;
|
||||
}
|
||||
interface ElsaCheckboxInput {
|
||||
"inputContext": ActivityInputContext;
|
||||
}
|
||||
interface ElsaCodeEditorInput {
|
||||
"inputContext": ActivityInputContext;
|
||||
}
|
||||
|
|
@ -358,6 +361,12 @@ declare global {
|
|||
prototype: HTMLElsaCheckListInputElement;
|
||||
new (): HTMLElsaCheckListInputElement;
|
||||
};
|
||||
interface HTMLElsaCheckboxInputElement extends Components.ElsaCheckboxInput, HTMLStencilElement {
|
||||
}
|
||||
var HTMLElsaCheckboxInputElement: {
|
||||
prototype: HTMLElsaCheckboxInputElement;
|
||||
new (): HTMLElsaCheckboxInputElement;
|
||||
};
|
||||
interface HTMLElsaCodeEditorInputElement extends Components.ElsaCodeEditorInput, HTMLStencilElement {
|
||||
}
|
||||
var HTMLElsaCodeEditorInputElement: {
|
||||
|
|
@ -650,6 +659,7 @@ declare global {
|
|||
"elsa-button-group": HTMLElsaButtonGroupElement;
|
||||
"elsa-canvas": HTMLElsaCanvasElement;
|
||||
"elsa-check-list-input": HTMLElsaCheckListInputElement;
|
||||
"elsa-checkbox-input": HTMLElsaCheckboxInputElement;
|
||||
"elsa-code-editor-input": HTMLElsaCodeEditorInputElement;
|
||||
"elsa-context-menu": HTMLElsaContextMenuElement;
|
||||
"elsa-copy-button": HTMLElsaCopyButtonElement;
|
||||
|
|
@ -739,6 +749,9 @@ declare namespace LocalJSX {
|
|||
interface ElsaCheckListInput {
|
||||
"inputContext"?: ActivityInputContext;
|
||||
}
|
||||
interface ElsaCheckboxInput {
|
||||
"inputContext"?: ActivityInputContext;
|
||||
}
|
||||
interface ElsaCodeEditorInput {
|
||||
"inputContext"?: ActivityInputContext;
|
||||
}
|
||||
|
|
@ -980,6 +993,7 @@ declare namespace LocalJSX {
|
|||
"elsa-button-group": ElsaButtonGroup;
|
||||
"elsa-canvas": ElsaCanvas;
|
||||
"elsa-check-list-input": ElsaCheckListInput;
|
||||
"elsa-checkbox-input": ElsaCheckboxInput;
|
||||
"elsa-code-editor-input": ElsaCodeEditorInput;
|
||||
"elsa-context-menu": ElsaContextMenu;
|
||||
"elsa-copy-button": ElsaCopyButton;
|
||||
|
|
@ -1042,6 +1056,7 @@ declare module "@stencil/core" {
|
|||
"elsa-button-group": LocalJSX.ElsaButtonGroup & JSXBase.HTMLAttributes<HTMLElsaButtonGroupElement>;
|
||||
"elsa-canvas": LocalJSX.ElsaCanvas & JSXBase.HTMLAttributes<HTMLElsaCanvasElement>;
|
||||
"elsa-check-list-input": LocalJSX.ElsaCheckListInput & JSXBase.HTMLAttributes<HTMLElsaCheckListInputElement>;
|
||||
"elsa-checkbox-input": LocalJSX.ElsaCheckboxInput & JSXBase.HTMLAttributes<HTMLElsaCheckboxInputElement>;
|
||||
"elsa-code-editor-input": LocalJSX.ElsaCodeEditorInput & JSXBase.HTMLAttributes<HTMLElsaCodeEditorInputElement>;
|
||||
"elsa-context-menu": LocalJSX.ElsaContextMenu & JSXBase.HTMLAttributes<HTMLElsaContextMenuElement>;
|
||||
"elsa-copy-button": LocalJSX.ElsaCopyButton & JSXBase.HTMLAttributes<HTMLElsaCopyButtonElement>;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
import {FunctionalComponent, h} from '@stencil/core';
|
||||
import {ActivityIconSettings, getActivityIconCssClass} from "./models";
|
||||
|
||||
export const SendHttpRequestIcon: FunctionalComponent<ActivityIconSettings> = (settings) => (
|
||||
<svg class={getActivityIconCssClass(settings)} width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"
|
||||
fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z"/>
|
||||
<circle cx="12" cy="12" r="9"/>
|
||||
<line x1="3.6" y1="9" x2="20.4" y2="9"/>
|
||||
<line x1="3.6" y1="15" x2="20.4" y2="15"/>
|
||||
<path d="M11.5 3a17 17 0 0 0 0 18"/>
|
||||
<path d="M12.5 3a17 17 0 0 1 0 18"/>
|
||||
</svg>
|
||||
);
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import {Component, Prop, h, State} from '@stencil/core';
|
||||
import {LiteralExpression, SyntaxNames} from "../../models";
|
||||
import {ActivityInputContext} from "../../services/node-input-driver";
|
||||
import {getInputPropertyValue } from "../../utils";
|
||||
import {ExpressionChangedArs} from "../designer/input-control-switch/input-control-switch";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-checkbox-input',
|
||||
shadow: false
|
||||
})
|
||||
export class Checkbox {
|
||||
@Prop() public inputContext: ActivityInputContext;
|
||||
@State() private isChecked?: boolean;
|
||||
|
||||
public async componentWillLoad() {
|
||||
this.isChecked = this.getSelectedValue();
|
||||
}
|
||||
|
||||
private getSelectedValue = (): boolean => {
|
||||
const input = getInputPropertyValue(this.inputContext);
|
||||
return (input?.expression as LiteralExpression)?.value;
|
||||
};
|
||||
|
||||
render() {
|
||||
const inputContext = this.inputContext;
|
||||
const inputDescriptor = inputContext.inputDescriptor;
|
||||
const fieldName = inputDescriptor.name;
|
||||
const fieldId = inputDescriptor.name;
|
||||
const displayName = inputDescriptor.displayName;
|
||||
const hint = inputDescriptor.description;
|
||||
const input = getInputPropertyValue(inputContext);
|
||||
const value = (input?.expression as LiteralExpression)?.value;
|
||||
const syntax = input?.expression?.type ?? inputDescriptor.defaultSyntax;
|
||||
const isChecked = this.isChecked;
|
||||
|
||||
return (
|
||||
<elsa-input-control-switch label={displayName} hint={hint} syntax={syntax} expression={value}
|
||||
onExpressionChanged={this.onExpressionChanged}>
|
||||
<input type="checkbox" name={fieldName} id={fieldId} value={value} checked={isChecked} onChange={this.onPropertyEditorChanged}/>
|
||||
</elsa-input-control-switch>
|
||||
);
|
||||
}
|
||||
|
||||
private onPropertyEditorChanged = (e: Event) => {
|
||||
const inputElement = e.target as HTMLInputElement;
|
||||
this.isChecked = inputElement.checked;
|
||||
this.inputContext.inputChanged(inputElement.checked, SyntaxNames.Literal);
|
||||
}
|
||||
|
||||
private onExpressionChanged = (e: CustomEvent<ExpressionChangedArs>) => {
|
||||
debugger;
|
||||
this.inputContext.inputChanged(e.detail.expression, e.detail.syntax);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import {
|
|||
} from "../components/icons/activities";
|
||||
import {WriteHttpResponseIcon} from "../components/icons/activities/write-http-response";
|
||||
import {FlowJoinIcon} from "../components/icons/activities/flow-join";
|
||||
import {SendHttpRequestIcon} from "../components/icons/activities/send-http-request"
|
||||
|
||||
export type ActivityType = string;
|
||||
export type ActivityIcon = (ActivityIconSettings?) => any;
|
||||
|
|
@ -39,6 +40,7 @@ export class ActivityIconRegistry {
|
|||
this.add('Elsa.Event', settings => <EventIcon size={settings?.size}/>);
|
||||
this.add('Elsa.RunJavaScript', settings => <RunJavaScriptIcon size={settings?.size}/>);
|
||||
this.add('Elsa.FlowJoin', settings => <FlowJoinIcon size={settings?.size}/>);
|
||||
this.add('Elsa.SendHttpRequest', settings => <SendHttpRequestIcon size={settings?.size}/>);
|
||||
}
|
||||
|
||||
public add(activityType: ActivityType, icon: ActivityIcon) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export class InputControlRegistry {
|
|||
this.add('radio-list', c => <elsa-radio-list-input inputContext={c}/>);
|
||||
this.add('multi-text', c => <elsa-multi-text-input inputContext={c}/>);
|
||||
this.add('code-editor', c => <elsa-code-editor-input inputContext={c}/>);
|
||||
this.add('checkbox', c => <elsa-checkbox-input inputContext={c}/>);
|
||||
}
|
||||
|
||||
public add(uiHint: UIHint, control: RenderActivityPropInputControl) {
|
||||
|
|
|
|||
153
src/modules/Elsa.Http/Activities/SendHttpRequest.cs
Normal file
153
src/modules/Elsa.Http/Activities/SendHttpRequest.cs
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Http.ContentWriters;
|
||||
using Elsa.Http.Models;
|
||||
using Elsa.Http.Parsers;
|
||||
using Elsa.Workflows.Core.Attributes;
|
||||
using Elsa.Workflows.Core.Models;
|
||||
using Elsa.Workflows.Management.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using HttpRequestHeaders = Elsa.Http.Models.HttpRequestHeaders;
|
||||
|
||||
namespace Elsa.Http;
|
||||
|
||||
[Activity("Elsa", "HTTP", "Send Http Request.", DisplayName = "Send HTTP Request")]
|
||||
public class SendHttpRequest : Activity
|
||||
{
|
||||
[Input]
|
||||
public Input<Uri?> Url { get; set; } = default!;
|
||||
|
||||
[Input(
|
||||
Options = new[] {"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"},
|
||||
UIHint = InputUIHints.Dropdown
|
||||
)]
|
||||
public Input<string?> Method { get; set; }
|
||||
|
||||
public Input<string?> Content { get; set; } = default!;
|
||||
|
||||
[Input(
|
||||
Options = new[] { "", "text/plain", "text/html", "application/json", "application/xml", "application/x-www-form-urlencoded" },
|
||||
UIHint = InputUIHints.Dropdown
|
||||
)]
|
||||
public Input<string?> ContentType { get; set; } = default!;
|
||||
|
||||
[Input(Category = "Security")]
|
||||
public Input<string?> Authorization { get; set; } = default!;
|
||||
|
||||
public Input<bool> ReadContent { get; set; } = new(false);
|
||||
|
||||
[Input(
|
||||
Options = new[] { "", "JsonElement", "Plain Text" },
|
||||
UIHint = InputUIHints.Dropdown
|
||||
)]
|
||||
public Input<string?> ResponseContentParserName { get; set; } = default!;
|
||||
|
||||
[Input(Category = "Security")]
|
||||
public Input<Dictionary<string, string>?> RequestHeaders { get; set; } = new(new HttpRequestHeaders());
|
||||
|
||||
[Output]
|
||||
public Output<object>? ResponseContent { get; set; }
|
||||
|
||||
[Output]
|
||||
public Output<HttpResponseModel> Response { get; set; }
|
||||
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var request = PrepareRequest(context);
|
||||
|
||||
var httpClientFactory = context.GetService<IHttpClientFactory>();
|
||||
var httpClient = httpClientFactory.CreateClient(nameof(SendHttpRequest));
|
||||
|
||||
var cancellationToken = context.CancellationToken;
|
||||
var response = await httpClient.SendAsync(request, cancellationToken);
|
||||
|
||||
var allHeaders =
|
||||
response.Headers.ToDictionary(x => x.Key, x => x.Value.ToArray())
|
||||
.Concat(response.Content.Headers.ToDictionary(x => x.Key, x => x.Value.ToArray()));
|
||||
|
||||
var responseModel = new HttpResponseModel(response.StatusCode, new Dictionary<string, string[]>())
|
||||
{
|
||||
StatusCode = response!.StatusCode,
|
||||
Headers = new Dictionary<string, string[]>(allHeaders)
|
||||
};
|
||||
|
||||
context.Set(Response, responseModel);
|
||||
|
||||
if (HasContent(response) && context.Get(ReadContent))
|
||||
{
|
||||
var parsers = context.GetService<IEnumerable<IHttpResponseContentReader>>();
|
||||
var formatter = SelectContentParser(parsers.ToList(), context.Get(ResponseContentParserName), context.Get(ContentType));
|
||||
context.Set(ResponseContent, await formatter.ReadAsync(response, context, cancellationToken));
|
||||
}
|
||||
}
|
||||
|
||||
private IHttpResponseContentReader SelectContentParser(List<IHttpResponseContentReader> parsers, string? parserName, string? contentType)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(parserName))
|
||||
{
|
||||
var simpleContentType = contentType?.Split(';').First() ?? "";
|
||||
var parser = parsers.OrderByDescending(x => x.Priority).ToList();
|
||||
|
||||
return parser.FirstOrDefault(x => x.GetSupportsContentType(simpleContentType)) ?? parser.Last();
|
||||
}
|
||||
else
|
||||
{
|
||||
var parser = parsers.FirstOrDefault(x => x.Name == parserName);
|
||||
|
||||
if (parser == null)
|
||||
throw new InvalidOperationException("The specified parser does not exist");
|
||||
|
||||
return parser;
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasContent(HttpResponseMessage response)
|
||||
{
|
||||
return response?.Content != null &&
|
||||
response.Content.Headers.ContentLength > 0;
|
||||
}
|
||||
|
||||
private HttpRequestMessage PrepareRequest(ActivityExecutionContext context)
|
||||
{
|
||||
var method = context.Get(Method);
|
||||
|
||||
var request = new HttpRequestMessage(
|
||||
new HttpMethod(method),
|
||||
context.Get(Url));
|
||||
|
||||
var headers = context.Get(RequestHeaders);
|
||||
var requestHeaders = new HeaderDictionary(headers
|
||||
.ToDictionary(x => x.Key, x => new StringValues(x.Value.Split(','))));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(context.Get(Authorization)))
|
||||
request.Headers.Authorization = AuthenticationHeaderValue.Parse(context.Get(Authorization));
|
||||
|
||||
foreach (var header in requestHeaders)
|
||||
request.Headers.Add(header.Key, header.Value.AsEnumerable());
|
||||
|
||||
var contentType = context.Get(ContentType);
|
||||
|
||||
var contentWriters = context.GetRequiredService<IEnumerable<IHttpRequestContentWriter>>();
|
||||
var contentWriter = SelectContentWriter(contentType, contentWriters);
|
||||
request.Content = contentWriter.GetContent(contentType, context.Get(Content));
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
private IHttpRequestContentWriter SelectContentWriter(string contentType,
|
||||
IEnumerable<IHttpRequestContentWriter> _requestContentWriters)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(contentType))
|
||||
{
|
||||
return new StringHttpRequestContentWriter();
|
||||
}
|
||||
|
||||
return _requestContentWriters.First(w => w.SupportsContentType(contentType));
|
||||
}
|
||||
}
|
||||
|
||||
8
src/modules/Elsa.Http/Constants/MimeTypes.cs
Normal file
8
src/modules/Elsa.Http/Constants/MimeTypes.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
namespace Elsa.Http.Constants;
|
||||
|
||||
public static class MimeTypes
|
||||
{
|
||||
public const string ApplicationXml = "application/xml";
|
||||
public const string ApplicationJson = "application/json";
|
||||
public const string ApplicationWwwFormUrlEncoded = "application/x-www-form-urlencoded";
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using Elsa.Http.Constants;
|
||||
|
||||
namespace Elsa.Http.ContentWriters;
|
||||
|
||||
public class FormUrlEncodedHttpRequestContentWriter : IHttpRequestContentWriter
|
||||
{
|
||||
private List<string> SupportedContentTypes = new() {MimeTypes.ApplicationWwwFormUrlEncoded};
|
||||
|
||||
public bool SupportsContentType(string contentType)
|
||||
{
|
||||
return SupportedContentTypes.Contains(contentType);
|
||||
}
|
||||
|
||||
public HttpContent GetContent<T>( T content, string? contentType = null)
|
||||
{
|
||||
return new FormUrlEncodedContent(GetContentAsDictionary(content));
|
||||
}
|
||||
|
||||
private Dictionary<string, string> GetContentAsDictionary<TType>(TType body)
|
||||
{
|
||||
return body is string || body is JsonObject ?
|
||||
JsonSerializer.Deserialize<Dictionary<string, string>>(JsonSerializer.Serialize(body)) :
|
||||
(Dictionary<string, string>)Convert.ChangeType(body, typeof(Dictionary<string, string>));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
using System.Net.Http;
|
||||
|
||||
namespace Elsa.Http.ContentWriters;
|
||||
|
||||
public interface IHttpRequestContentWriter
|
||||
{
|
||||
bool SupportsContentType(string contentType);
|
||||
HttpContent GetContent<T>(T content, string? contentType = null);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Elsa.Http.Constants;
|
||||
|
||||
namespace Elsa.Http.ContentWriters;
|
||||
|
||||
public class StringHttpRequestContentWriter : IHttpRequestContentWriter
|
||||
{
|
||||
private List<string> SupportedContentTypes = new() {MimeTypes.ApplicationJson, MimeTypes.ApplicationXml};
|
||||
|
||||
public bool SupportsContentType(string contentType)
|
||||
{
|
||||
return SupportedContentTypes.Contains(contentType);
|
||||
}
|
||||
|
||||
public HttpContent GetContent<T>(T content, string? contentType = null)
|
||||
{
|
||||
var serializedContent = JsonSerializer.Serialize(content);
|
||||
return new StringContent(serializedContent, Encoding. UTF8, contentType);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="2.2.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
using Elsa.Features.Abstractions;
|
||||
using Elsa.Features.Services;
|
||||
using Elsa.Http.ContentWriters;
|
||||
using Elsa.Http.Handlers;
|
||||
using Elsa.Http.Implementations;
|
||||
using Elsa.Http.Options;
|
||||
using Elsa.Http.Parsers;
|
||||
using Elsa.Http.Services;
|
||||
using Elsa.Mediator.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -43,9 +45,18 @@ public class HttpFeature : FeatureBase
|
|||
Services.Configure<HttpActivityOptions>(options => options.BasePath = BasePath);
|
||||
|
||||
Services
|
||||
.AddHttpClient()
|
||||
.AddSingleton<IRouteMatcher, RouteMatcher>()
|
||||
.AddSingleton<IRouteTable, RouteTable>()
|
||||
.AddNotificationHandlersFrom<UpdateRouteTable>()
|
||||
.AddHttpContextAccessor();
|
||||
.AddHttpContextAccessor()
|
||||
|
||||
// Add Content Parsers
|
||||
.AddSingleton<IHttpResponseContentReader, JsonElementHttpResponseContentReader>()
|
||||
|
||||
//Add Request Content Writers
|
||||
.AddSingleton<IHttpRequestContentWriter, StringHttpRequestContentWriter>()
|
||||
.AddSingleton<IHttpRequestContentWriter, FormUrlEncodedHttpRequestContentWriter>()
|
||||
;
|
||||
}
|
||||
}
|
||||
8
src/modules/Elsa.Http/Models/HttpRequestHeaders.cs
Normal file
8
src/modules/Elsa.Http/Models/HttpRequestHeaders.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Elsa.Http.Models;
|
||||
|
||||
public class HttpRequestHeaders : Dictionary<string, string>
|
||||
{
|
||||
public string ContentType => this["content-type"];
|
||||
}
|
||||
6
src/modules/Elsa.Http/Models/HttpResponseModel.cs
Normal file
6
src/modules/Elsa.Http/Models/HttpResponseModel.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
|
||||
namespace Elsa.Http.Models;
|
||||
|
||||
public record HttpResponseModel(HttpStatusCode StatusCode, IDictionary<string, string[]> Headers);
|
||||
13
src/modules/Elsa.Http/Parsers/IHttpResponseContentReader.cs
Normal file
13
src/modules/Elsa.Http/Parsers/IHttpResponseContentReader.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elsa.Http.Parsers;
|
||||
|
||||
public interface IHttpResponseContentReader
|
||||
{
|
||||
string Name { get; }
|
||||
int Priority { get; }
|
||||
bool GetSupportsContentType(string contentType);
|
||||
Task<object> ReadAsync(HttpResponseMessage response, object context, CancellationToken cancellationToken);
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elsa.Http.Parsers;
|
||||
|
||||
public class JsonElementHttpResponseContentReader : IHttpResponseContentReader
|
||||
{
|
||||
public string Name => "JsonElement";
|
||||
public int Priority => 0;
|
||||
public bool GetSupportsContentType(string contentType) => contentType.Contains("/json", StringComparison.OrdinalIgnoreCase);
|
||||
public async Task<object> ReadAsync(HttpResponseMessage response, object context, CancellationToken cancellationToken)
|
||||
{
|
||||
var json = (await response.Content.ReadAsStringAsync()).Trim();
|
||||
return JsonDocument.Parse(json).RootElement;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elsa.Http.Parsers;
|
||||
|
||||
public class PlainTextHttpResponseContentReader : IHttpResponseContentReader
|
||||
{
|
||||
public string Name => "Plain Text";
|
||||
public int Priority => -1;
|
||||
public bool GetSupportsContentType(string contentType) => true;
|
||||
public async Task<object> ReadAsync(HttpResponseMessage response, object context, CancellationToken cancellationToken) => await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ services
|
|||
.UseRuntime(runtime =>
|
||||
{
|
||||
runtime
|
||||
.UseEntityFrameworkCore(ef => ef.UseSqlite())
|
||||
.UseEntityFrameworkCore(f =>f.UseSqlite())
|
||||
.AddWorkflow<HelloWorldWorkflow>()
|
||||
.AddWorkflow<HttpWorkflow>()
|
||||
.AddWorkflow<ForkedHttpWorkflow>()
|
||||
|
|
@ -61,13 +61,13 @@ var app = builder.Build();
|
|||
var serviceProvider = app.Services;
|
||||
|
||||
// Configure workflow engine execution pipeline.
|
||||
serviceProvider.ConfigureDefaultWorkflowExecutionPipeline(pipeline =>
|
||||
pipeline
|
||||
.UseWorkflowExecutionLogPersistence()
|
||||
.UsePersistentVariables()
|
||||
.UseWorkflowContexts()
|
||||
.UseStackBasedActivityScheduler()
|
||||
);
|
||||
// serviceProvider.ConfigureDefaultWorkflowExecutionPipeline(pipeline =>
|
||||
// pipeline
|
||||
// .UseWorkflowExecutionLogPersistence()
|
||||
// .UsePersistentVariables()
|
||||
// .UseWorkflowContexts()
|
||||
// .UseStackBasedActivityScheduler()
|
||||
// );
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
app.UseDeveloperExceptionPage();
|
||||
|
|
|
|||
|
|
@ -36,6 +36,16 @@ services
|
|||
// Razor Pages.
|
||||
services.AddRazorPages();
|
||||
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy("AllowSpecificOrigin",
|
||||
builder => builder.AllowAnyOrigin()
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader()
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
// Configure middleware pipeline.
|
||||
var app = builder.Build();
|
||||
|
||||
|
|
@ -54,4 +64,10 @@ app.UseAuthorization();
|
|||
app.UseHttpActivities();
|
||||
app.MapRazorPages();
|
||||
|
||||
app.UseCors(x => x
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader()
|
||||
.SetIsOriginAllowed(origin => true) // allow any origin
|
||||
.AllowCredentials());
|
||||
|
||||
app.Run();
|
||||
Loading…
Reference in a new issue