public async Task WriteAsync_DoesNotWriteNullStrings() { // Arrange Encoding encoding = Encoding.UTF8; var memoryStream = new MemoryStream(); var response = new Mock<HttpResponse>(); response.SetupProperty<long?>(o => o.ContentLength); response.SetupGet(r => r.Body).Returns(memoryStream); var httpContext = new Mock<HttpContext>(); httpContext.Setup(o => o.Response).Returns(response.Object); var formatter = new StringOutputFormatter(); var context = new OutputFormatterWriteContext( httpContext.Object, new TestHttpResponseStreamWriterFactory().CreateWriter, typeof(string), @object: null); // Act await formatter.WriteResponseBodyAsync(context); // Assert Assert.Equal(0, memoryStream.Length); response.VerifySet(r => r.ContentLength = It.IsAny<long?>(), Times.Never()); }
public void CanWriteResult_ReturnsTrueForStringTypes( object value, bool useDeclaredTypeAsString, bool expectedCanWriteResult) { // Arrange var expectedContentType = expectedCanWriteResult ? MediaTypeHeaderValue.Parse("text/plain") : MediaTypeHeaderValue.Parse("application/json"); var formatter = new StringOutputFormatter(); var type = useDeclaredTypeAsString ? typeof(string) : typeof(object); var context = new OutputFormatterWriteContext( new DefaultHttpContext(), new TestHttpResponseStreamWriterFactory().CreateWriter, type, value); context.ContentType = MediaTypeHeaderValue.Parse("application/json"); // Act var result = formatter.CanWriteResult(context); // Assert Assert.Equal(expectedCanWriteResult, result); Assert.Equal(expectedContentType, context.ContentType); }
public void CanWriteResult_ByDefault_ReturnsTrue_IfTheValueIsNull( object value, bool declaredTypeAsString, bool expected, bool useNonNullContentType) { // Arrange var type = declaredTypeAsString ? typeof(string) : typeof(object); var contentType = useNonNullContentType ? MediaTypeHeaderValue.Parse("text/plain") : null; var context = new OutputFormatterWriteContext( new DefaultHttpContext(), new TestHttpResponseStreamWriterFactory().CreateWriter, type, value) { ContentType = contentType, }; var formatter = new HttpNoContentOutputFormatter(); // Act var result = formatter.CanWriteResult(context); // Assert Assert.Equal(expected, result); }
public void SelectFormatter_WithNoProvidedContentType_DoesConneg() { // Arrange var executor = CreateExecutor(); var formatters = new List<IOutputFormatter> { new TestXmlOutputFormatter(), new TestJsonOutputFormatter(), // This will be chosen based on the accept header }; var context = new OutputFormatterWriteContext( new DefaultHttpContext(), new TestHttpResponseStreamWriterFactory().CreateWriter, objectType: null, @object: null); context.HttpContext.Request.Headers[HeaderNames.Accept] = "application/json"; // Act var formatter = executor.SelectFormatter( context, new[] { new MediaTypeHeaderValue("application/json") }, formatters); // Assert Assert.Same(formatters[1], formatter); Assert.Equal(new MediaTypeHeaderValue("application/json"), context.ContentType); }
public void SelectResponseCharacterEncoding_SelectsEncoding( string acceptCharsetHeaders, string[] supportedEncodings, string expectedEncoding) { // Arrange var httpContext = new Mock<HttpContext>(); var httpRequest = new DefaultHttpContext().Request; httpRequest.Headers[HeaderNames.AcceptCharset] = acceptCharsetHeaders; httpRequest.Headers[HeaderNames.Accept] = "application/acceptCharset"; httpContext.SetupGet(o => o.Request).Returns(httpRequest); var formatter = new TestOutputFormatter(); foreach (string supportedEncoding in supportedEncodings) { formatter.SupportedEncodings.Add(Encoding.GetEncoding(supportedEncoding)); } var context = new OutputFormatterWriteContext( httpContext.Object, new TestHttpResponseStreamWriterFactory().CreateWriter, typeof(string), "someValue") { ContentType = MediaTypeHeaderValue.Parse(httpRequest.Headers[HeaderNames.Accept]), }; // Act var actualEncoding = formatter.SelectCharacterEncoding(context); // Assert Assert.Equal(Encoding.GetEncoding(expectedEncoding), actualEncoding); }
public static void FormatterSelected( this ILogger logger, IOutputFormatter outputFormatter, OutputFormatterWriteContext context) { var contentType = Convert.ToString(context.ContentType); _formatterSelected(logger, outputFormatter, contentType, null); }
public async Task WriteAsync(OutputFormatterWriteContext context) { var response = context.HttpContext.Response; var responseMessage = context.Object as HttpResponseMessage; if (responseMessage == null) { var message = Resources.FormatHttpResponseMessageFormatter_UnsupportedType( nameof(HttpResponseMessageOutputFormatter), nameof(HttpResponseMessage)); throw new InvalidOperationException(message); } using (responseMessage) { response.StatusCode = (int)responseMessage.StatusCode; var responseFeature = context.HttpContext.Features.Get<IHttpResponseFeature>(); if (responseFeature != null) { responseFeature.ReasonPhrase = responseMessage.ReasonPhrase; } var responseHeaders = responseMessage.Headers; // Ignore the Transfer-Encoding header if it is just "chunked". // We let the host decide about whether the response should be chunked or not. if (responseHeaders.TransferEncodingChunked == true && responseHeaders.TransferEncoding.Count == 1) { responseHeaders.TransferEncoding.Clear(); } foreach (var header in responseHeaders) { response.Headers.Append(header.Key, header.Value.ToArray()); } if (responseMessage.Content != null) { var contentHeaders = responseMessage.Content.Headers; // Copy the response content headers only after ensuring they are complete. // We ask for Content-Length first because HttpContent lazily computes this // and only afterwards writes the value into the content headers. var unused = contentHeaders.ContentLength; foreach (var header in contentHeaders) { response.Headers.Append(header.Key, header.Value.ToArray()); } await responseMessage.Content.CopyToAsync(response.Body); } } }
/// <inheritdoc /> public Task WriteAsync(OutputFormatterWriteContext context) { var response = context.HttpContext.Response; response.ContentLength = 0; if (response.StatusCode == StatusCodes.Status200OK) { response.StatusCode = StatusCodes.Status204NoContent; } return Task.FromResult(true); }
public override void WriteResponseHeaders(OutputFormatterWriteContext context) { var model = (QuerySummary)context.Object; var headers = context.HttpContext.Response.Headers; string paginationString = String.Join(",", model.Page.ToString(), model.PageSize.ToString(), model.Total.ToString()); headers.Add("X-Pagination", paginationString); }
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { var contact = (Contact)context.Object; var builder = new StringBuilder(); builder.AppendLine("BEGIN:VCARD"); builder.AppendFormat("FN:{0}", contact.Name); builder.AppendLine(); builder.AppendLine("END:VCARD"); await context.HttpContext.Response.WriteAsync( builder.ToString(), context.ContentType?.Encoding ?? Encoding.UTF8); }
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { var model = (QuerySummary)context.Object; var response = context.HttpContext.Response; using (var csv = new StringWriter()) { foreach (string id in model.IDs) { csv.WriteLine(id); } response.WriteAsync(csv.ToString()); } return Task.FromResult(response); }
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var valueAsString = (string)context.Object; if (string.IsNullOrEmpty(valueAsString)) { return TaskCache.CompletedTask; } var response = context.HttpContext.Response; return response.WriteAsync(valueAsString, context.ContentType?.Encoding ?? Encoding.UTF8); }
public async Task WriteAsync_Sets406NotAcceptable() { // Arrange var formatter = new HttpNotAcceptableOutputFormatter(); var context = new OutputFormatterWriteContext( new DefaultHttpContext(), new TestHttpResponseStreamWriterFactory().CreateWriter, objectType: null, @object: null); // Act await formatter.WriteAsync(context); // Assert Assert.Equal(StatusCodes.Status406NotAcceptable, context.HttpContext.Response.StatusCode); }
public void CanWriteResult_OnlyActsOnStreams(Type type) { // Arrange var formatter = new StreamOutputFormatter(); var @object = type != null ? Activator.CreateInstance(type) : null; var context = new OutputFormatterWriteContext( new DefaultHttpContext(), new TestHttpResponseStreamWriterFactory().CreateWriter, type, @object); // Act var result = formatter.CanWriteResult(context); // Assert Assert.False(result); }
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { if (context == null) throw new ArgumentNullException(nameof(context)); var response = context.HttpContext.Response; var encoding = context.ContentType?.Encoding ?? Encoding.UTF8; var o = context.Object as StandardResponse; var standard = o ?? StandardResponse.Create(context.Object); return Task.Run(() => { using (var stream = new HttpResponseStreamWriter(response.Body, encoding)) { WriteObject(stream, standard); } }); }
public void CanWriteResult_ReturnsTrue_IfReturnTypeIsVoidOrTask(Type declaredType) { // Arrange var context = new OutputFormatterWriteContext( new DefaultHttpContext(), new TestHttpResponseStreamWriterFactory().CreateWriter, declaredType, "Something non null.") { ContentType = MediaTypeHeaderValue.Parse("text/plain"), }; var formatter = new HttpNoContentOutputFormatter(); // Act var result = formatter.CanWriteResult(context); // Assert Assert.True(result); }
public void CanWriteResult_ReturnsTrue_WhenConnegHasFailed() { // Arrange var formatter = new HttpNotAcceptableOutputFormatter(); var context = new OutputFormatterWriteContext( new DefaultHttpContext(), new TestHttpResponseStreamWriterFactory().CreateWriter, objectType: null, @object: null) { FailedContentNegotiation = true, }; // Act var result = formatter.CanWriteResult(context); // Assert Assert.True(result); }
public async Task WriteAsync(OutputFormatterWriteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var response = context.HttpContext.Response; var selectedEncoding = Encoding.UTF8; using (var writer = context.WriterFactory(response.Body, selectedEncoding)) { var requestUri = context.HttpContext.Request.Scheme + "://" + context.HttpContext.Request.Host.ToUriComponent() + context.HttpContext.Request.Path; writer.Write(_serializer.Serialize(context.Object as ResourceResult, requestUri)); // Perf: call FlushAsync to call WriteAsync on the stream with any content left in the TextWriter's // buffers. This is better than just letting dispose handle it (which would result in a synchronous // write). await writer.FlushAsync(); } }
public void CanWriteResult_ReturnsTrue_ForStreams(Type type, string contentType) { // Arrange var formatter = new StreamOutputFormatter(); var contentTypeHeader = contentType == null ? null : new MediaTypeHeaderValue(contentType); var context = new OutputFormatterWriteContext( new DefaultHttpContext(), new TestHttpResponseStreamWriterFactory().CreateWriter, type, new MemoryStream()) { ContentType = contentTypeHeader, }; // Act var canWrite = formatter.CanWriteResult(context); // Assert Assert.True(canWrite); }
public void CanWriteResult_OnlyActsOnStreams_IgnoringContentType(Type type, string contentType) { // Arrange var formatter = new StreamOutputFormatter(); var contentTypeHeader = contentType == null ? null : new MediaTypeHeaderValue(contentType); var context = new OutputFormatterWriteContext( new DefaultHttpContext(), new TestHttpResponseStreamWriterFactory().CreateWriter, type, new SimplePOCO()) { ContentType = contentTypeHeader, }; // Act var canWrite = formatter.CanWriteResult(context); // Assert Assert.False(canWrite); }
/// <inheritdoc /> public async Task WriteAsync(OutputFormatterWriteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } using (var valueAsStream = ((Stream)context.Object)) { var response = context.HttpContext.Response; if (context.ContentType != null) { response.ContentType = context.ContentType.ToString(); } var bufferingFeature = context.HttpContext.Features.Get<IHttpBufferingFeature>(); bufferingFeature?.DisableResponseBuffering(); await valueAsStream.CopyToAsync(response.Body); } }
/// <inheritdoc /> public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var response = context.HttpContext.Response; var writerSettings = WriterSettings.Clone(); writerSettings.Encoding = context.ContentType.Encoding ?? Encoding.UTF8; // Wrap the object only if there is a wrapping type. var value = context.Object; var wrappingType = GetSerializableType(context.ObjectType); if (wrappingType != null && wrappingType != context.ObjectType) { var wrapperProvider = WrapperProviderFactories.GetWrapperProvider(new WrapperProviderContext( declaredType: context.ObjectType, isSerialization: true)); value = wrapperProvider.Wrap(value); } var xmlSerializer = GetCachedSerializer(wrappingType); using (var textWriter = context.WriterFactory(context.HttpContext.Response.Body, writerSettings.Encoding)) { using (var xmlWriter = CreateXmlWriter(textWriter, writerSettings)) { xmlSerializer.Serialize(xmlWriter, value); } // Perf: call FlushAsync to call WriteAsync on the stream with any content left in the TextWriter's // buffers. This is better than just letting dispose handle it (which would result in a synchronous // write). await textWriter.FlushAsync(); } }
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { throw new NotImplementedException(); }
/// <summary> /// Writes the response body. /// </summary> /// <param name="context">The formatter context associated with the call.</param> /// <returns>A task which can write the response body.</returns> public abstract Task WriteResponseBodyAsync(OutputFormatterWriteContext context);
/// <summary> /// Sets the headers on <see cref="Microsoft.AspNet.Http.HttpResponse"/> object. /// </summary> /// <param name="context">The formatter context associated with the call.</param> public virtual void WriteResponseHeaders(OutputFormatterWriteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var response = context.HttpContext.Response; response.ContentType = context.ContentType?.ToString(); }
/// <inheritdoc /> public Task WriteAsync(OutputFormatterWriteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var selectedMediaType = context.ContentType; if (selectedMediaType == null) { // If content type is not set then set it based on supported media types. if (SupportedEncodings.Count > 0) { selectedMediaType = SupportedMediaTypes[0]; } else { throw new InvalidOperationException(Resources.FormatOutputFormatterNoMediaType(GetType().FullName)); } } // Copy the media type as it may be a 'frozen' instance. selectedMediaType = selectedMediaType.Copy(); // Note: Text-based media types will use an encoding/charset - binary formats just ignore it. We want to // make this class work with media types that use encodings, and those that don't. // // The default implementation of SelectCharacterEncoding will read from the list of SupportedEncodings // and will always choose a default encoding if any are supported. So, the only cases where the // selectedEncoding can be null are: // // 1). No supported encodings - we assume this is a non-text format // 2). Custom implementation of SelectCharacterEncoding - trust the user and give them what they want. var selectedEncoding = SelectCharacterEncoding(context); if (selectedEncoding != null) { // Override the content type value even if one already existed. selectedMediaType.Encoding = selectedEncoding; } context.ContentType = selectedMediaType; WriteResponseHeaders(context); return WriteResponseBodyAsync(context); }
/// <summary> /// Determines the best <see cref="Encoding"/> amongst the supported encodings /// for reading or writing an HTTP entity body based on the provided <paramref name="contentTypeHeader"/>. /// </summary> /// <param name="context">The formatter context associated with the call. /// </param> /// <returns>The <see cref="Encoding"/> to use when reading the request or writing the response.</returns> public virtual Encoding SelectCharacterEncoding(OutputFormatterWriteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var request = context.HttpContext.Request; var encoding = MatchAcceptCharacterEncoding(request.GetTypedHeaders().AcceptCharset); if (encoding != null) { return encoding; } var charset = context.ContentType?.Charset; if (charset != null) { for (var i = 0; i < SupportedEncodings.Count; i++) { if (string.Equals(charset, SupportedEncodings[i].WebName, StringComparison.OrdinalIgnoreCase)) { // This is supported. return context.ContentType.Encoding; } } } // A formatter for a non-text media-type won't have any supported encodings. return SupportedEncodings.Count > 0 ? SupportedEncodings[0] : null; }
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { return(Task.FromResult(true)); }
/// <inheritdoc /> public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var response = context.HttpContext.Response; var writerSettings = WriterSettings.Clone(); writerSettings.Encoding = context.ContentType.Encoding ?? Encoding.UTF8; // Wrap the object only if there is a wrapping type. var value = context.Object; var wrappingType = GetSerializableType(context.ObjectType); if (wrappingType != null && wrappingType != context.ObjectType) { var wrapperProvider = WrapperProviderFactories.GetWrapperProvider(new WrapperProviderContext( declaredType: context.ObjectType, isSerialization: true)); value = wrapperProvider.Wrap(value); } var xmlSerializer = GetCachedSerializer(wrappingType); using (var textWriter = context.WriterFactory(context.HttpContext.Response.Body, writerSettings.Encoding)) { using (var xmlWriter = CreateXmlWriter(textWriter, writerSettings)) { xmlSerializer.Serialize(xmlWriter, value); } } return TaskCache.CompletedTask; }
public async Task WriteToStreamAsync_UsesCorrectCharacterEncoding( string content, string encodingAsString, bool isDefaultEncoding) { // Arrange var formatter = new JsonOutputFormatter(); var formattedContent = "\"" + content + "\""; var mediaType = MediaTypeHeaderValue.Parse(string.Format("application/json; charset={0}", encodingAsString)); var encoding = CreateOrGetSupportedEncoding(formatter, encodingAsString, isDefaultEncoding); var expectedData = encoding.GetBytes(formattedContent); var body = new MemoryStream(); var actionContext = GetActionContext(mediaType, body); var outputFormatterContext = new OutputFormatterWriteContext( actionContext.HttpContext, new TestHttpResponseStreamWriterFactory().CreateWriter, typeof(string), content) { ContentType = mediaType, }; // Act await formatter.WriteResponseBodyAsync(outputFormatterContext); // Assert var actualData = body.ToArray(); Assert.Equal(expectedData, actualData); }
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var response = context.HttpContext.Response; var selectedEncoding = context.ContentType?.Encoding ?? Encoding.UTF8; using (var writer = context.WriterFactory(response.Body, selectedEncoding)) { WriteObject(writer, context.Object); } return Task.FromResult(true); }