예제 #1
0
        public override async Task ExecuteResultAsync(ActionContext context)
        {
            // See if the list of content types added to this object result is valid.
            ThrowIfUnsupportedContentType();
            var formatters = GetDefaultFormatters(context);
            var formatterContext = new OutputFormatterContext()
            {
                DeclaredType = DeclaredType,
                ActionContext = context,
                Object = Value,
                StatusCode = StatusCode
            };

            var selectedFormatter = SelectFormatter(formatterContext, formatters);
            if (selectedFormatter == null)
            {
                // No formatter supports this.
                context.HttpContext.Response.StatusCode = StatusCodes.Status406NotAcceptable;
                return;
            }

            if (StatusCode.HasValue)
            {
                context.HttpContext.Response.StatusCode = StatusCode.Value;
            }

            OnFormatting(context);
            await selectedFormatter.WriteAsync(formatterContext);
        }
예제 #2
0
 public async Task WriteAsync(OutputFormatterContext context)
 {
     // Override using the selected encoding.
     context.SelectedEncoding = Encoding;
     var jsonFormatter = new JsonOutputFormatter();
     await jsonFormatter.WriteResponseBodyAsync(context);
 }
예제 #3
0
        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 mockHttpContext = new Mock <HttpContext>();

            mockHttpContext.Setup(o => o.Response).Returns(response.Object);

            var formatter        = new TextPlainFormatter();
            var formatterContext = new OutputFormatterContext()
            {
                Object           = null,
                DeclaredType     = typeof(string),
                ActionContext    = new ActionContext(mockHttpContext.Object, new RouteData(), new ActionDescriptor()),
                SelectedEncoding = encoding
            };

            // Act
            await formatter.WriteResponseBodyAsync(formatterContext);

            // Assert
            Assert.Equal(0, memoryStream.Length);
            response.VerifySet(r => r.ContentLength = It.IsAny <long?>(), Times.Never());
        }
예제 #4
0
        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 mockHttpContext = new Mock<HttpContext>();
            mockHttpContext.Setup(o => o.Response).Returns(response.Object);

            var formatter = new StringOutputFormatter();
            var formatterContext = new OutputFormatterContext()
            {
                Object = null,
                DeclaredType = typeof(string),
                HttpContext = mockHttpContext.Object,
                SelectedEncoding = encoding
            };

            // Act
            await formatter.WriteResponseBodyAsync(formatterContext);

            // Assert
            Assert.Equal(0, memoryStream.Length);
            response.VerifySet(r => r.ContentLength = It.IsAny<long?>(), Times.Never());
        }
예제 #5
0
        public override async Task ExecuteResultAsync(ActionContext context)
        {
            var formatters       = GetDefaultFormatters(context);
            var formatterContext = new OutputFormatterContext()
            {
                DeclaredType  = DeclaredType,
                ActionContext = context,
                Object        = Value,
            };

            var selectedFormatter = SelectFormatter(formatterContext, formatters);

            if (selectedFormatter == null)
            {
                // No formatter supports this.
                context.HttpContext.Response.StatusCode = 406;
                return;
            }

            if (StatusCode != null)
            {
                context.HttpContext.Response.StatusCode = (int)StatusCode;
            }

            OnFormatting(context);
            await selectedFormatter.WriteAsync(formatterContext);
        }
예제 #6
0
        /// <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([NotNull] OutputFormatterContext context)
        {
            var selectedMediaType = context.SelectedContentType;

            // If content type is not set then set it based on supported media types.
            selectedMediaType = selectedMediaType ?? SupportedMediaTypes.FirstOrDefault();
            if (selectedMediaType == null)
            {
                throw new InvalidOperationException(Resources.FormatOutputFormatterNoMediaType(GetType().FullName));
            }

            // Clone the media type as we don't want it to affect the next request
            selectedMediaType = MediaTypeHeaderValue.Parse(selectedMediaType.ToString());

            var selectedEncoding = SelectCharacterEncoding(context);

            if (selectedEncoding == null)
            {
                // No supported encoding was found so there is no way for us to start writing.
                throw new InvalidOperationException(Resources.FormatOutputFormatterNoEncoding(GetType().FullName));
            }

            context.SelectedEncoding = selectedEncoding;

            // Override the content type value even if one already existed.
            selectedMediaType.Charset = selectedEncoding.WebName;

            context.SelectedContentType = context.SelectedContentType ?? selectedMediaType;
            var response = context.ActionContext.HttpContext.Response;

            response.ContentType = selectedMediaType.ToString();
        }
예제 #7
0
        public void SelectFormatter_WithNoMatchingAcceptHeadersAndRequestContentType_PicksFormatterBasedOnObjectType
            (string acceptHeader)
        {
            // For no accept headers,
            // can write is called twice once for the request Content-Type and once for the type match pass.
            // For each additional accept header, it is called once.
            // Arrange
            var acceptHeaderCollection = string.IsNullOrEmpty(acceptHeader) ?
                                         null : MediaTypeHeaderValue.ParseList(new[] { acceptHeader }).ToArray();
            var stream       = new MemoryStream();
            var httpResponse = new Mock <HttpResponse>();

            httpResponse.SetupProperty <string>(o => o.ContentType);
            httpResponse.SetupGet(r => r.Body).Returns(stream);

            var actionContext = CreateMockActionContext(httpResponse.Object,
                                                        requestAcceptHeader: acceptHeader,
                                                        requestContentType: "application/xml");
            var input  = "testInput";
            var result = new ObjectResult(input);
            var mockCountingFormatter = new Mock <IOutputFormatter>();

            var context = new OutputFormatterContext()
            {
                HttpContext  = actionContext.HttpContext,
                Object       = input,
                DeclaredType = typeof(string)
            };
            var mockCountingSupportedContentType = MediaTypeHeaderValue.Parse("application/text");

            mockCountingFormatter.Setup(o => o.CanWriteResult(context,
                                                              It.Is <MediaTypeHeaderValue>(mth => mth == null)))
            .Returns(true);
            mockCountingFormatter.Setup(o => o.CanWriteResult(context, mockCountingSupportedContentType))
            .Returns(true);

            // Set more than one formatters. The test output formatter throws on write.
            result.Formatters = new List <IOutputFormatter>
            {
                new CannotWriteFormatter(),
                mockCountingFormatter.Object,
            };

            // Act
            var formatter = result.SelectFormatter(context, result.Formatters);

            // Assert
            Assert.Equal(mockCountingFormatter.Object, formatter);
            mockCountingFormatter.Verify(v => v.CanWriteResult(context, null), Times.Once());

            // CanWriteResult is invoked for the following cases:
            // 1. For each accept header present
            // 2. Request Content-Type
            // 3. Type based match
            var callCount = (acceptHeaderCollection == null ? 0 : acceptHeaderCollection.Count()) + 2;

            mockCountingFormatter.Verify(v => v.CanWriteResult(context,
                                                               It.IsNotIn <MediaTypeHeaderValue>(mockCountingSupportedContentType)),
                                         Times.Exactly(callCount));
        }
예제 #8
0
        /// <inheritdoc />
        public Task WriteAsync(OutputFormatterContext context)
        {
            var response = context.HttpContext.Response;

            response.StatusCode = StatusCodes.Status406NotAcceptable;
            return(Task.FromResult(true));
        }
예제 #9
0
        /// <inheritdoc />
        public virtual bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
        {
            MediaTypeHeaderValue mediaType = null;
            if (contentType == null)
            {
                // If the desired content type is set to null, the current formatter is free to choose the 
                // response media type. 
                mediaType = SupportedMediaTypes.FirstOrDefault();
            }
            else
            {
                // Since supportedMedia Type is going to be more specific check if supportedMediaType is a subset
                // of the content type which is typically what we get on acceptHeader.
                mediaType = SupportedMediaTypes
                                  .FirstOrDefault(supportedMediaType => supportedMediaType.IsSubsetOf(contentType));
            }

            if (mediaType != null)
            {
                context.SelectedContentType = mediaType;
                return true;
            }

            return false;
        }
        /// <inheritdoc />
        public Task WriteAsync(OutputFormatterContext context)
        {
            var response = context.ActionContext.HttpContext.Response;

            response.StatusCode = 406;
            return(Task.FromResult(true));
        }
예제 #11
0
        public override async Task ExecuteResultAsync(ActionContext context)
        {
            // See if the list of content types added to this object result is valid.
            ThrowIfUnsupportedContentType();
            var formatters       = GetDefaultFormatters(context);
            var formatterContext = new OutputFormatterContext()
            {
                DeclaredType  = DeclaredType,
                ActionContext = context,
                Object        = Value,
                StatusCode    = StatusCode
            };

            var selectedFormatter = SelectFormatter(formatterContext, formatters);

            if (selectedFormatter == null)
            {
                // No formatter supports this.
                context.HttpContext.Response.StatusCode = StatusCodes.Status406NotAcceptable;
                return;
            }

            if (StatusCode.HasValue)
            {
                context.HttpContext.Response.StatusCode = StatusCode.Value;
            }

            OnFormatting(context);
            await selectedFormatter.WriteAsync(formatterContext);
        }
예제 #12
0
 public Task WriteAsync(OutputFormatterContext context)
 {
     var response = context.HttpContext.Response;
     response.ContentLength = 0;
     response.StatusCode = context.StatusCode ?? StatusCodes.Status204NoContent;
     return Task.FromResult(true);
 }
