Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 84 additions & 5 deletions src/DotNetWorker.Core/Http/HttpResponseDataExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -77,7 +78,23 @@ public static Task WriteStringAsync(this HttpResponseData response, string value
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous operation.</returns>
public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T instance, CancellationToken cancellationToken = default)
{
return WriteAsJsonAsync(response, instance, "application/json; charset=utf-8", cancellationToken);
return WriteAsJsonAsync(response, instance, "application/json; charset=utf-8", HttpStatusCode.OK, cancellationToken);
}

/// <summary>
/// Write the specified value as JSON to the response body using the provided <see cref="ObjectSerializer"/>.
/// The response content-type will be set to <code>application/json; charset=utf-8</code> and the status code set to 200.
/// </summary>
/// <typeparam name="T">The type of object to write.</typeparam>
/// <param name="response">The response to write JSON to.</param>
/// <param name="instance">The instance to serialize and write as JSON.</param>
/// <param name="statusCode">The status code to set on the response.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous operation.</returns>
public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T instance, HttpStatusCode statusCode,
CancellationToken cancellationToken = default)
{
return WriteAsJsonAsync(response, instance, "application/json; charset=utf-8", statusCode, cancellationToken);
}

/// <summary>
Expand All @@ -100,9 +117,35 @@ public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T in
ObjectSerializer serializer = response.FunctionContext.InstanceServices.GetService<IOptions<WorkerOptions>>()?.Value?.Serializer
?? throw new InvalidOperationException("A serializer is not configured for the worker.");

return WriteAsJsonAsync(response, instance, serializer, contentType, cancellationToken);
return WriteAsJsonAsync(response, instance, serializer, contentType, HttpStatusCode.OK, cancellationToken);
}

/// <summary>
/// Write the specified value as JSON to the response body using the default <see cref="ObjectSerializer"/> configured for this worker.
/// The response content-type will be set to the provided <paramref name="contentType"/> and the status code set to 200.
/// </summary>
/// <typeparam name="T">The type of object to write.</typeparam>
/// <param name="response">The response to write JSON to.</param>
/// <param name="instance">The instance to serialize and write as JSON.</param>
/// <param name="contentType">The content-type to set on the response.</param>
/// <param name="statusCode">The status code to set on the response.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous operation.</returns>
public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T instance, string contentType, HttpStatusCode statusCode,
CancellationToken cancellationToken = default)
{
if (response is null)
{
throw new ArgumentNullException(nameof(response));
}

ObjectSerializer serializer = response.FunctionContext.InstanceServices.GetService<IOptions<WorkerOptions>>()?.Value?.Serializer
?? throw new InvalidOperationException("A serializer is not configured for the worker.");

return WriteAsJsonAsync(response, instance, serializer, contentType, statusCode, cancellationToken);
}


/// <summary>
/// Write the specified value as JSON to the response body using the provided <see cref="ObjectSerializer"/>.
/// The response content-type will be set to <code>application/json; charset=utf-8</code> and the status code set to 200.
Expand All @@ -115,7 +158,42 @@ public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T in
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous operation.</returns>
public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T instance, ObjectSerializer serializer, CancellationToken cancellationToken = default)
{
return WriteAsJsonAsync(response, instance, serializer, "application/json; charset=utf-8", cancellationToken);
return WriteAsJsonAsync(response, instance, serializer, "application/json; charset=utf-8", HttpStatusCode.OK, cancellationToken);
}

/// <summary>
/// Write the specified value as JSON to the response body using the provided <see cref="ObjectSerializer"/>.
/// The response content-type will be set to <code>application/json; charset=utf-8</code> and the status code set to 200.
/// </summary>
/// <typeparam name="T">The type of object to write.</typeparam>
/// <param name="response">The response to write JSON to.</param>
/// <param name="instance">The instance to serialize and write as JSON.</param>
/// <param name="serializer">The serializer used to serialize the instance.</param>
/// <param name="statusCode">The status code to set on the response.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous operation.</returns>
public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T instance, ObjectSerializer serializer, HttpStatusCode statusCode,
CancellationToken cancellationToken = default)
{
return WriteAsJsonAsync(response, instance, serializer, "application/json; charset=utf-8", statusCode, cancellationToken);
}

/// <summary>
/// Write the specified value as JSON to the response body using the provided <see cref="ObjectSerializer"/>.
/// The response content-type will be set to the provided <paramref name="contentType"/> and the status code set to 200.
/// </summary>
/// <typeparam name="T">The type of object to write.</typeparam>
/// <param name="response">The response to write JSON to.</param>
/// <param name="instance">The instance to serialize and write as JSON.</param>
/// <param name="serializer">The serializer used to serialize the instance.</param>
/// <param name="contentType">The content-type to set on the response.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous operation.</returns>
public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T instance,
ObjectSerializer serializer, string contentType,
CancellationToken cancellationToken = default)
{
return WriteAsJsonAsync(response, instance, serializer, contentType, HttpStatusCode.OK, cancellationToken);
}

/// <summary>
Expand All @@ -127,9 +205,10 @@ public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T in
/// <param name="instance">The instance to serialize and write as JSON.</param>
/// <param name="serializer">The serializer used to serialize the instance.</param>
/// <param name="contentType">The content-type to set on the response.</param>
/// <param name="statusCode">The status code to set on the response.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous operation.</returns>
public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T instance, ObjectSerializer serializer, string contentType, CancellationToken cancellationToken = default)
public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T instance, ObjectSerializer serializer, string contentType, HttpStatusCode statusCode, CancellationToken cancellationToken = default)
{
if (response is null)
{
Expand All @@ -147,7 +226,7 @@ public static ValueTask WriteAsJsonAsync<T>(this HttpResponseData response, T in
}

response.Headers.Add("Content-Type", contentType);
response.StatusCode = System.Net.HttpStatusCode.OK;
response.StatusCode = statusCode;

return serializer.SerializeAsync(response.Body, instance, typeof(T), cancellationToken);
}
Expand Down
21 changes: 21 additions & 0 deletions test/DotNetWorkerTests/HttpResponseDataExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,27 @@ public async Task WriteAsJsonAsync_ContentTypeOverload_AppliesParameters()
Assert.Equal("{\"jsonnetname\":\"Test\",\"jsonnetint\":42}", result);
}

[Fact]
public async Task WriteAsJsonAsync_StatusCodeOverload_AppliesParameters()
{
FunctionContext context = CreateContext(new NewtonsoftJsonObjectSerializer());
var response = CreateResponse(context);

var poco = new ResponsePoco
{
Name = "Test",
SomeInt = 42
};

await HttpResponseDataExtensions.WriteAsJsonAsync(response, poco, HttpStatusCode.BadRequest);

string result = ReadResponseBody(response);

Assert.Equal("application/json; charset=utf-8", response.Headers.GetValues("content-type").FirstOrDefault());
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
Assert.Equal("{\"jsonnetname\":\"Test\",\"jsonnetint\":42}", result);
}

[Fact]
public async Task WriteAsJsonAsync_SerializerAndContentTypeOverload_AppliesParameters()
{
Expand Down