Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

ASP.NET MVC returns Content-Type text/plain even if application/xml was requested in case of return type is string #3692

Closed
YEVHENO opened this issue Dec 4, 2015 · 12 comments
Assignees
Milestone

Comments

@YEVHENO
Copy link

YEVHENO commented Dec 4, 2015

This is my controller:

[Route("")]
public class ValuesController : Controller
{
    //This always returns text/plain
    [HttpPost("/text")]
    [Produces("application/xml", "application/json")]
    public string GetText() => "Some text";

    [HttpPost("/textarray")]
    [Produces("application/xml", "application/json")]
    public IEnumerable<string> GetTextarray() => new[] { "Some text", "Some text2" };
}

GetText() always returns text/plain even if I specify "Accept: application/xml" in request header. This happens only in case of return type "string". I expect get xml instead of plain text. See sample requests below:

Request 1:
GET /text HTTP/1.1
Host: localhost:5004
Accept: application/xml

Response 1:
HTTP/1.1 200 OK
Date: Fri, 04 Dec 2015 20:13:00 GMT
Content-Type: text/plain; charset=utf-8
Server: Kestrel

Some text

Request 2:
GET /textarray HTTP/1.1
Host: localhost:5004
Accept: application/xml

Response 2:
HTTP/1.1 200 OK
Date: Fri, 04 Dec 2015 20:13:04 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel

<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><string>Some text</string><string>Some text2</string></ArrayOfString>
@dougbu
Copy link
Member

dougbu commented Dec 5, 2015

Have you added the Microsoft.AspNet.Mvc.Formatters.Xml package to your dependencies in project.json? Without that dependency and configuration in the Startup class (or a custom output formatter), MVC does not support application/xml.

@YEVHENO
Copy link
Author

YEVHENO commented Dec 5, 2015

Yes, I have added Microsoft.AspNet.Mvc.Formatters.Xml like this:

var mvc = services.AddMvc(); mvc.AddXmlSerializerFormatters();

In my controller GetTextarray() return xml if requested. I have an issue with GetText which has response type string. Only in this case MVC always returns plain text. Please see sample request/response from my first comment.

@rynowak
Copy link
Member

rynowak commented Dec 7, 2015

I'd try adding the following to your startup code:

mvc.AddMvcOptions(options =>
{
    options.OutputFormatters.RemoveType<StringOutputFormatter>();
});

We have a formatter registered by default that treats strings as text/plain content.

You could also bypass formatters if your content is already in the format you want.

return Content(text, "application/xml");

@Eilon Eilon changed the title ASP.NET MCV returns Content-Type text/plain even if application/xml was requested in case of return type is string ASP.NET MVC returns Content-Type text/plain even if application/xml was requested in case of return type is string Dec 7, 2015
@danroth27 danroth27 reopened this Dec 7, 2015
@danroth27 danroth27 removed the question label Dec 7, 2015
@YEVHENO
Copy link
Author

YEVHENO commented Dec 7, 2015

Removing of StringOutputFormatter helps. But then no need to return xml content like this: return Content(text, "application/xml"). Attribute [Produces("application/xml")] does it.

@YEVHENO
Copy link
Author

YEVHENO commented Dec 7, 2015

My expectation was the following: Since I have marked method as [Produces("application/xml")], XmlSerializerOutputFormatter for this method should have higher priority than StringOutputFormatter. But that is not true if return type is string.

@danroth27 danroth27 added this to the 6.0.0-rc2 milestone Dec 9, 2015
@danroth27
Copy link
Member

We should figure out what we want to do with the StringFormatter.

@YEVHENO
Copy link
Author

YEVHENO commented Dec 9, 2015

I would definitely suggest do not remove StringFormatter from OutputFormatters. Although, it partially solve my issue.

@rynowak
Copy link
Member

rynowak commented Dec 14, 2015

discussed this with @lodejard and @kichalla today

Thoughts that we had on the design tenets here:

1. You should be able to return a string, and have it be whatever content type you want. This is for cases where you have pre-built XML or JSON or whatever.
[Produces("application/xml")]
public object GetProducts()
{
    string preformatted;
    if (_cache.TryGetProductsXml(out preformatted))
    {
        return preformatted; // Should result in application/xml through string formatter
    }

    return db.Products.ToList(); // Should result in application/xml through xml formatter
}
2. You should be able to use formatters with setting response.ContentType
public object GetProducts()
{
    Response.ContentType = "application/xml";
    return db.Products.ToList(); // Should result in application/xml through xml formatter 
}
3. We feel kinda dubious about scenarios where you're using primitive/simple types with formatters....
public object GetProductId(string productName)
{
    Response.ContentType = "application/xml";
    return db.Products
                   .Where(p => p.Name == productName)
                   .Select(p => p.Id)
                   .FirstOrDefault(); // what does this do?
}

@YEVHENO
Copy link
Author

YEVHENO commented Dec 14, 2015

My scenario for using primitive/simple types with formatters is the following: I have to interact with the system which expects text value as xml serialized string: <string>Text Value</string>.

@rynowak
Copy link
Member

rynowak commented Dec 14, 2015

My scenario for using primitive/simple types with formatters is the following: I have to interact with the system which expects text value as xml serialized string: Text Value.

Thanks, this is something we need to make sure stays working

@rynowak rynowak assigned ryanbrandenburg and unassigned rynowak Jan 12, 2016
@rynowak
Copy link
Member

rynowak commented Jan 12, 2016

Load balancing to a different Ryan

@ryanbrandenburg
Copy link
Contributor

So @YEVHENO the end decision here ended up being that it was a bug that the content type was getting left as text/plain, but it is intended behavior that the string formatter takes the string before your xml formatter can get it. To get your desired behavior remove or re-arrange the StringOutputFormatter.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants