Browse Source

Merge pull request #9180 from alexandru-bagu/non-file-remote-stream

use IRemoteContentStream without form content headers
pull/9994/head
maliming 5 years ago
committed by GitHub
parent
commit
c86d8406c8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/AbpRemoteStreamContentModelBinder.cs
  2. 9
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs
  3. 9
      framework/src/Volo.Abp.Core/Volo/Abp/Content/IRemoteStreamContent.cs
  4. 36
      framework/src/Volo.Abp.Core/Volo/Abp/Content/RemoteStreamContent.cs
  5. 11
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
  6. 11
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/RequestPayloadBuilder.cs
  7. 17
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController.cs
  8. 23
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController_Tests.cs
  9. 60
      framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs
  10. 6
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs
  11. 23
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/MediaDescriptors/CreateMediaInputStream.cs
  12. 15
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs
  13. 7
      modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/MediaDescriptors/MediaDescriptorAppService.cs
  14. 11
      modules/cms-kit/test/Volo.CmsKit.Application.Tests/MediaDescriptors/MediaDescriptorAdminAppService_Tests.cs

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

@ -108,14 +108,14 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
if (file.Name.Equals(modelName, StringComparison.OrdinalIgnoreCase)) if (file.Name.Equals(modelName, StringComparison.OrdinalIgnoreCase))
{ {
postedFiles.Add(new RemoteStreamContent(file.OpenReadStream()) postedFiles.Add(new RemoteStreamContent(file.OpenReadStream(), file.FileName, file.ContentType, file.Length));
{
ContentType = file.ContentType,
FileName = file.FileName
});
} }
} }
} }
else if (bindingContext.IsTopLevelObject)
{
postedFiles.Add(new RemoteStreamContent(request.Body, null, request.ContentType, request.ContentLength));
}
} }
} }
} }

9
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs

@ -33,14 +33,9 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
context.HttpContext.Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString(); context.HttpContext.Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString();
} }
using (var stream = remoteStream.GetStream()) using (remoteStream)
{ {
if (stream.CanSeek) await remoteStream.GetStream().CopyToAsync(context.HttpContext.Response.Body);
{
stream.Position = 0;
}
await stream.CopyToAsync(context.HttpContext.Response.Body);
} }
} }
} }

9
framework/src/Volo.Abp.Core/Volo/Abp/Content/IRemoteStreamContent.cs

@ -1,15 +1,16 @@
using System.IO; using System;
using System.IO;
namespace Volo.Abp.Content namespace Volo.Abp.Content
{ {
public interface IRemoteStreamContent public interface IRemoteStreamContent : IDisposable
{ {
string FileName { get; }
string ContentType { get; } string ContentType { get; }
long? ContentLength { get; } long? ContentLength { get; }
string FileName { get; }
Stream GetStream(); Stream GetStream();
} }
} }

36
framework/src/Volo.Abp.Core/Volo/Abp/Content/RemoteStreamContent.cs

@ -5,28 +5,40 @@ namespace Volo.Abp.Content
public class RemoteStreamContent : IRemoteStreamContent public class RemoteStreamContent : IRemoteStreamContent
{ {
private readonly Stream _stream; private readonly Stream _stream;
private readonly bool _disposeStream;
private bool _disposed;
public RemoteStreamContent(Stream stream) public virtual string FileName { get; }
public virtual string ContentType { get; } = "application/octet-stream";
public virtual long? ContentLength { get; }
public RemoteStreamContent(Stream stream, string fileName = null, string contentType = null, long? readOnlyLength = null, bool disposeStream = true)
{ {
_stream = stream; _stream = stream;
}
public RemoteStreamContent(Stream stream, string fileName)
: this(stream)
{
FileName = fileName; FileName = fileName;
ContentType = "application/octet-stream"; if (contentType != null)
{
ContentType = contentType;
}
ContentLength = readOnlyLength ?? (_stream.CanSeek ? _stream.Length - _stream.Position : null);
_disposeStream = disposeStream;
} }
public virtual string ContentType { get; set; }
public virtual long? ContentLength => GetStream().Length;
public virtual string FileName { get; set; }
public virtual Stream GetStream() public virtual Stream GetStream()
{ {
return _stream; return _stream;
} }
public virtual void Dispose()
{
if (!_disposed && _disposeStream)
{
_disposed = true;
_stream?.Dispose();
}
}
} }
} }