예제 #13
0
        private IEnumerable <MediaTypeHeaderValue> GetSortedAcceptHeaderMediaTypes(
            OutputFormatterContext formatterContext)
        {
            var request = formatterContext.HttpContext.Request;
            var incomingAcceptHeaderMediaTypes = request.GetTypedHeaders().Accept ?? new MediaTypeHeaderValue[] { };

            // By default we want to ignore considering accept headers for content negotiation when
            // they have a media type like */* in them. Browsers typically have these media types.
            // In these cases we would want the first formatter in the list of output formatters to
            // write the response. This default behavior can be changed through options, so checking here.
            var options = formatterContext
                          .HttpContext
                          .RequestServices
                          .GetRequiredService <IOptions <MvcOptions> >()
                          .Value;

            var respectAcceptHeader = true;

            if (options.RespectBrowserAcceptHeader == false &&
                incomingAcceptHeaderMediaTypes.Any(mediaType => mediaType.MatchesAllTypes))
            {
                respectAcceptHeader = false;
            }

            var sortedAcceptHeaderMediaTypes = Enumerable.Empty <MediaTypeHeaderValue>();

            if (respectAcceptHeader)
            {
                sortedAcceptHeaderMediaTypes = SortMediaTypeHeaderValues(incomingAcceptHeaderMediaTypes)
                                               .Where(header => header.Quality != HeaderQuality.NoMatch);
            }

            return(sortedAcceptHeaderMediaTypes);
        }
예제 #14
0
        /// <inheritdoc />
        public override async Task ExecuteResultAsync([NotNull] ActionContext context)
        {
            var objectResult = new ObjectResult(Value);

            // Set the content type explicitly to application/json and text/json.
            // if the user has not already set it.
            if (ContentTypes == null || ContentTypes.Count == 0)
            {
                foreach (var contentType in DefaultContentTypes)
                {
                    objectResult.ContentTypes.Add(contentType);
                }
            }
            else
            {
                objectResult.ContentTypes = ContentTypes;
            }

            var formatterContext = new OutputFormatterContext()
            {
                ActionContext = context,
                DeclaredType  = objectResult.DeclaredType,
                Object        = Value,
            };

            var formatter = SelectFormatter(objectResult, formatterContext);
            await formatter.WriteAsync(formatterContext);
        }
예제 #15
0
        /// <inheritdoc />
        public virtual bool CanWriteResult([NotNull] OutputFormatterContext context, MediaTypeHeaderValue contentType)
        {
            var runtimeType = context.Object == null ? null : context.Object.GetType();

            if (!CanWriteType(context.DeclaredType, runtimeType))
            {
                return(false);
            }

            MediaTypeHeaderValue mediaType = null;

            if (contentType == null)
            {
                // If the desired content type is set to null, the current formatter is free to choose the
                // response media type.
                mediaType = SupportedMediaTypes.FirstOrDefault();
            }
            else
            {
                // Since supportedMedia Type is going to be more specific check if supportedMediaType is a subset
                // of the content type which is typically what we get on acceptHeader.
                mediaType = SupportedMediaTypes
                            .FirstOrDefault(supportedMediaType => supportedMediaType.IsSubsetOf(contentType));
            }

            if (mediaType != null)
            {
                context.SelectedContentType = mediaType;
                return(true);
            }

            return(false);
        }
예제 #16
0
        public Task WriteAsync(OutputFormatterContext context)
        {
            var response = context.HttpContext.Response;

            response.ContentLength = 0;
            response.StatusCode    = context.StatusCode ?? StatusCodes.Status204NoContent;
            return(Task.FromResult(true));
        }
