/// <summary> /// Writes the specified <see cref="System.IO.Stream"/> to the response. /// <para> /// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or /// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable). /// </para> /// <para> /// This API is an alias for <see cref="File(Stream, string, string?, DateTimeOffset?, EntityTagHeaderValue?, bool)"/>. /// </para> /// </summary> /// <param name="stream">The <see cref="System.IO.Stream"/> to write to the response.</param> /// <param name="contentType">The <c>Content-Type</c> of the response. Defaults to <c>application/octet-stream</c>.</param> /// <param name="fileDownloadName">The the file name to be used in the <c>Content-Disposition</c> header.</param> /// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified. /// Used to configure the <c>Last-Modified</c> response header and perform conditional range requests.</param> /// <param name="entityTag">The <see cref="EntityTagHeaderValue"/> to be configure the <c>ETag</c> response header /// and perform conditional requests.</param> /// <param name="enableRangeProcessing">Set to <c>true</c> to enable range requests processing.</param> /// <returns>The created <see cref="IResult"/> for the response.</returns> /// <remarks> /// The <paramref name="stream" /> parameter is disposed after the response is sent. /// </remarks> public static IResult Stream( Stream stream, string?contentType = null, string?fileDownloadName = null, DateTimeOffset?lastModified = null, EntityTagHeaderValue?entityTag = null, bool enableRangeProcessing = false) => TypedResults.Stream(stream, contentType, fileDownloadName, lastModified, entityTag, enableRangeProcessing);
/// <summary> /// Allows writing directly to the response body. /// <para> /// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or /// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable). /// </para> /// </summary> /// <param name="streamWriterCallback">The callback that allows users to write directly to the response body.</param> /// <param name="contentType">The <c>Content-Type</c> of the response. Defaults to <c>application/octet-stream</c>.</param> /// <param name="fileDownloadName">The the file name to be used in the <c>Content-Disposition</c> header.</param> /// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified. /// Used to configure the <c>Last-Modified</c> response header and perform conditional range requests.</param> /// <param name="entityTag">The <see cref="EntityTagHeaderValue"/> to be configure the <c>ETag</c> response header /// and perform conditional requests.</param> /// <returns>The created <see cref="IResult"/> for the response.</returns> #pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters public static IResult Stream( #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters Func <Stream, Task> streamWriterCallback, string?contentType = null, string?fileDownloadName = null, DateTimeOffset?lastModified = null, EntityTagHeaderValue?entityTag = null) => TypedResults.Stream(streamWriterCallback, contentType, fileDownloadName, lastModified, entityTag);
/// <summary> /// Writes the contents of specified <see cref="System.IO.Pipelines.PipeReader"/> to the response. /// <para> /// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or /// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable). /// </para> /// </summary> /// <param name="pipeReader">The <see cref="System.IO.Pipelines.PipeReader"/> to write to the response.</param> /// <param name="contentType">The <c>Content-Type</c> of the response. Defaults to <c>application/octet-stream</c>.</param> /// <param name="fileDownloadName">The the file name to be used in the <c>Content-Disposition</c> header.</param> /// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified. /// Used to configure the <c>Last-Modified</c> response header and perform conditional range requests.</param> /// <param name="entityTag">The <see cref="EntityTagHeaderValue"/> to be configure the <c>ETag</c> response header /// and perform conditional requests.</param> /// <param name="enableRangeProcessing">Set to <c>true</c> to enable range requests processing.</param> /// <returns>The created <see cref="IResult"/> for the response.</returns> /// <remarks> /// The <paramref name="pipeReader" /> parameter is completed after the response is sent. /// </remarks> #pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters public static IResult Stream( #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters PipeReader pipeReader, string?contentType = null, string?fileDownloadName = null, DateTimeOffset?lastModified = null, EntityTagHeaderValue?entityTag = null, bool enableRangeProcessing = false) => TypedResults.Stream(pipeReader, contentType, fileDownloadName, lastModified, entityTag, enableRangeProcessing);
public void Stream_ResultHasCorrectValues(int overload, string contentType, string fileDownloadName, bool enableRangeProcessing, DateTimeOffset lastModified, EntityTagHeaderValue entityTag) { // Arrange var stream = new MemoryStream(); // Act var result = overload switch { 0 => TypedResults.Stream(stream, contentType, fileDownloadName, lastModified, entityTag, enableRangeProcessing), 1 => TypedResults.Stream(PipeReader.Create(stream), contentType, fileDownloadName, lastModified, entityTag, enableRangeProcessing), _ => (IResult)TypedResults.Stream((s) => Task.CompletedTask, contentType, fileDownloadName, lastModified, entityTag) }; // Assert switch (overload) { case <= 1: var fileStreamResult = result as FileStreamHttpResult; Assert.NotNull(fileStreamResult.FileStream); Assert.Equal(contentType ?? "application/octet-stream", fileStreamResult.ContentType); Assert.Equal(fileDownloadName, fileStreamResult.FileDownloadName); Assert.Equal(enableRangeProcessing, fileStreamResult.EnableRangeProcessing); Assert.Equal(lastModified, fileStreamResult.LastModified); Assert.Equal(entityTag, fileStreamResult.EntityTag); break; default: var pushStreamResult = result as PushStreamHttpResult; Assert.Equal(contentType ?? "application/octet-stream", pushStreamResult.ContentType); Assert.Equal(fileDownloadName, pushStreamResult.FileDownloadName); Assert.False(pushStreamResult.EnableRangeProcessing); Assert.Equal(lastModified, pushStreamResult.LastModified); Assert.Equal(entityTag, pushStreamResult.EntityTag); break; } }
public void Stream_WithNullCallback_ThrowsArgNullException() { Assert.Throws <ArgumentNullException>("streamWriterCallback", () => TypedResults.Stream(default(Func <Stream, Task>))); }
public void Stream_WithNullPipeReader_ThrowsArgNullException() { Assert.Throws <ArgumentNullException>("pipeReader", () => TypedResults.Stream(default(PipeReader))); }
public void Stream_WithNullStream_ThrowsArgNullException() { Assert.Throws <ArgumentNullException>("stream", () => TypedResults.Stream(default(Stream))); }