11
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs

@ -113,12 +113,11 @@ namespace Volo.Abp.Http.Client.DynamicProxying
/* returning a class that holds a reference to response /* returning a class that holds a reference to response
* content just to be sure that GC does not dispose of * content just to be sure that GC does not dispose of
* it before we finish doing our work with the stream */ * 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(),
ContentType = responseContent.Headers.ContentType?.ToString(), responseContent.Headers?.ContentDisposition?.FileNameStar ?? RemoveQuotes(responseContent.Headers?.ContentDisposition?.FileName).ToString(),
FileName = responseContent.Headers?.ContentDisposition?.FileNameStar ?? responseContent.Headers?.ContentType?.ToString(),
RemoveQuotes(responseContent.Headers?.ContentDisposition?.FileName).ToString() responseContent.Headers?.ContentLength);
};
} }
var stringContent = await responseContent.ReadAsStringAsync(); var stringContent = await responseContent.ReadAsStringAsync();

11
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/RequestPayloadBuilder.cs

@ -82,16 +82,12 @@ namespace Volo.Abp.Http.Client.DynamicProxying
if (value is IRemoteStreamContent remoteStreamContent) if (value is IRemoteStreamContent remoteStreamContent)
{ {
var stream = remoteStreamContent.GetStream(); var stream = remoteStreamContent.GetStream();
if (stream.CanSeek)
{
stream.Position = 0;
}
var streamContent = new StreamContent(stream); var streamContent = new StreamContent(stream);
if (!remoteStreamContent.ContentType.IsNullOrWhiteSpace()) if (!remoteStreamContent.ContentType.IsNullOrWhiteSpace())
{ {
streamContent.Headers.ContentType = new MediaTypeHeaderValue(remoteStreamContent.ContentType); streamContent.Headers.ContentType = new MediaTypeHeaderValue(remoteStreamContent.ContentType);
} }
streamContent.Headers.ContentLength = remoteStreamContent.ContentLength;
formData.Add(streamContent, parameter.Name, remoteStreamContent.FileName ?? parameter.Name); formData.Add(streamContent, parameter.Name, remoteStreamContent.FileName ?? parameter.Name);
} }
else if (value is IEnumerable<IRemoteStreamContent> remoteStreamContents) else if (value is IEnumerable<IRemoteStreamContent> remoteStreamContents)
@ -99,15 +95,12 @@ namespace Volo.Abp.Http.Client.DynamicProxying
foreach (var content in remoteStreamContents) foreach (var content in remoteStreamContents)
{ {
var stream = content.GetStream(); var stream = content.GetStream();
if (stream.CanSeek)
{
stream.Position = 0;
}
var streamContent = new StreamContent(stream); var streamContent = new StreamContent(stream);
if (!content.ContentType.IsNullOrWhiteSpace()) if (!content.ContentType.IsNullOrWhiteSpace())
{ {
streamContent.Headers.ContentType = new MediaTypeHeaderValue(content.ContentType); streamContent.Headers.ContentType = new MediaTypeHeaderValue(content.ContentType);
} }
streamContent.Headers.ContentLength = content.ContentLength;
formData.Add(streamContent, parameter.Name, content.FileName ?? parameter.Name); formData.Add(streamContent, parameter.Name, content.FileName ?? parameter.Name);
} }
} }

17
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController.cs

@ -16,11 +16,8 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
{ {
var memoryStream = new MemoryStream(); var memoryStream = new MemoryStream();
await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("DownloadAsync")); await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("DownloadAsync"));
memoryStream.Position = 0;
return new RemoteStreamContent(memoryStream, "download.rtf") return new RemoteStreamContent(memoryStream, "download.rtf", "application/rtf");
{
ContentType = "application/rtf"
};
} }
[HttpPost] [HttpPost]
@ -32,5 +29,15 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
return await reader.ReadToEndAsync() + ":" + file.ContentType + ":" + file.FileName; return await reader.ReadToEndAsync() + ":" + file.ContentType + ":" + file.FileName;
} }
} }
[HttpPost]
[Route("Upload-Raw")]
public async Task<string> UploadRawAsync(IRemoteStreamContent file)
{
using (var reader = new StreamReader(file.GetStream()))
{
return await reader.ReadToEndAsync() + ":" + file.ContentType;
}
}
} }
} }

