Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
53 changes: 53 additions & 0 deletions src/Microsoft.AspNet.Mvc.Core/Formatters/TextPlainFormatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;

namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Writes a string value to the response.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always writes a string value to the response, regardless of requested contenttype

/// </summary>
public class TextPlainFormatter : OutputFormatter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PlanTextFormatter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

followed the pattern of MediaTypeMediaSubType.

{
public TextPlainFormatter()
{
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/plain"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should just be cached on the class, or even better just cached in a static class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SupportedEncodings.Add(Encoding.GetEncoding("utf-8"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be Encoding.Utf8 or Encodings.UTF8WithoutBom?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right, however this doesn't get used. Will update

}

public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
{
if (base.CanWriteResult(context, contentType))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return base.CanWriteResult(content, contentType) &&
           content.Object is string;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Orthogonal to Pranav's comment, with the current implementation this is going to participate in content negotiation, if accept header or content type (set by using ProducesContent attr) is set. Now as per my discussion with @yishaigalatzer we want to always return text/plain format if the object is a string. However this means that if some action (or class ) had a

[ProducesContent("application/json")]

then the produces content attribute gets ignored which in my opinion is not right.
@yishaigalatzer thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. We are not going to call it produces content
  2. I think the behavior is still correct. You can explicitly set the formatter or remove the textplain formatter to ignore it.
  3. I think it needs to support more types than just string. Stringbuilder comes to mind. Not sure if we want other types as well, textwriter?

-----Original Message-----
From: "Harsh Gupta" [email protected]
Sent: ‎7/‎27/‎2014 5:17 PM
To: "aspnet/Mvc" [email protected]
Cc: "Yishai Galatzer" [email protected]
Subject: Re: [Mvc] Adding TextPlainFormatter to always handle returningstrings as text\pla... (#868)

In src/Microsoft.AspNet.Mvc.Core/Formatters/TextPlainFormatter.cs:

+namespace Microsoft.AspNet.Mvc
+{

  • ///

  • /// Writes a string value to the response.

  • ///

  • public class TextPlainFormatter : OutputFormatter

  • {

  •    public TextPlainFormatter()
    
  •    {
    
  •        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/plain"));
    
  •        SupportedEncodings.Add(Encoding.GetEncoding("utf-8"));
    
  •    }
    
  •    public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
    
  •    {
    
  •        if (base.CanWriteResult(context, contentType))
    

    Orthogonal to Pranav's comment, with the current implementation this is going to participate in content negotiation, if accept header or content type (set by using ProducesContent attr) is set. Now as per my discussion with @yishaigalatzer we want to always return text/plain format if the object is a string. However this means that if some action (or class ) had a
    [ProducesContent("application/json")]
    then the produces content attribute gets ignored which in my opinion is not right.
    @yishaigalatzer thoughts?

    Reply to this email directly or view it on GitHub.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well,not honoring the attribute does not sound good, however if the 99% scenario is it will be text/plain for a string (which I think it is) then this is fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the intended design. What does the base do?

-----Original Message-----
From: "Harsh Gupta" [email protected]
Sent: ‎7/‎28/‎2014 3:35 PM
To: "aspnet/Mvc" [email protected]
Cc: "Yishai Galatzer" [email protected]
Subject: Re: [Mvc] Adding TextPlainFormatter to always handle returningstrings as text\pla... (#868)

In src/Microsoft.AspNet.Mvc.Core/Formatters/TextPlainFormatter.cs:

+namespace Microsoft.AspNet.Mvc
+{

  • ///

  • /// Writes a string value to the response.

  • ///

  • public class TextPlainFormatter : OutputFormatter

  • {

  •    public TextPlainFormatter()
    
  •    {
    
  •        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/plain"));
    
  •        SupportedEncodings.Add(Encoding.GetEncoding("utf-8"));
    
  •    }
    
  •    public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
    
  •    {
    
  •        if (base.CanWriteResult(context, contentType))
    

    well,not honoring the attribute does not sound good, however if the 99% scenario is it will be text/plain for a string (which I think it is) then this is fine.

    Reply to this email directly or view it on GitHub.

{
var valueAsString = context.Object as string;
if (valueAsString != null)
{
return true;
}
}

return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add support for StringBuilder and StringWriter and open a issue to followup @pranavkm when he is done with the RazorTextWriter to see if we think it's useful here as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next PR>

}

public override void WriteResponseContentHeaders(OutputFormatterContext context)
{
// Ignore the accept-charset field, as this will always write utf-8.
var response = context.ActionContext.HttpContext.Response;
response.ContentType = "text/plain;charset=utf-8";
}

public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
{
var response = context.ActionContext.HttpContext.Response;
var valueAsString = context.Object as string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do an explicit cast instead of an as

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make the content type declarative on a property

await response.WriteAsync(valueAsString);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you aren't doing any async work in this, you could return the result of WriteAsync

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<Compile Include="Extensions\ViewEngineDescriptorExtensions.cs" />
<Compile Include="Formatters\DefaultOutputFormattersProvider.cs" />
<Compile Include="Formatters\IOutputFormatter.cs" />
<Compile Include="Formatters\TextPlainFormatter.cs" />
<Compile Include="Formatters\StringWithQualityHeaderValueComparer.cs" />
<Compile Include="IExpiringFileInfoCache.cs" />
<Compile Include="Formatters\IOutputFormattersProvider.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public void Setup(MvcOptions options)
options.ModelBinders.Add(new ComplexModelDtoModelBinder());

// Set up default output formatters.
options.OutputFormatters.Add(new TextPlainFormatter());
options.OutputFormatters.Add(new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), true));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm..looks like my comment in other PR didn't make it...named parameter and also indent should be false

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my bad- actually I had to base it off another PR ( the actual code in the repo has the correct value https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs)


// Set up ValueProviders
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,29 +309,29 @@ public async Task ObjectResult_NoFormatterFound_Returns406()
httpResponse.VerifySet(r => r.StatusCode = 406);
}

// TODO: Disabling since this scenario is no longer dealt with in object result.
// Re-enable once we do.
//[Fact]
[Fact]
public async Task ObjectResult_Execute_CallsContentResult_SetsContent()
{
// Arrange
var expectedContentType = "text/plain";
var expectedContentType = "text/plain;charset=utf-8";
var input = "testInput";
var stream = new MemoryStream();

var httpResponse = new Mock<HttpResponse>();
var tempContentType = string.Empty;
httpResponse.SetupProperty<string>(o => o.ContentType);
httpResponse.SetupGet(r => r.Body).Returns(stream);

var actionContext = CreateMockActionContext(httpResponse.Object);
var actionContext = CreateMockActionContext(httpResponse.Object,
requestAcceptHeader: null,
requestContentType: null);

// Act
var result = new ObjectResult(input);
await result.ExecuteResultAsync(actionContext);

// Assert
httpResponse.VerifySet(r => r.ContentType = expectedContentType);

// The following verifies the correct Content was written to Body
Assert.Equal(input.Length, httpResponse.Object.Body.Length);
}
Expand Down Expand Up @@ -473,7 +473,10 @@ public IReadOnlyList<IOutputFormatter> OutputFormatters
get
{
return new List<IOutputFormatter>()
{ new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), indent: true) };
{
new TextPlainFormatter(),
new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), indent: true)
};
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions test/Microsoft.AspNet.Mvc.Test/MvcOptionSetupTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ public void Setup_SetsUpOutputFormatters()
setup.Setup(mvcOptions);

// Assert
Assert.Equal(1, mvcOptions.OutputFormatters.Count);
Assert.IsType<JsonOutputFormatter>(mvcOptions.OutputFormatters[0].OutputFormatter);
Assert.Equal(2, mvcOptions.OutputFormatters.Count);
Assert.IsType<TextPlainFormatter>(mvcOptions.OutputFormatters[0].OutputFormatter);
Assert.IsType<JsonOutputFormatter>(mvcOptions.OutputFormatters[1].OutputFormatter);
}
}
}