|
|
|
|
@ -3,8 +3,11 @@ using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
using System.Net.Http.Headers;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using JetBrains.Annotations;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using Volo.Abp.Content;
|
|
|
|
|
using Volo.Abp.DependencyInjection;
|
|
|
|
|
using Volo.Abp.Http.Client.Proxying;
|
|
|
|
|
@ -16,21 +19,37 @@ namespace Volo.Abp.Http.Client.ClientProxying
|
|
|
|
|
{
|
|
|
|
|
public class ClientProxyRequestPayloadBuilder : ITransientDependency
|
|
|
|
|
{
|
|
|
|
|
protected static MethodInfo CallObjectToFormDataAsyncMethod { get; }
|
|
|
|
|
|
|
|
|
|
static ClientProxyRequestPayloadBuilder()
|
|
|
|
|
{
|
|
|
|
|
CallObjectToFormDataAsyncMethod = typeof(ClientProxyRequestPayloadBuilder)
|
|
|
|
|
.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
|
|
|
|
|
.First(m => m.Name == nameof(ObjectToFormDataAsync) && m.IsGenericMethodDefinition);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected IServiceScopeFactory ServiceScopeFactory { get; }
|
|
|
|
|
|
|
|
|
|
public ClientProxyRequestPayloadBuilder(IServiceScopeFactory serviceScopeFactory)
|
|
|
|
|
{
|
|
|
|
|
ServiceScopeFactory = serviceScopeFactory;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[CanBeNull]
|
|
|
|
|
public virtual HttpContent BuildContent(ActionApiDescriptionModel action, IReadOnlyDictionary<string, object> methodArguments, IJsonSerializer jsonSerializer, ApiVersionInfo apiVersion)
|
|
|
|
|
public virtual async Task<HttpContent> BuildContentAsync(ActionApiDescriptionModel action, IReadOnlyDictionary<string, object> methodArguments, IJsonSerializer jsonSerializer, ApiVersionInfo apiVersion)
|
|
|
|
|
{
|
|
|
|
|
var body = GenerateBody(action, methodArguments, jsonSerializer);
|
|
|
|
|
var body = await GenerateBodyAsync(action, methodArguments, jsonSerializer);
|
|
|
|
|
if (body != null)
|
|
|
|
|
{
|
|
|
|
|
return body;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
body = GenerateFormPostData(action, methodArguments);
|
|
|
|
|
body = await GenerateFormPostDataAsync(action, methodArguments);
|
|
|
|
|
|
|
|
|
|
return body;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual HttpContent GenerateBody(ActionApiDescriptionModel action, IReadOnlyDictionary<string, object> methodArguments, IJsonSerializer jsonSerializer)
|
|
|
|
|
protected virtual Task<HttpContent> GenerateBodyAsync(ActionApiDescriptionModel action, IReadOnlyDictionary<string, object> methodArguments, IJsonSerializer jsonSerializer)
|
|
|
|
|
{
|
|
|
|
|
var parameters = action
|
|
|
|
|
.Parameters
|
|
|
|
|
@ -39,7 +58,7 @@ namespace Volo.Abp.Http.Client.ClientProxying
|
|
|
|
|
|
|
|
|
|
if (parameters.Length <= 0)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
return Task.FromResult<HttpContent>(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parameters.Length > 1)
|
|
|
|
|
@ -52,13 +71,13 @@ namespace Volo.Abp.Http.Client.ClientProxying
|
|
|
|
|
var value = HttpActionParameterHelper.FindParameterValue(methodArguments, parameters[0]);
|
|
|
|
|
if (value == null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
return Task.FromResult<HttpContent>(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new StringContent(jsonSerializer.Serialize(value), Encoding.UTF8, MimeTypes.Application.Json);
|
|
|
|
|
return Task.FromResult<HttpContent>(new StringContent(jsonSerializer.Serialize(value), Encoding.UTF8, MimeTypes.Application.Json));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual HttpContent GenerateFormPostData(ActionApiDescriptionModel action, IReadOnlyDictionary<string, object> methodArguments)
|
|
|
|
|
protected virtual async Task<HttpContent> GenerateFormPostDataAsync(ActionApiDescriptionModel action, IReadOnlyDictionary<string, object> methodArguments)
|
|
|
|
|
{
|
|
|
|
|
var parameters = action
|
|
|
|
|
.Parameters
|
|
|
|
|
@ -70,71 +89,75 @@ namespace Volo.Abp.Http.Client.ClientProxying
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parameters.Any(x => x.BindingSourceId == ParameterBindingSources.FormFile))
|
|
|
|
|
var formData = new MultipartFormDataContent();
|
|
|
|
|
|
|
|
|
|
foreach (var parameter in parameters)
|
|
|
|
|
{
|
|
|
|
|
var formData = new MultipartFormDataContent();
|
|
|
|
|
foreach (var parameter in parameters)
|
|
|
|
|
var value = HttpActionParameterHelper.FindParameterValue(methodArguments, parameter);
|
|
|
|
|
if (value == null)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var formDataContents = await (Task<List<KeyValuePair<string, HttpContent>>>)CallObjectToFormDataAsyncMethod
|
|
|
|
|
.MakeGenericMethod(value.GetType())
|
|
|
|
|
.Invoke(this, new object[] { value });
|
|
|
|
|
|
|
|
|
|
if (formDataContents != null)
|
|
|
|
|
{
|
|
|
|
|
var value = HttpActionParameterHelper.FindParameterValue(methodArguments, parameter);
|
|
|
|
|
if (value == null)
|
|
|
|
|
foreach (var content in formDataContents)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
formData.Add(content.Value, content.Key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (value is IRemoteStreamContent remoteStreamContent)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (value is IRemoteStreamContent remoteStreamContent)
|
|
|
|
|
{
|
|
|
|
|
var stream = remoteStreamContent.GetStream();
|
|
|
|
|
var streamContent = new StreamContent(stream);
|
|
|
|
|
if (!remoteStreamContent.ContentType.IsNullOrWhiteSpace())
|
|
|
|
|
{
|
|
|
|
|
var stream = remoteStreamContent.GetStream();
|
|
|
|
|
var streamContent = new StreamContent(stream);
|
|
|
|
|
if (!remoteStreamContent.ContentType.IsNullOrWhiteSpace())
|
|
|
|
|
{
|
|
|
|
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue(remoteStreamContent.ContentType);
|
|
|
|
|
}
|
|
|
|
|
streamContent.Headers.ContentLength = remoteStreamContent.ContentLength;
|
|
|
|
|
formData.Add(streamContent, parameter.Name, remoteStreamContent.FileName ?? parameter.Name);
|
|
|
|
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue(remoteStreamContent.ContentType);
|
|
|
|
|
}
|
|
|
|
|
else if (value is IEnumerable<IRemoteStreamContent> remoteStreamContents)
|
|
|
|
|
streamContent.Headers.ContentLength = remoteStreamContent.ContentLength;
|
|
|
|
|
formData.Add(streamContent, parameter.Name, remoteStreamContent.FileName ?? parameter.Name);
|
|
|
|
|
}
|
|
|
|
|
else if (value is IEnumerable<IRemoteStreamContent> remoteStreamContents)
|
|
|
|
|
{
|
|
|
|
|
foreach (var content in remoteStreamContents)
|
|
|
|
|
{
|
|
|
|
|
foreach (var content in remoteStreamContents)
|
|
|
|
|
var stream = content.GetStream();
|
|
|
|
|
var streamContent = new StreamContent(stream);
|
|
|
|
|
if (!content.ContentType.IsNullOrWhiteSpace())
|
|
|
|
|
{
|
|
|
|
|
var stream = content.GetStream();
|
|
|
|
|
var streamContent = new StreamContent(stream);
|
|
|
|
|
if (!content.ContentType.IsNullOrWhiteSpace())
|
|
|
|
|
{
|
|
|
|
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue(content.ContentType);
|
|
|
|
|
}
|
|
|
|
|
streamContent.Headers.ContentLength = content.ContentLength;
|
|
|
|
|
formData.Add(streamContent, parameter.Name, content.FileName ?? parameter.Name);
|
|
|
|
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue(content.ContentType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
formData.Add(new StringContent(value.ToString(), Encoding.UTF8), parameter.Name);
|
|
|
|
|
streamContent.Headers.ContentLength = content.ContentLength;
|
|
|
|
|
formData.Add(streamContent, parameter.Name, content.FileName ?? parameter.Name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return formData;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var postDataBuilder = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
var isFirstParam = true;
|
|
|
|
|
foreach (var parameter in parameters.Where(p => p.BindingSourceId == ParameterBindingSources.Form))
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var value = HttpActionParameterHelper.FindParameterValue(methodArguments, parameter);
|
|
|
|
|
if (value == null)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
formData.Add(new StringContent(value.ToString(), Encoding.UTF8), parameter.Name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
postDataBuilder.Append(isFirstParam ? "?" : "&");
|
|
|
|
|
postDataBuilder.Append(parameter.Name + "=" + System.Net.WebUtility.UrlEncode(value.ToString()));
|
|
|
|
|
return formData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isFirstParam = false;
|
|
|
|
|
protected virtual async Task<List<KeyValuePair<string, HttpContent>>> ObjectToFormDataAsync<T>(T value)
|
|
|
|
|
{
|
|
|
|
|
using (var scope = ServiceScopeFactory.CreateScope())
|
|
|
|
|
{
|
|
|
|
|
var objectToFormData = scope.ServiceProvider.GetService<IObjectToFormData<T>>();
|
|
|
|
|
if (objectToFormData != null)
|
|
|
|
|
{
|
|
|
|
|
return await objectToFormData.ConvertAsync(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new StringContent(postDataBuilder.ToString(), Encoding.UTF8, MimeTypes.Application.XWwwFormUrlencoded);
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|