diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Content/IRemoteStreamContent.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Content/IRemoteStreamContent.cs index 4cabd5b5e0..ba564df18e 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Content/IRemoteStreamContent.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Content/IRemoteStreamContent.cs @@ -5,12 +5,12 @@ namespace Volo.Abp.Content { public interface IRemoteStreamContent : IDisposable { + string FileName { get; } + string ContentType { get; } long? ContentLength { get; } - string FileName { get; } - Stream GetStream(); } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Content/RemoteStreamContent.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Content/RemoteStreamContent.cs index f2e69f49ad..f663066e34 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Content/RemoteStreamContent.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Content/RemoteStreamContent.cs @@ -5,22 +5,30 @@ namespace Volo.Abp.Content public class RemoteStreamContent : IRemoteStreamContent { private readonly Stream _stream; - private readonly string _fileName; - private readonly string _contentType; - private readonly long? _length; - private readonly bool _leaveOpen; + private readonly bool _disposeStream; + private bool _disposed; - public virtual string FileName => _fileName; - public virtual string ContentType => _contentType; - public virtual long? ContentLength => _length; + public virtual string FileName { get; } - public RemoteStreamContent(Stream stream, string fileName, string contentType = null, long? readOnlylength = null, bool leaveOpen = false) + public virtual string ContentType { get; } = "application/octet-stream"; + + public virtual long? ContentLength { get; } + + public RemoteStreamContent(Stream stream, bool disposeStream = true) { _stream = stream; - _fileName = fileName; - _contentType = contentType ?? "application/octet-stream"; - _length = readOnlylength ?? (stream.GetNullableLength() - stream.GetNullablePosition()); - _leaveOpen = leaveOpen; + _disposeStream = disposeStream; + } + + public RemoteStreamContent(Stream stream, string fileName, string contentType = null, long? readOnlyLength = null, bool disposeStream = true) + : this(stream, disposeStream) + { + FileName = fileName; + if (contentType != null) + { + ContentType = contentType; + } + ContentLength = readOnlyLength ?? (_stream.CanSeek ? _stream.Length - _stream.Position : null); } public virtual Stream GetStream() @@ -30,8 +38,9 @@ namespace Volo.Abp.Content public virtual void Dispose() { - if (!_leaveOpen) + if (!_disposed && _disposeStream) { + _disposed = true; _stream?.Dispose(); } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Extensions/StreamExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Extensions/StreamExtensions.cs deleted file mode 100644 index 0501e92d56..0000000000 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Extensions/StreamExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.IO; - -public static class StreamExtensions -{ - public static long? GetNullableLength(this Stream stream) - { - try - { - return stream?.Length; - } - catch - { - /*some stream classes throw exceptions when accessing Length because they do not have access to such information */ - return null; - } - } - public static long? GetNullablePosition(this Stream stream) - { - try - { - return stream?.Position; - } - catch - { - /*some stream classes throw exceptions when accessing Position because they do not have access to such information */ - return null; - } - } -} diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs index 9f41142e15..a83d25910a 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs @@ -113,11 +113,11 @@ namespace Volo.Abp.Http.Client.DynamicProxying /* returning a class that holds a reference to response * content just to be sure that GC does not dispose of * it before we finish doing our work with the stream */ - return (T)(object)new RemoteStreamContent( - await responseContent.ReadAsStreamAsync(), + return (T) (object) new RemoteStreamContent( + await responseContent.ReadAsStreamAsync(), responseContent.Headers?.ContentDisposition?.FileNameStar ?? RemoveQuotes(responseContent.Headers?.ContentDisposition?.FileName).ToString(), - responseContent.Headers.ContentType?.ToString(), - responseContent.Headers.ContentLength); + responseContent.Headers?.ContentType?.ToString(), + responseContent.Headers?.ContentLength); } var stringContent = await responseContent.ReadAsStringAsync(); diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/RequestPayloadBuilder.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/RequestPayloadBuilder.cs index 7893073442..d83b319b28 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/RequestPayloadBuilder.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/RequestPayloadBuilder.cs @@ -87,7 +87,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying { streamContent.Headers.ContentType = new MediaTypeHeaderValue(remoteStreamContent.ContentType); } - streamContent.Headers.ContentLength = stream.GetNullableLength() - stream.GetNullablePosition(); + streamContent.Headers.ContentLength = remoteStreamContent.ContentLength; formData.Add(streamContent, parameter.Name, remoteStreamContent.FileName ?? parameter.Name); } else if (value is IEnumerable remoteStreamContents) @@ -100,7 +100,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying { streamContent.Headers.ContentType = new MediaTypeHeaderValue(content.ContentType); } - streamContent.Headers.ContentLength = stream.GetNullableLength() - stream.GetNullablePosition(); + streamContent.Headers.ContentLength = content.ContentLength; formData.Add(streamContent, parameter.Name, content.FileName ?? parameter.Name); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/MediaDescriptors/MediaDescriptorAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/MediaDescriptors/MediaDescriptorAppService.cs index 366a86c0b0..99700630e7 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/MediaDescriptors/MediaDescriptorAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/MediaDescriptors/MediaDescriptorAppService.cs @@ -24,7 +24,7 @@ namespace Volo.CmsKit.MediaDescriptors var entity = await MediaDescriptorRepository.GetAsync(id); var stream = await MediaContainer.GetAsync(id.ToString()); - return new RemoteStreamContent(stream, entity.MimeType); + return new RemoteStreamContent(stream, entity.Name, entity.MimeType); } } -} \ No newline at end of file +} diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/MediaDescriptors/MediaDescriptorAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/MediaDescriptors/MediaDescriptorAdminAppService_Tests.cs index 898b58d437..2559d6ab90 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/MediaDescriptors/MediaDescriptorAdminAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/MediaDescriptors/MediaDescriptorAdminAppService_Tests.cs @@ -35,12 +35,12 @@ namespace Volo.CmsKit.MediaDescriptors var media = await _mediaDescriptorAdminAppService.CreateAsync(_cmsKitTestData.Media_1_EntityType, new CreateMediaInputWithStream { Name = mediaName, - File = new RemoteStreamContent(stream, mediaType) + File = new RemoteStreamContent(stream, mediaName, mediaType) }); - + media.ShouldNotBeNull(); } - + [Fact] public async Task Should_Delete_Media() { @@ -49,4 +49,4 @@ namespace Volo.CmsKit.MediaDescriptors (await _mediaDescriptorRepository.FindAsync(_cmsKitTestData.Media_1_Id)).ShouldBeNull(); } } -} \ No newline at end of file +}