Browse Source

Merge pull request #11007 from abpframework/auto-merge/rel-5-0/729

Merge branch dev with rel-5.0
pull/11019/head
Ahmet Çotur 5 years ago
committed by GitHub
parent
commit
4a12a8ace6
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. 66
      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; 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) public async Task BindModelAsync(ModelBindingContext bindingContext)
{ {
@ -17,7 +18,7 @@ public class AbpRemoteStreamContentModelBinder : IModelBinder
throw new ArgumentNullException(nameof(bindingContext)); 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). // 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 // This handles the fact that there will be nothing in the ValueProviders for this parameter
@ -42,7 +43,7 @@ public class AbpRemoteStreamContentModelBinder : IModelBinder
} }
object value; object value;
if (bindingContext.ModelType == typeof(IRemoteStreamContent) || bindingContext.ModelType == typeof(RemoteStreamContent)) if (bindingContext.ModelType == typeof(TRemoteStreamContent))
{ {
if (postedFiles.Count == 0) if (postedFiles.Count == 0)
{ {
@ -63,7 +64,7 @@ public class AbpRemoteStreamContentModelBinder : IModelBinder
// Perform any final type mangling needed. // Perform any final type mangling needed.
var modelType = bindingContext.ModelType; var modelType = bindingContext.ModelType;
if (modelType == typeof(IRemoteStreamContent[]) || modelType == typeof(RemoteStreamContent[])) if (modelType == typeof(TRemoteStreamContent[]))
{ {
value = postedFiles.ToArray(); value = postedFiles.ToArray();
} }
@ -91,7 +92,7 @@ public class AbpRemoteStreamContentModelBinder : IModelBinder
private async Task GetFormFilesAsync( private async Task GetFormFilesAsync(
string modelName, string modelName,
ModelBindingContext bindingContext, ModelBindingContext bindingContext,
ICollection<IRemoteStreamContent> postedFiles) ICollection<TRemoteStreamContent> postedFiles)
{ {
var request = bindingContext.HttpContext.Request; var request = bindingContext.HttpContext.Request;
if (request.HasFormContentType) if (request.HasFormContentType)
@ -108,13 +109,52 @@ public class AbpRemoteStreamContentModelBinder : IModelBinder
if (file.Name.Equals(modelName, StringComparison.OrdinalIgnoreCase)) 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) 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 @@ public class AbpRemoteStreamContentModelBinderProvider : IModelBinderProvider
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
if (context.Metadata.ModelType == typeof(IRemoteStreamContent) || if (context.Metadata.ModelType == typeof(RemoteStreamContent) ||
context.Metadata.ModelType == typeof(RemoteStreamContent) ||
typeof(IEnumerable<IRemoteStreamContent>).IsAssignableFrom(context.Metadata.ModelType) ||
typeof(IEnumerable<RemoteStreamContent>).IsAssignableFrom(context.Metadata.ModelType)) 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; return null;

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

@ -59,10 +59,10 @@ public class PersonAppServiceClientProxy_Tests : AbpHttpClientTestBase
var id2 = Guid.NewGuid(); var id2 = Guid.NewGuid();
var @params = await _peopleAppService.GetParams(new List<Guid> var @params = await _peopleAppService.GetParams(new List<Guid>
{ {
id1, id1,
id2 id2
}, new[] { "name1", "name2" }); }, new[] { "name1", "name2" });
@params.ShouldContain(id1.ToString("N")); @params.ShouldContain(id1.ToString("N"));
@params.ShouldContain(id2.ToString("N")); @params.ShouldContain(id2.ToString("N"));
@ -224,10 +224,10 @@ public class PersonAppServiceClientProxy_Tests : AbpHttpClientTestBase
memoryStream2.Position = 0; memoryStream2.Position = 0;
var result = await _peopleAppService.UploadMultipleAsync(new List<IRemoteStreamContent>() var result = await _peopleAppService.UploadMultipleAsync(new List<IRemoteStreamContent>()
{ {
new RemoteStreamContent(memoryStream, "File1.rtf", "application/rtf"), new RemoteStreamContent(memoryStream, "File1.rtf", "application/rtf"),
new RemoteStreamContent(memoryStream2, "File2.rtf", "application/rtf2") new RemoteStreamContent(memoryStream2, "File2.rtf", "application/rtf2")
}); });
result.ShouldBe("File1:application/rtf:File1.rtfFile2:application/rtf2:File2.rtf"); result.ShouldBe("File1:application/rtf:File1.rtfFile2:application/rtf2:File2.rtf");
} }
@ -263,11 +263,11 @@ public class PersonAppServiceClientProxy_Tests : AbpHttpClientTestBase
var result = await _peopleAppService.CreateMultipleFileAsync(new CreateMultipleFileInput() var result = await _peopleAppService.CreateMultipleFileAsync(new CreateMultipleFileInput()
{ {
Name = "123.rtf", Name = "123.rtf",
Contents = new List<IRemoteStreamContent>() Contents = new List<RemoteStreamContent>()
{ {
new RemoteStreamContent(memoryStream, "1-1.rtf", "application/rtf"), new RemoteStreamContent(memoryStream, "1-1.rtf", "application/rtf"),
new RemoteStreamContent(memoryStream2, "1-2.rtf", "application/rtf2") new RemoteStreamContent(memoryStream2, "1-2.rtf", "application/rtf2")
}, },
Inner = new CreateFileInput() Inner = new CreateFileInput()
{ {
Name = "789.rtf", Name = "789.rtf",
@ -283,18 +283,18 @@ public class PersonAppServiceClientProxy_Tests : AbpHttpClientTestBase
var result = await _peopleAppService.GetParamsFromQueryAsync(new GetParamsInput() var result = await _peopleAppService.GetParamsFromQueryAsync(new GetParamsInput()
{ {
NameValues = new List<GetParamsNameValue>() NameValues = new List<GetParamsNameValue>()
{
new GetParamsNameValue()
{ {
new GetParamsNameValue() Name = "name1",
{ Value = "value1"
Name = "name1",
Value = "value1"
},
new GetParamsNameValue()
{
Name = "name2",
Value = "value2"
}
}, },
new GetParamsNameValue()
{
Name = "name2",
Value = "value2"
}
},
NameValue = new GetParamsNameValue() NameValue = new GetParamsNameValue()
{ {
Name = "name3", Name = "name3",
@ -310,18 +310,18 @@ public class PersonAppServiceClientProxy_Tests : AbpHttpClientTestBase
var result = await _peopleAppService.GetParamsFromFormAsync(new GetParamsInput() var result = await _peopleAppService.GetParamsFromFormAsync(new GetParamsInput()
{ {
NameValues = new List<GetParamsNameValue>() NameValues = new List<GetParamsNameValue>()
{
new GetParamsNameValue()
{ {
new GetParamsNameValue() Name = "name1",
{ Value = "value1"
Name = "name1",
Value = "value1"
},
new GetParamsNameValue()
{
Name = "name2",
Value = "value2"
}
}, },
new GetParamsNameValue()
{
Name = "name2",
Value = "value2"
}
},
NameValue = new GetParamsNameValue() NameValue = new GetParamsNameValue()
{ {
Name = "name3", Name = "name3",

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

@ -6,5 +6,5 @@ public class CreateFileInput
{ {
public string Name { get; set; } 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 @@ public class CreateMultipleFileInput
{ {
public string Name { get; set; } public string Name { get; set; }
public IEnumerable<IRemoteStreamContent> Contents { get; set; } public IEnumerable<RemoteStreamContent> Contents { get; set; }
public CreateFileInput Inner { get; set; } public CreateFileInput Inner { get; set; }
} }

Loading…
Cancel
Save