Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Response content types in swagger, .net core api

I had some problems to render my api response as xml in swagger, finally I got it to render in the correct format, application/xml with my first action below, but it still says I can only render it as application/json.

I tried to remove application/json from Produces attribute, but still shows only application/json.

Any ideas why its behaving in this way?

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddMvcOptions(o => o.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter()));
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        c.RoutePrefix = "";
    });
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
        c.AddSecurityDefinition("Bearer", new ApiKeyScheme { In = "header", Description = "Please enter JWT with Bearer into field", Name = "Authorization", Type = "apiKey" });
        c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> {
            { "Bearer", Enumerable.Empty<string>() },
        });
    });
}

And action:

[Produces("application/json", "application/xml")]
public ContentResult GetByAddress(string address)
{
    var addressId = GetAddressIdByAddress(address);
    string result = _soapApi.GetResultById(addressId);
    return Content(result, "application/xml", Encoding.UTF8);
}

Same result with:

[Produces("application/json", "application/xml")]
public IActionResult GetByAddress(string address)
{
    var addressId = GetAddressIdByAddress(address);
    string result = _soapApi.GetResultById(addressId);
    return Content(result, "application/xml", Encoding.UTF8);
}

Results in:

Results in this When clicking excecute I get the result in the correct XML-format though.

While this:

[Produces("application/json", "application/xml")]
public string GetByAddress(string address)
{
    var addressId = GetAddressIdByAddress(address);
    string result = _soapApi.GetResultById(addressId);
    return result;
}

Or this:

[Produces("application/json", "application/xml")]
public List<Address> GetByAddreses()
{
    string result = _soapApi.GetResults();
    return result;
}

Results in:

enter image description here

I am not able to return a list of parsed objects due to different data-structure returned for different parameters. So at this point I only receive raw soap xml-data and have to parse/deserialize it. But to actually be able to see the raw response I also need to show it as Content from string with content-type application/xml. And it gives me a nice output like (even though it still says only application/json is possible):

enter image description here

To summarize it:

I did not get it work with response content-type showing the correct content-type (in "Response Content Type" -filter) when a string was parsed to its actual format like below. Even though this results in the correct output for application/xml that was the most important (see screenshot above);

[Produces("application/json", "application/xml")]
public ContentResult GetByAddress(string address)
{
    return Content("<xml>...</xml>", "application/xml", Encoding.UTF8);
} 
like image 524
Sgedda Avatar asked Dec 27 '18 12:12

Sgedda


2 Answers

It's because the return type overrides the annotations. To get it working as you wish, you need to return IActionResult and use annotations to provide what response type model it should be for particular code.
So instead returning result, return Ok(result)

I created sample code and it works for me using swagger 4.0.1

[HttpGet("Get2")]
[Produces("application/json", "application/xml", Type = typeof(List<string>))]
public IActionResult Get2()
{
   var list = new List<string>() { "value1", "value2" };
   return Ok(list);
}

swagger output

like image 69
Miq Avatar answered Sep 19 '22 07:09

Miq


[Produces("application/json", "application/xml")]
public Task<IActionResult> GetByAddreses()
{
    var result = _soapApi.GetResults();
var response = ResponceMethod<List<Address>>.SuccessResponse(StatusCodes.Status200OK, "Success", result);
    return Ok(response);
}
like image 26
Bhargil Joshi Avatar answered Sep 17 '22 07:09

Bhargil Joshi