23
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentTestController_Tests.cs

@ -30,13 +30,32 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters
var streamContent = new StreamContent(memoryStream); var streamContent = new StreamContent(memoryStream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/rtf"); streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/rtf");
requestMessage.Content = new MultipartFormDataContent {{ streamContent, "file", "upload.rtf" }};
requestMessage.Content = new MultipartFormDataContent {{streamContent, "file", "upload.rtf"}};
var response = await Client.SendAsync(requestMessage); var response = await Client.SendAsync(requestMessage);
(await response.Content.ReadAsStringAsync()).ShouldBe("UploadAsync:application/rtf:upload.rtf"); (await response.Content.ReadAsStringAsync()).ShouldBe("UploadAsync:application/rtf:upload.rtf");
} }
} }
[Fact]
public async Task UploadRawAsync()
{
using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/remote-stream-content-test/upload-raw"))
{
var memoryStream = new MemoryStream();
var text = @"{ ""hello"": ""world"" }";
await memoryStream.WriteAsync(Encoding.UTF8.GetBytes(text));
memoryStream.Position = 0;
var streamContent = new StreamContent(memoryStream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
requestMessage.Content = streamContent;
var response = await Client.SendAsync(requestMessage);
(await response.Content.ReadAsStringAsync()).ShouldBe($"{text}:application/json");
}
}
} }
} }

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

@ -49,7 +49,7 @@ namespace Volo.Abp.Http.DynamicProxying
{ {
var people = await _peopleAppService.GetListAsync(new PagedAndSortedResultRequestDto()); var people = await _peopleAppService.GetListAsync(new PagedAndSortedResultRequestDto());
people.TotalCount.ShouldBeGreaterThan(0); people.TotalCount.ShouldBeGreaterThan(0);
people.Items.Count.ShouldBe((int) people.TotalCount); people.Items.Count.ShouldBe((int)people.TotalCount);
} }
[Fact] [Fact]
@ -90,8 +90,7 @@ namespace Volo.Abp.Http.DynamicProxying
{ {
Name = uniquePersonName, Name = uniquePersonName,
Age = 42 Age = 42
} });
);
person.ShouldNotBeNull(); person.ShouldNotBeNull();
person.Id.ShouldNotBe(Guid.Empty); person.Id.ShouldNotBe(Guid.Empty);
@ -110,8 +109,7 @@ namespace Volo.Abp.Http.DynamicProxying
var person = await _peopleAppService.CreateAsync(new PersonDto var person = await _peopleAppService.CreateAsync(new PersonDto
{ {
Age = 42 Age = 42
} });
);
}); });
} }
@ -195,10 +193,22 @@ namespace Volo.Abp.Http.DynamicProxying
var memoryStream = new MemoryStream(); var memoryStream = new MemoryStream();
await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("UploadAsync")); await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("UploadAsync"));
memoryStream.Position = 0; memoryStream.Position = 0;
var result = await _peopleAppService.UploadAsync(new RemoteStreamContent(memoryStream, "upload.rtf")
{ var result = await _peopleAppService.UploadAsync(new RemoteStreamContent(memoryStream, "upload.rtf", "application/rtf"));
ContentType = "application/rtf" result.ShouldBe("UploadAsync:application/rtf:upload.rtf");
}); }
[Fact]
public async Task UploadPartialAsync()
{
var memoryStream = new MemoryStream();
var rawData = new byte[16];
var text = Encoding.UTF8.GetBytes("UploadAsync");
await memoryStream.WriteAsync(rawData);
await memoryStream.WriteAsync(text);
memoryStream.Position = rawData.Length;
var result = await _peopleAppService.UploadAsync(new RemoteStreamContent(memoryStream, "upload.rtf", "application/rtf"));
result.ShouldBe("UploadAsync:application/rtf:upload.rtf"); result.ShouldBe("UploadAsync:application/rtf:upload.rtf");
} }
@ -215,15 +225,8 @@ namespace Volo.Abp.Http.DynamicProxying
var result = await _peopleAppService.UploadMultipleAsync(new List<IRemoteStreamContent>() var result = await _peopleAppService.UploadMultipleAsync(new List<IRemoteStreamContent>()
{ {
new RemoteStreamContent(memoryStream, "File1.rtf") new RemoteStreamContent(memoryStream, "File1.rtf", "application/rtf"),
{ new RemoteStreamContent(memoryStream2, "File2.rtf", "application/rtf2")
ContentType = "application/rtf"
},
new RemoteStreamContent(memoryStream2, "File2.rtf")
{
ContentType = "application/rtf2"
}
}); });
result.ShouldBe("File1:application/rtf:File1.rtfFile2:application/rtf2:File2.rtf"); result.ShouldBe("File1:application/rtf:File1.rtfFile2:application/rtf2:File2.rtf");
} }
@ -237,10 +240,7 @@ namespace Volo.Abp.Http.DynamicProxying
var result = await _peopleAppService.CreateFileAsync(new CreateFileInput() var result = await _peopleAppService.CreateFileAsync(new CreateFileInput()
{ {
Name = "123.rtf", Name = "123.rtf",
Content = new RemoteStreamContent(memoryStream, "create.rtf") Content = new RemoteStreamContent(memoryStream, "create.rtf", "application/rtf")
{
ContentType = "application/rtf"
}
}); });
result.ShouldBe("123.rtf:CreateFileAsync:application/rtf:create.rtf"); result.ShouldBe("123.rtf:CreateFileAsync:application/rtf:create.rtf");
} }
@ -265,23 +265,13 @@ namespace Volo.Abp.Http.DynamicProxying
Name = "123.rtf", Name = "123.rtf",
Contents = new List<IRemoteStreamContent>() Contents = new List<IRemoteStreamContent>()
{ {
new RemoteStreamContent(memoryStream, "1-1.rtf") new RemoteStreamContent(memoryStream, "1-1.rtf", "application/rtf"),
{ new RemoteStreamContent(memoryStream2, "1-2.rtf", "application/rtf2")
ContentType = "application/rtf"
},
new RemoteStreamContent(memoryStream2, "1-2.rtf")
{
ContentType = "application/rtf2"
}
}, },
Inner = new CreateFileInput() Inner = new CreateFileInput()
{ {
Name = "789.rtf", Name = "789.rtf",
Content = new RemoteStreamContent(memoryStream3, "i-789.rtf") Content = new RemoteStreamContent(memoryStream3, "i-789.rtf", "application/rtf3")
{
ContentType = "application/rtf3"
}
} }
}); });
result.ShouldBe("123.rtf:File1:application/rtf:1-1.rtf123.rtf:File2:application/rtf2:1-2.rtf789.rtf:File3:application/rtf3:i-789.rtf"); result.ShouldBe("123.rtf:File1:application/rtf:1-1.rtf123.rtf:File2:application/rtf2:1-2.rtf789.rtf:File3:application/rtf3:i-789.rtf");