예제 #17
0
 public async Task WriteAsync(OutputFormatterContext context)
 {
     // Override using the selected encoding.
     context.SelectedEncoding = Encoding;
     var jsonFormatter = new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(),
                                                 indent: false);
     await jsonFormatter.WriteResponseBodyAsync(context);
 }
        public async override Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var itemType = context.DeclaredType.GetElementType() ?? context.DeclaredType.GetGenericArguments()[0];

            using (var stringWriter = new StringWriter())
            {
                stringWriter.WriteLine(
                    string.Join<string>(
                        ",", itemType.GetProperties().Select(x => x.Name)
                        )
                    );

                foreach (var obj in (IEnumerable<object>) context.Object)
                {
                    var vals = obj.GetType().GetProperties().Select(
                        pi => new
                        {
                            Value = pi.GetValue(obj, null)
                        }
                        );

                    var valueLine = string.Empty;

                    string _val;
                    foreach (var val in vals)
                    {
                        if (val.Value != null)
                        {
                            _val = val.Value.ToString();
                            //Check if the value contans a comma and place it in quotes if so
                            if (_val.Contains(","))
                                _val = string.Concat("\"", _val, "\"");

                            //Replace any \r or \n special characters from a new line with a space
                            if (_val.Contains("\r"))
                                _val = _val.Replace("\r", " ");
                            if (_val.Contains("\n"))
                                _val = _val.Replace("\n", " ");

                            valueLine = string.Concat(valueLine, _val, ",");

                        }
                        else
                        {
                            valueLine = string.Concat(valueLine, ",");
                        }
                    }

                    stringWriter.WriteLine(valueLine.TrimEnd(','));
                }

                var writer = new StreamWriter(context.HttpContext.Response.Body);
                await writer.WriteAsync(stringWriter.ToString());
                await writer.FlushAsync();
            }
        }
        public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var response = context.ActionContext.HttpContext.Response;
            var selectedEncoding = context.SelectedEncoding;

            Model.Serialize(response.Body, context.Object);
            return;

            // await response.Body.WriteAsync(valueAsString, context.SelectedEncoding);
        }
예제 #20
0
        public override void WriteResponseHeaders(OutputFormatterContext context)
        {
            if (context.Object is IEdmModel)
            {
                context.SelectedContentType = SupportedMediaTypes[2];
            }

            context.ActionContext.HttpContext.Response.Headers.Add("OData-Version", new[] { "4.0" });
            base.WriteResponseHeaders(context);
        }
예제 #21
0
        /// <inheritdoc />
        public bool CanWriteResult([NotNull] OutputFormatterContext context, MediaTypeHeaderValue contentType)
        {
            // Ignore the passed in content type, if the object is a Stream.
            if (context.Object is Stream)
            {
                context.SelectedContentType = contentType;
                return(true);
            }

            return(false);
        }
예제 #22
0
        public override async Task WriteResponseBodyAsync(OutputFormatterContext 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.SelectedEncoding);
        }
예제 #23
0
        public override Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var response         = context.HttpContext.Response;
            var selectedEncoding = context.SelectedEncoding;

            using (var writer = new HttpResponseStreamWriter(response.Body, selectedEncoding))
            {
                WriteObject(writer, context.Object);
            }

            return(Task.FromResult(true));
        }
예제 #24
0
        public override Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var response = context.HttpContext.Response;
            var selectedEncoding = context.SelectedEncoding;

            using (var writer = new HttpResponseStreamWriter(response.Body, selectedEncoding))
            {
                WriteObject(writer, context.Object);
            }

            return Task.FromResult(true);
        }
예제 #25
0
        public Task WriteAsync(OutputFormatterContext context)
        {
            var response = context.ActionContext.HttpContext.Response;

            response.ContentLength = 0;

            // Only set the status code if its not already set.
            // TODO: By default the status code is set to 200.
            // https://github.com/aspnet/HttpAbstractions/issues/114
            response.StatusCode = 204;
            return(Task.FromResult(true));
        }
예제 #26
0
        public bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
        {
            // ignore the contentType and just look at the content.
            // This formatter will be selected if the content is null.
            // We check for Task as a user can directly create an ObjectContentResult with the unwrapped type.
            if (context.DeclaredType == typeof(void) || context.DeclaredType == typeof(Task))
            {
                return true;
            }

            return TreatNullValueAsNoContent && context.Object == null;
        }
예제 #27
0
        public bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
        {
            // ignore the contentType and just look at the content.
            // This formatter will be selected if the content is null.
            // We check for Task as a user can directly create an ObjectContentResult with the unwrapped type.
            if (context.DeclaredType == typeof(void) || context.DeclaredType == typeof(Task))
            {
                return(true);
            }

            return(TreatNullValueAsNoContent && context.Object == null);
        }
예제 #28
0
 public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
 {
     if (base.CanWriteResult(context, contentType))
     {
         var actionReturnString = context.Object as string;
         if (actionReturnString != null)
         {
             return true;
         }
     }
     return false;
 }
예제 #29
0
        public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var valueAsString = (string)context.Object;
            if (string.IsNullOrEmpty(valueAsString))
            {
                return;
            }

            var response = context.HttpContext.Response;

            await response.WriteAsync(valueAsString, context.SelectedEncoding);
        }
