Browse Source

Merge pull request #11005 from abpframework/AbpRemoteStreamContentModelBinder

Enhance `AbpRemoteStreamContentModelBinder` class.
pull/11007/head
Ahmet Çotur 4 years ago
committed by GitHub
parent
commit
9992ece804
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 54
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/AbpRemoteStreamContentModelBinder.cs
  2. 12
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/AbpRemoteStreamContentModelBinderProvider.cs
  3. 2
      framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs
  4. 2
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/CreateFileInput.cs
  5. 2
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/CreateMultipleFileInput.cs

54
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/AbpRemoteStreamContentModelBinder.cs

@ -8,7 +8,8 @@ using Volo.Abp.Content;
namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
{
public class AbpRemoteStreamContentModelBinder : IModelBinder
public class AbpRemoteStreamContentModelBinder<TRemoteStreamContent> : IModelBinder
where TRemoteStreamContent: class, IRemoteStreamContent
{
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
@ -17,7 +18,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
throw new ArgumentNullException(nameof(bindingContext));
}
var postedFiles = new List<IRemoteStreamContent>();
var postedFiles = GetCompatibleCollection<TRemoteStreamContent>(bindingContext);
// If we're at the top level, then use the FieldName (parameter or property name).
// This handles the fact that there will be nothing in the ValueProviders for this parameter
@ -42,7 +43,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
}
object value;
if (bindingContext.ModelType == typeof(IRemoteStreamContent) || bindingContext.ModelType == typeof(RemoteStreamContent))
if (bindingContext.ModelType == typeof(TRemoteStreamContent))
{
if (postedFiles.Count == 0)
{
@ -63,7 +64,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
// Perform any final type mangling needed.
var modelType = bindingContext.ModelType;
if (modelType == typeof(IRemoteStreamContent[]) || modelType == typeof(RemoteStreamContent[]))
if (modelType == typeof(TRemoteStreamContent[]))
{
value = postedFiles.ToArray();
}
@ -91,7 +92,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
private async Task GetFormFilesAsync(
string modelName,
ModelBindingContext bindingContext,
ICollection<IRemoteStreamContent> postedFiles)
ICollection<TRemoteStreamContent> postedFiles)
{
var request = bindingContext.HttpContext.Request;
if (request.HasFormContentType)
@ -108,14 +109,53 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
if (file.Name.Equals(modelName, StringComparison.OrdinalIgnoreCase))
{
postedFiles.Add(new RemoteStreamContent(file.OpenReadStream(), file.FileName, file.ContentType, file.Length));
postedFiles.Add(new RemoteStreamContent(file.OpenReadStream(), file.FileName, file.ContentType, file.Length).As<TRemoteStreamContent>());
}
}
}
else if (bindingContext.IsTopLevelObject)
{
postedFiles.Add(new RemoteStreamContent(request.Body, null, request.ContentType, request.ContentLength));
postedFiles.Add(new RemoteStreamContent(request.Body, null, request.ContentType, request.ContentLength).As<TRemoteStreamContent>());
}
}
private static ICollection<T> GetCompatibleCollection<T>(ModelBindingContext bindingContext)
{
var model = bindingContext.Model;
var modelType = bindingContext.ModelType;
// There's a limited set of collection types we can create here.
//
// For the simple cases: Choose List<T> if the destination type supports it (at least as an intermediary).
//
// For more complex cases: If the destination type is a class that implements ICollection<T>, then activate
// an instance and return that.
//
// Otherwise just give up.
if (typeof(T).IsAssignableFrom(modelType))
{
return new List<T>();
}
if (modelType == typeof(T[]))
{
return new List<T>();
}
// Does collection exist and can it be reused?
if (model is ICollection<T> collection && !collection.IsReadOnly)
{
collection.Clear();
return collection;
}
if (modelType.IsAssignableFrom(typeof(List<T>)))
{
return new List<T>();
}
return (ICollection<T>)Activator.CreateInstance(modelType);
}
}
}

12
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/AbpRemoteStreamContentModelBinderProvider.cs

@ -14,12 +14,16 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.ModelType == typeof(IRemoteStreamContent) ||
context.Metadata.ModelType == typeof(RemoteStreamContent) ||
typeof(IEnumerable<IRemoteStreamContent>).IsAssignableFrom(context.Metadata.ModelType) ||
if (context.Metadata.ModelType == typeof(RemoteStreamContent) ||
typeof(IEnumerable<RemoteStreamContent>).IsAssignableFrom(context.Metadata.ModelType))
{
return new AbpRemoteStreamContentModelBinder();
return new AbpRemoteStreamContentModelBinder<RemoteStreamContent>();
}
if (context.Metadata.ModelType == typeof(IRemoteStreamContent) ||
typeof(IEnumerable<IRemoteStreamContent>).IsAssignableFrom(context.Metadata.ModelType))
{
return new AbpRemoteStreamContentModelBinder<IRemoteStreamContent>();
}
return null;

2
framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs

@ -263,7 +263,7 @@ namespace Volo.Abp.Http.DynamicProxying
var result = await _peopleAppService.CreateMultipleFileAsync(new CreateMultipleFileInput()
{
Name = "123.rtf",
Contents = new List<IRemoteStreamContent>()
Contents = new List<RemoteStreamContent>()
{
new RemoteStreamContent(memoryStream, "1-1.rtf", "application/rtf"),
new RemoteStreamContent(memoryStream2, "1-2.rtf", "application/rtf2")

2
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/CreateFileInput.cs

@ -6,6 +6,6 @@ namespace Volo.Abp.TestApp.Application.Dto
{
public string Name { get; set; }
public RemoteStreamContent Content { get; set; }
public IRemoteStreamContent Content { get; set; }
}
}

2
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/CreateMultipleFileInput.cs

@ -7,7 +7,7 @@ namespace Volo.Abp.TestApp.Application.Dto
{
public string Name { get; set; }
public IEnumerable<IRemoteStreamContent> Contents { get; set; }
public IEnumerable<RemoteStreamContent> Contents { get; set; }
public CreateFileInput Inner { get; set; }
}

Loading…
Cancel
Save