6
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs

@ -72,11 +72,9 @@ namespace Volo.Abp.TestApp.Application
{ {
var memoryStream = new MemoryStream(); var memoryStream = new MemoryStream();
await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("DownloadAsync")); await memoryStream.WriteAsync(Encoding.UTF8.GetBytes("DownloadAsync"));
memoryStream.Position = 0;
return new RemoteStreamContent(memoryStream, "download.rtf") return new RemoteStreamContent(memoryStream, "download.rtf", "application/rtf");
{
ContentType = "application/rtf"
};
} }
public async Task<string> UploadAsync(IRemoteStreamContent streamContent) public async Task<string> UploadAsync(IRemoteStreamContent streamContent)

23
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/MediaDescriptors/CreateMediaInputStream.cs

@ -1,23 +0,0 @@
using System.ComponentModel.DataAnnotations;
using System.IO;
using Volo.Abp.Content;
using Volo.Abp.Validation;
using Volo.CmsKit.MediaDescriptors;
namespace Volo.CmsKit.Admin.MediaDescriptors
{
public class CreateMediaInputStream : RemoteStreamContent
{
[Required]
[DynamicStringLength(typeof(MediaDescriptorConsts), nameof(MediaDescriptorConsts.MaxEntityTypeLength))]
public string EntityType { get; set; }
[Required]
[DynamicStringLength(typeof(MediaDescriptorConsts), nameof(MediaDescriptorConsts.MaxNameLength))]
public string Name { get; set; }
public CreateMediaInputStream(Stream stream) : base(stream)
{
}
}
}

15
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs

@ -18,7 +18,7 @@ namespace Volo.CmsKit.Admin.MediaDescriptors
public MediaDescriptorAdminAppService( public MediaDescriptorAdminAppService(
IBlobContainer<MediaContainer> mediaContainer, IBlobContainer<MediaContainer> mediaContainer,
IMediaDescriptorRepository mediaDescriptorRepository, IMediaDescriptorRepository mediaDescriptorRepository,
MediaDescriptorManager mediaDescriptorManager, MediaDescriptorManager mediaDescriptorManager,
IMediaDescriptorDefinitionStore mediaDescriptorDefinitionStore) IMediaDescriptorDefinitionStore mediaDescriptorDefinitionStore)
{ {
MediaContainer = mediaContainer; MediaContainer = mediaContainer;
@ -34,15 +34,12 @@ namespace Volo.CmsKit.Admin.MediaDescriptors
/* TODO: Shouldn't CreatePolicies be a dictionary and we check for inputStream.EntityType? */ /* TODO: Shouldn't CreatePolicies be a dictionary and we check for inputStream.EntityType? */
await CheckAnyOfPoliciesAsync(definition.CreatePolicies); await CheckAnyOfPoliciesAsync(definition.CreatePolicies);
using (var stream = inputStream.File.GetStream()) var newEntity = await MediaDescriptorManager.CreateAsync(entityType, inputStream.Name, inputStream.File.ContentType, inputStream.File.ContentLength ?? 0);
{
var newEntity = await MediaDescriptorManager.CreateAsync(entityType, inputStream.Name, inputStream.File.ContentType, inputStream.File.ContentLength ?? 0);
await MediaContainer.SaveAsync(newEntity.Id.ToString(), stream); await MediaContainer.SaveAsync(newEntity.Id.ToString(), inputStream.File.GetStream());
await MediaDescriptorRepository.InsertAsync(newEntity); await MediaDescriptorRepository.InsertAsync(newEntity);
return ObjectMapper.Map<MediaDescriptor, MediaDescriptorDto>(newEntity); return ObjectMapper.Map<MediaDescriptor, MediaDescriptorDto>(newEntity);
}
} }
public virtual async Task DeleteAsync(Guid id) public virtual async Task DeleteAsync(Guid id)
@ -58,4 +55,4 @@ namespace Volo.CmsKit.Admin.MediaDescriptors
await MediaDescriptorRepository.DeleteAsync(id); await MediaDescriptorRepository.DeleteAsync(id);
} }
} }
} }

7
modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/MediaDescriptors/MediaDescriptorAppService.cs

@ -24,10 +24,7 @@ namespace Volo.CmsKit.MediaDescriptors
var entity = await MediaDescriptorRepository.GetAsync(id); var entity = await MediaDescriptorRepository.GetAsync(id);
var stream = await MediaContainer.GetAsync(id.ToString()); var stream = await MediaContainer.GetAsync(id.ToString());
return new RemoteStreamContent(stream) return new RemoteStreamContent(stream, entity.Name, entity.MimeType);
{
ContentType = entity.MimeType
};
} }
} }
} }

11
modules/cms-kit/test/Volo.CmsKit.Application.Tests/MediaDescriptors/MediaDescriptorAdminAppService_Tests.cs

@ -35,15 +35,12 @@ namespace Volo.CmsKit.MediaDescriptors
var media = await _mediaDescriptorAdminAppService.CreateAsync(_cmsKitTestData.Media_1_EntityType, new CreateMediaInputWithStream var media = await _mediaDescriptorAdminAppService.CreateAsync(_cmsKitTestData.Media_1_EntityType, new CreateMediaInputWithStream
{ {
Name = mediaName, Name = mediaName,
File = new RemoteStreamContent(stream) File = new RemoteStreamContent(stream, mediaName, mediaType)
{
ContentType = mediaType
}
}); });
media.ShouldNotBeNull(); media.ShouldNotBeNull();
} }
[Fact] [Fact]
public async Task Should_Delete_Media() public async Task Should_Delete_Media()
{ {
@ -52,4 +49,4 @@ namespace Volo.CmsKit.MediaDescriptors
(await _mediaDescriptorRepository.FindAsync(_cmsKitTestData.Media_1_Id)).ShouldBeNull(); (await _mediaDescriptorRepository.FindAsync(_cmsKitTestData.Media_1_Id)).ShouldBeNull();
} }
} }
} }

Loading…
Cancel
Save