예제 #30
0
        /// <inheritdoc />
        public override bool CanWriteResult([NotNull] OutputFormatterContext context, MediaTypeHeaderValue contentType)
        {
            if (base.CanWriteResult(context, contentType))
            {
                if (CreateSerializer(GetObjectType(context)) != null)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #31
0
        public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var valueAsString = (string)context.Object;

            if (string.IsNullOrEmpty(valueAsString))
            {
                return;
            }

            var response = context.HttpContext.Response;

            await response.WriteAsync(valueAsString, context.SelectedEncoding);
        }
예제 #32
0
        public override Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var response         = context.ActionContext.HttpContext.Response;
            var selectedEncoding = context.SelectedEncoding;

            using (var delegatingStream = new DelegatingStream(response.Body))
                using (var writer = new StreamWriter(delegatingStream, selectedEncoding, 1024, leaveOpen: true))
                {
                    WriteObject(writer, context.Object);
                }

            return(Task.FromResult(true));
        }
예제 #33
0
        public virtual IOutputFormatter SelectFormatterUsingAnyAcceptableContentType(
            OutputFormatterContext formatterContext,
            IEnumerable <IOutputFormatter> formatters,
            IEnumerable <MediaTypeHeaderValue> acceptableContentTypes)
        {
            var selectedFormatter = formatters.FirstOrDefault(
                formatter =>
                acceptableContentTypes
                .Any(contentType =>
                     formatter.CanWriteResult(formatterContext, contentType)));

            return(selectedFormatter);
        }
예제 #34
0
        /// <summary>
        /// Gets the type of the object to be serialized.
        /// </summary>
        /// <param name="context">The context which contains the object to be serialized.</param>
        /// <returns>The type of the object to be serialized.</returns>
        public virtual Type GetObjectType([NotNull] OutputFormatterContext context)
        {
            if (context.DeclaredType == null ||
                context.DeclaredType == typeof(object))
            {
                if (context.Object != null)
                {
                    return(context.Object.GetType());
                }
            }

            return(context.DeclaredType);
        }
예제 #35
0
        public override Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var response = context.ActionContext.HttpContext.Response;
            var selectedEncoding = context.SelectedEncoding;

            using (var nonDisposableStream = new NonDisposableStream(response.Body))
            using (var writer = new StreamWriter(nonDisposableStream, selectedEncoding, 1024, leaveOpen: true))
            {
                WriteObject(writer, context.Object);
            }

            return Task.FromResult(true);
        }
예제 #36
0
        /// <inheritdoc />
        public async Task WriteAsync([NotNull] OutputFormatterContext context)
        {
            using (var valueAsStream = ((Stream)context.Object))
            {
                var response = context.ActionContext.HttpContext.Response;

                if (context.SelectedContentType != null)
                {
                    response.ContentType = context.SelectedContentType.ToString();
                }

                await valueAsStream.CopyToAsync(response.Body);
            }
        }
예제 #37
0
        public virtual IOutputFormatter SelectFormatterBasedOnTypeMatch(
            OutputFormatterContext formatterContext,
            IEnumerable <IOutputFormatter> formatters)
        {
            foreach (var formatter in formatters)
            {
                if (formatter.CanWriteResult(formatterContext, contentType: null))
                {
                    return(formatter);
                }
            }

            return(null);
        }
예제 #38
0
 public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
 {
     if (base.CanWriteResult(context, contentType))
     {
         var actionReturn = context.Object as Product;
         if (actionReturn != null)
         {
             var response = context.ActionContext.HttpContext.Response;
             context.SelectedContentType = contentType;
             return true;
         }
     }
     return false;
 }
예제 #39
0
        public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var valueAsString = (string)context.Object;
            if (valueAsString == null)
            {
                // if the value is null don't write anything.
                return;
            }

            var response = context.ActionContext.HttpContext.Response;
            using (var writer = new StreamWriter(response.Body, context.SelectedEncoding, 1024, leaveOpen: true))
            {
                await writer.WriteAsync(valueAsString);
            }
        }
예제 #40
0
        public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
        {
            // Ignore the passed in content type, if the object is string
            // always return it as a text/plain format.
            if (context.DeclaredType == typeof(string))
            {
                return true;
            }

            if (context.Object is string)
            {
                return true;
            }

            return false;
        }
예제 #41
0
        public void CanWriteResult_SetsContentType()
        {
            // Arrange
            var formatter   = new StreamOutputFormatter();
            var contentType = new MediaTypeHeaderValue("text/plain");
            var context     = new OutputFormatterContext();

            context.Object = new MemoryStream();

            // Act
            var result = formatter.CanWriteResult(context, contentType);

            // Assert
            Assert.True(result);
            Assert.Same(contentType, context.SelectedContentType);
        }
예제 #42
0
        public void CanWriteResult_OnlyActsOnStreams(Type type)
        {
            // Arrange
            var formatter   = new StreamOutputFormatter();
            var context     = new OutputFormatterContext();
            var contentType = new MediaTypeHeaderValue("text/plain");

            context.Object = type != null?Activator.CreateInstance(type) : null;

            // Act
            var result = formatter.CanWriteResult(context, contentType);

            // Assert
            Assert.False(result);
            Assert.Null(context.SelectedContentType);
        }
예제 #43
0
        public override async Task WriteResponseBodyAsync(OutputFormatterContext 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");

            var responseStream = new NonDisposableStream(context.ActionContext.HttpContext.Response.Body);
            using (var writer = new StreamWriter(responseStream, context.SelectedEncoding, bufferSize: 1024))
            {
                await writer.WriteAsync(builder.ToString());
            }
        }
        public void CanWriteResult_OnlyActsOnStreams(Type type)
        {
            // Arrange
            var formatter = new StreamOutputFormatter();
            var context = new OutputFormatterContext();
            var contentType = new MediaTypeHeaderValue("text/plain");

            context.Object = type != null ? Activator.CreateInstance(type) : null;

            // Act
            var result = formatter.CanWriteResult(context, contentType);

            // Assert
            Assert.False(result);
            Assert.Null(context.SelectedContentType);
        }
예제 #45
0
        public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
        {
            // Ignore the passed in content type, if the object is string
            // always return it as a text/plain format.
            if (context.DeclaredType == typeof(string))
            {
                return(true);
            }

            if (context.Object is string)
            {
                return(true);
            }

            return(false);
        }
예제 #46
0
        public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var valueAsString = (string)context.Object;

            if (valueAsString == null)
            {
                // if the value is null don't write anything.
                return;
            }

            var response = context.ActionContext.HttpContext.Response;

            using (var writer = new StreamWriter(response.Body, context.SelectedEncoding, 1024, leaveOpen: true))
            {
                await writer.WriteAsync(valueAsString);
            }
        }
        public void CanWriteResult_ReturnsTrue_ForStreams(Type declaredType, string contentType)
        {
            // Arrange
            var formatter = new StreamOutputFormatter();
            var contentTypeHeader = contentType == null ? null : new MediaTypeHeaderValue(contentType);
            var formatterContext = new OutputFormatterContext()
            {
                DeclaredType = declaredType,
                Object = new MemoryStream()
            };

            // Act
            var canWrite = formatter.CanWriteResult(formatterContext, contentTypeHeader);

            // Assert
            Assert.True(canWrite);
        }
        public void CanWriteResult_OnlyActsOnStreams_IgnoringContentType(Type declaredType, string contentType)
        {
            // Arrange
            var formatter = new StreamOutputFormatter();
            var contentTypeHeader = contentType == null ? null : new MediaTypeHeaderValue(contentType);
            var formatterContext = new OutputFormatterContext()
            {
                DeclaredType = declaredType,
                Object = new SimplePOCO()
            };

            // Act
            var canWrite = formatter.CanWriteResult(formatterContext, contentTypeHeader);

            // Assert
            Assert.False(canWrite);
        }
예제 #49
0
        public void CanWriteResult_ReturnsTrueForStringTypes(object value, bool useDeclaredTypeAsString, bool expectedCanWriteResult)
        {
            // Arrange
            var formatter = new TextPlainFormatter();
            var typeToUse = useDeclaredTypeAsString ? typeof(string) : typeof(object);
            var formatterContext = new OutputFormatterContext()
            {
                Object = value,
                DeclaredType = typeToUse
            };

            // Act
            var result = formatter.CanWriteResult(formatterContext, null);

            // Assert
            Assert.Equal(expectedCanWriteResult, result);
        }
예제 #50
0
        public void CanWriteResult_ReturnsTrue_ForStreams(Type declaredType, string contentType)
        {
            // Arrange
            var formatter         = new StreamOutputFormatter();
            var contentTypeHeader = contentType == null ? null : new MediaTypeHeaderValue(contentType);
            var formatterContext  = new OutputFormatterContext()
            {
                DeclaredType = declaredType,
                Object       = new MemoryStream()
            };

            // Act
            var canWrite = formatter.CanWriteResult(formatterContext, contentTypeHeader);

            // Assert
            Assert.True(canWrite);
        }
예제 #51
0
        public void CanWriteResult_OnlyActsOnStreams_IgnoringContentType(Type declaredType, string contentType)
        {
            // Arrange
            var formatter         = new StreamOutputFormatter();
            var contentTypeHeader = contentType == null ? null : new MediaTypeHeaderValue(contentType);
            var formatterContext  = new OutputFormatterContext()
            {
                DeclaredType = declaredType,
                Object       = new SimplePOCO()
            };

            // Act
            var canWrite = formatter.CanWriteResult(formatterContext, contentTypeHeader);

            // Assert
            Assert.False(canWrite);
        }
예제 #52
0
        public override Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var response = context.ActionContext.HttpContext.Response;
            var selectedEncoding = context.SelectedEncoding;
            using (var writer = new StreamWriter(response.Body, selectedEncoding, 1024, leaveOpen: true))
            {
                using (var jsonWriter = CreateJsonWriter(writer))
                {
                    var jsonSerializer = CreateJsonSerializer();
                    jsonSerializer.Serialize(jsonWriter, context.Object);

                    // We're explicitly calling flush here to simplify the debugging experience because the
                    // underlying TextWriter might be long-lived. If this method ends up being called repeatedly
                    // for a request, we should revisit.
                    jsonWriter.Flush();
                }
            }

            return Task.FromResult(true);
        }
예제 #53
0
        /// <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(OutputFormatterContext context)
        {
            var request = context.ActionContext.HttpContext.Request;
            var encoding = MatchAcceptCharacterEncoding(request.AcceptCharset);
            if (encoding == null)
            {
                // Match based on request acceptHeader.
                var requestContentType = MediaTypeHeaderValue.Parse(request.ContentType);
                if (requestContentType != null && !string.IsNullOrEmpty(requestContentType.Charset))
                {
                    var requestCharset = requestContentType.Charset;
                    encoding = SupportedEncodings.FirstOrDefault(
                                                            supportedEncoding =>
                                                                requestCharset.Equals(supportedEncoding.WebName));
                }
            }

            encoding = encoding ?? SupportedEncodings.FirstOrDefault();
            return encoding;
        }
예제 #54
0
파일: ObjectResult.cs 프로젝트: Nakro/Mvc
        public override async Task ExecuteResultAsync(ActionContext context)
        {
            var formatters = GetDefaultFormatters(context);
            var formatterContext = new OutputFormatterContext()
            {
                DeclaredType = DeclaredType,
                ActionContext = context,
                Object = Value, 
            };

            var selectedFormatter = SelectFormatter(formatterContext, formatters);
            if (selectedFormatter == null)
            {
                // No formatter supports this.
                context.HttpContext.Response.StatusCode = 406;
                return;
            }

            await selectedFormatter.WriteAsync(formatterContext);
        }
예제 #55
0
        public async Task WriteAsync_DoesNotWriteNullStrings()
        {
            // Arrange
            var formatter = new TextPlainFormatter();
            var formatterContext = new OutputFormatterContext()
            {
                Object = null,
                DeclaredType = typeof(string), 
            };

            var tempMemoryStream = new MemoryStream();
            var mockHttpContext = new Mock<HttpContext>();
            mockHttpContext.SetupGet(o => o.Response.Body)
                           .Returns(tempMemoryStream);
            // Act
            await formatter.WriteResponseBodyAsync(formatterContext);

            // Assert
            Assert.Equal(0, tempMemoryStream.Length);
        }
예제 #56
0
        public override async Task ExecuteResultAsync(ActionContext context)
        {
            var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<ObjectResult>>();
                            
            // See if the list of content types added to this object result is valid.
            ThrowIfUnsupportedContentType();
            var formatters = GetDefaultFormatters(context);

            var formatterContext = new OutputFormatterContext()
            {
                DeclaredType = DeclaredType,
                HttpContext = context.HttpContext,
                Object = Value,
                StatusCode = StatusCode
            };

            var selectedFormatter = SelectFormatter(formatterContext, formatters);
            if (selectedFormatter == null)
            {
                // No formatter supports this.
                logger.LogWarning("No output formatter was found to write the response.");

                context.HttpContext.Response.StatusCode = StatusCodes.Status406NotAcceptable;
                return;
            }

            logger.LogVerbose(
                "Selected output formatter '{OutputFormatter}' and content type " +
                "'{ContentType}' to write the response.", 
                selectedFormatter.GetType().FullName,
                formatterContext.SelectedContentType);

            if (StatusCode.HasValue)
            {
                context.HttpContext.Response.StatusCode = StatusCode.Value;
            }

            OnFormatting(context);
            await selectedFormatter.WriteAsync(formatterContext);
        }
예제 #57
0
        private IEnumerable<MediaTypeHeaderValue> GetSortedAcceptHeaderMediaTypes(
            OutputFormatterContext formatterContext)
        {
            var request = formatterContext.ActionContext.HttpContext.Request;
            var incomingAcceptHeaderMediaTypes = request.GetTypedHeaders().Accept ?? new MediaTypeHeaderValue[] { };

            // By default we want to ignore considering accept headers for content negotiation when
            // they have a media type like */* in them. Browsers typically have these media types.
            // In these cases we would want the first formatter in the list of output formatters to
            // write the response. This default behavior can be changed through options, so checking here.
            var options = formatterContext.ActionContext.HttpContext
                                                        .RequestServices
                                                        .GetRequiredService<IOptions<MvcOptions>>()
                                                        .Options;

            var respectAcceptHeader = true;
            if (options.RespectBrowserAcceptHeader == false
                && incomingAcceptHeaderMediaTypes.Any(mediaType => mediaType.MatchesAllTypes))
            {
                respectAcceptHeader = false;
            }

            var sortedAcceptHeaderMediaTypes = Enumerable.Empty<MediaTypeHeaderValue>();
            if (respectAcceptHeader)
            {
                sortedAcceptHeaderMediaTypes = SortMediaTypeHeaderValues(incomingAcceptHeaderMediaTypes)
                                                .Where(header => header.Quality != HeaderQuality.NoMatch);
            }

            return sortedAcceptHeaderMediaTypes;
        }
예제 #58
0
        public virtual IOutputFormatter SelectFormatter(
            OutputFormatterContext formatterContext,
            IEnumerable<IOutputFormatter> formatters)
        {
            // Check if any content-type was explicitly set (for example, via ProducesAttribute 
            // or Url path extension mapping). If yes, then ignore content-negotiation and use this content-type.
            if (ContentTypes.Count == 1)
            {
                return SelectFormatterUsingAnyAcceptableContentType(formatterContext,
                                                                    formatters,
                                                                    ContentTypes);
            }

            var sortedAcceptHeaderMediaTypes = GetSortedAcceptHeaderMediaTypes(formatterContext);

            IOutputFormatter selectedFormatter = null;
            if (ContentTypes == null || ContentTypes.Count == 0)
            {
                // Check if we have enough information to do content-negotiation, otherwise get the first formatter
                // which can write the type.
                MediaTypeHeaderValue requestContentType = null;
                MediaTypeHeaderValue.TryParse(
                    formatterContext.ActionContext.HttpContext.Request.ContentType,
                    out requestContentType);
                if (!sortedAcceptHeaderMediaTypes.Any() && requestContentType == null)
                {
                    return SelectFormatterBasedOnTypeMatch(formatterContext, formatters);
                }

                //
                // Content-Negotiation starts from this point on.
                //

                // 1. Select based on sorted accept headers.
                if (sortedAcceptHeaderMediaTypes.Any())
                {
                    selectedFormatter = SelectFormatterUsingSortedAcceptHeaders(
                                                                            formatterContext,
                                                                            formatters,
                                                                            sortedAcceptHeaderMediaTypes);
                }

                // 2. No formatter was found based on accept headers, fall back on request Content-Type header.
                if (selectedFormatter == null && requestContentType != null)
                {
                    selectedFormatter = SelectFormatterUsingAnyAcceptableContentType(
                                                                                formatterContext,
                                                                                formatters,
                                                                                new[] { requestContentType });
                }

                // 3. No formatter was found based on Accept and request Content-Type headers, so
                // fallback on type based match.
                if (selectedFormatter == null)
                {
                    // Set this flag to indicate that content-negotiation has failed to let formatters decide
                    // if they want to write the response or not.
                    formatterContext.FailedContentNegotiation = true;

                    return SelectFormatterBasedOnTypeMatch(formatterContext, formatters);
                }
            }
            else
            {
                if (sortedAcceptHeaderMediaTypes.Any())
                {
                    // Filter and remove accept headers which cannot support any of the user specified content types.
                    var filteredAndSortedAcceptHeaders = sortedAcceptHeaderMediaTypes
                                                                    .Where(acceptHeader => 
                                                                        ContentTypes.Any(contentType => 
                                                                            contentType.IsSubsetOf(acceptHeader)));

                    selectedFormatter = SelectFormatterUsingSortedAcceptHeaders(
                                                                        formatterContext,
                                                                        formatters,
                                                                        filteredAndSortedAcceptHeaders);
                }

                if (selectedFormatter == null)
                {
                    // Either there were no acceptHeaders that were present OR
                    // There were no accept headers which matched OR
                    // There were acceptHeaders which matched but there was no formatter
                    // which supported any of them.
                    // In any of these cases, if the user has specified content types,
                    // do a last effort to find a formatter which can write any of the user specified content type.
                    selectedFormatter = SelectFormatterUsingAnyAcceptableContentType(
                                                                        formatterContext,
                                                                        formatters,
                                                                        ContentTypes);
                }
            }

            return selectedFormatter;
        }
예제 #59
0
 public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
 {
     var response = context.ActionContext.HttpContext.Response;
     response.ContentType = ContentType + ";charset=utf-8";
     await response.WriteAsync(context.Object.ToString());
 }
예제 #60
0
 public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
 {
     var response = context.ActionContext.HttpContext.Response;            
     await response.WriteAsync(context.Object.ToString());
 }