Parameter dont have value in webapi - c#

I am trying to call a service through swagger, by passing a parameter in XML format.
Method is hitting, but the passed parameter is blank
Means "xlff" is blank. Do you have clue what wrong i am doing
/// <summary>
/// Get or insert blog comments which is approved based on blogs
/// </summary>
/// <remarks> Get or insert blog comments which is approved based on blogs</remarks>
/// <param name="xlf">The comment.</param>
/// <response code="200">Get approved blog comments</response>
/// <response code="404">Not found</response>
/// <returns>IHttpActionResult</returns>
[Route("api/smartling/ProcessSmartlingTranslation")]
[VersionedRoute("", 1)]
[ResponseType(typeof(HttpResponseMessage))]
[HttpPost]
public IHttpActionResult ProcessSmartlingTranslation([FromBody]xliff xlff)
{
return Content(HttpStatusCode.BadRequest, "Any object");
}
/// <summary>
/// XliffModel created
/// </summary>
public class xliff
{
/// <summary>
/// file getter setter method
/// </summary>
public string file { get; set; }
/// <summary>
/// body getter setter method
/// </summary>
public string body { get; set; }
}

Your parameter content type is application/json, but you're sending xml. You should change the content type to application/xml.

Related

Swashbuckle.AspNetCore <example> not working for me

I am trying to set up examples using tag but, it is not working for me. I am using Swashbuckle.AspNetCore library.
Some code samples are below,
Added the following to my csproj. file
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Program.cs
builder.Services.AddSwaggerGen(options =>
{
options.OperationFilter<SwaggerDefaultValues>();
var filePath = Path.Combine(System.AppContext.BaseDirectory, "My.xml");
options.IncludeXmlComments(filePath);
});
Controller looks like,
[Authorize]
[ApiController]
[ApiVersion("1.0")]
[Route("[controller]")]
[Route("v{version:apiVersion}/[controller]")]
[Produces("application/json")]
public class MyController : ControllerBase
{
}
My method looks like,
/// <summary>
/// Method to Post an Incident
/// </summary>
/// <param name="initiateRequest" example="FORM_CODE"></param>
[ProducesResponseType(typeof(InitiateResponseDTO), StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ExceptionDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[HttpPost]
public async Task<ActionResult<InitiateResponseDTO>> PostAsync(MyRequest myRequest)
{
//Logic
return StatusCode(StatusCodes.Status201Created, InitiateResponseDTO);
}
MyDTO looks like,
/// <summary>
/// Initiate Response DTO
/// </summary>
public class InitiateResponseDTO
{
/// <summary>
/// IncidentId
/// </summary>
/// <example>985769890</example>
public int IncidentId { get; set; }
}
Exception Details Class
/// <summary>
/// Exception Details class
/// </summary>
public class ExceptionDetails
{
/// <summary>
/// HTTP status code for the exception.
/// </summary>
/// <example>400</example>
public int StatusCode { get; set; } = (int)HttpStatusCode.InternalServerError;
/// <summary>
/// (Friendly) message about the exception.
/// </summary>
/// <example>Invalid form code supplied: FORM_CODE</example>
public string Message { get; set; } = "An error occured";
/// <summary>
/// Error code for the returned error.
/// </summary>
/// <example>UNKNOWN_FORM</example>
public string ErrorCode { get; set; } = ErrorCodes.Generic;
/// <summary>
/// Exception Target denoting the method in which the error occurred.
/// </summary>
/// <example>MoveNext <- Method name from which the error occurred</example>
public string? Target { get; set; }
/// <summary>
/// InnerError message denoting the StackTrace.
/// </summary>
/// <example> Some Sample</example>
public string? InnerError { get; set; }
}
Still in Swagger UI, I don't see the example values,
Is there anything incorrect with the config? I am using Swashbuckle.AspNetCore 6.4.0
One simple option would be to decorate your properties with the [DefaultValue]
/// <summary>
/// Initiate Response DTO
/// </summary>
public class InitiateResponseDTO
{
/// <summary>
/// IncidentId
/// </summary>
/// <example>985769890</example>
[DefaultValue(985769890)]
public int IncidentId { get; set; }
}
Depending on how the serialization is done in your project, it should work.
There is also the possibility to look into the Swashbuckle.AspNetCore.Filters Nuget library to setup your examples as you like, but it requires more work: https://github.com/mattfrear/Swashbuckle.AspNetCore.Filters#automatic-annotation

How to display parameter in Web API help page for request and response body

I want to show request and response body as parameter not as raw data .
For that I have followed Generate Description Fields for Body Parameters answer but not get success , still showing
/// <summary>
/// Gets some very important data from the server.
/// </summary>
/// <param name="reqData">A Test Model</param>
[HttpPost]
public AccountService.GetAccountList_ResponseData GetAccountList([FromBody] AccountService.GetAccountList_ReqestData reqData)
{
}
//--my modal
public class GetAccountList_ReqestData
{
/// <summary>
/// StartDate
/// </summary>
/// <param name="StartDate">Describe parameter.</param>
public string StartDate { get; set; }
}
//---Also enabled
config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/WebApi.xml")));
You have to add XmlDocs to your class GetAccountList_RequestData
/// <summary>
/// My requestData model
/// </summary>
/// <param name="reqData">The description you want </param>
public class GetAccountList_ReqestData
{
/// <summary>
/// StartDate
/// </summary>
/// <param name="StartDate">Describe parameter.</param>
public string StartDate { get; set; }
}
You followed the steps correctly, however the person asking in the other thread was displaying a property. You on the other hand are asking for an object, which is your class. Therefor the xmldocs of the class will be used to generate the descriptions.

Swagger italicizing quotes

Following remarks in the XML comments section in my code show up in Swagger -
/// <remarks>
/// {
/// "your_val": "1a",
/// "member": "Test"
/// }
///</remarks>
I am noticing that the last value (in this case Test) always has italicized quotations (Red arrow). Does anyone know how to change it to be regular quotes? For example, like they are for 1a (Blue arrow).
Add a remarks element to the Create action method documentation. It supplements information specified in the summary element and provides a more robust Swagger UI. The remarks element content can consist of text, JSON, or XML.
So, in order to fix the remarks and generate the Swagger documentation in a proper way, you must add a text after open the remarks tag, add a break line, and then add an example of request.
Another important detail is the indentation, you must apply a proper code indentation.
Please, find below your current scenario, a fix for your problem, and 2 examples.
Before - Wrong (your scenario)
/// <remarks>
/// {
/// "your_val": "1a",
/// "member": "Test"
/// }
After - Correct
/// <remarks>
/// [Description]:
///
/// {
/// "your_val": "1a",
/// "member": "Test"
/// }
///</remarks>
Example 01:
/// <summary>
/// Creates a Item From Query (Default)
/// </summary>
/// <remarks>
/// Sample request:
///
/// POST /api/Items/CreateViaQuery
/// {
/// "code": "0001",
/// "description": "Item1"
/// }
///
/// </remarks>
/// <param cref="CreateItemViewModel" name="createItemViewModel">Create Item View Model</param>
/// <returns>A newly created Item</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost("CreateViaQuery")]
[ProducesResponseType((int)HttpStatusCode.Created)]
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
public ActionResult<CreateItemViewModel> CreateViaQuery(CreateItemViewModel createItemViewModel)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
return Created("", createItemViewModel);
}
Example 02:
/// <summary>
/// Creates a Item From Body
/// </summary>
/// <remarks>
/// Sample request:
///
/// POST /api/Items/CreateViaBody
/// {
/// "code": "0001",
/// "description": "Item1"
/// }
///
/// </remarks>
/// <param cref="CreateItemViewModel" name="createItemViewModel">Create Item View Model</param>
/// <returns>A newly created Item</returns>
/// <response code="201" cref="CreateItemViewModel">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost("CreateViaBody")]
[ProducesResponseType((int)HttpStatusCode.Created)]
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
public ActionResult<CreateItemViewModel> CreateViaBody([FromBody]CreateItemViewModel createItemViewModel)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
return Created("", createItemViewModel);
}
For more info, please take a look the following article:
Get started with Swashbuckle and ASP.NET Core
I hope this can help you.

How to describe input model as much as possible using Swagger

I have an example input model as follows:
public class CarInputModel {
public string Name { get; set; }
public string ModelName { get; set; }
}
This values will come from UI, what kind of annotations can I use with swagger to describe this API model as much as possible?
You can't use many annotations at all to describe the model. You mostly describe the API itself
[HttpGet] and [HttpPost] for the http attributes
[Produces(typeof(CarInputModel)] for the return type of an action and [ProducesResponseType(typeof(CarInputModel), (int)HttpStatusCode.OK)] for result types based on http code (i.e. return different model on error)
[Route] for the route itself
Additionally you can use Xml Docs to describe the classes and their parameters.
/// <summary>
/// Adds a new car model.
/// </summary>
/// <param name="model">The model to add</param>
/// <response code="201">Returns when the car was added successfully and returns the location to the new resource</response>
/// <response code="400">Invalid Request data.</response>
/// <response code="409">Car mode already exists.</response>
/// <returns>The newly added model on success and a list of errors on failure.</returns>
[HttpPost]
[ProducesResponseType(typeof(CarInputModel), (int)HttpStatusCode.Created)]
[ProducesResponseType(typeof(SerializableError), (int)HttpStatusCode.BadRequest)]
[ProducesResponseType(typeof(void), (int)HttpStatusCode.Conflict)]
public IActionResult AddCar(CarInputModel model)
{
}
/// <summary>
/// Represents a car
/// </summary>
public class CarInputModel {
/// <summary>
/// Name of the car
/// </summary>
public string Name { get; set; }
/// <summary>
/// Model of the car
/// </summary>
public string ModelName { get; set; }
}
In order to use XmlDocs you need to enable compilation of the xml docs in your project settings (and the of your models) and then add this to your Startup.cs
services.AddSwaggerGen(options =>
{
var appEnv = PlatformServices.Default.Application;
options.IncludeXmlComments(Path.Combine(appEnv.ApplicationBasePath, $"{appEnv.ApplicationName}.xml"));
});

Duplicate parameters output through Swashbuckle/Swagger

Code is further down in the post.
Question: I would like Swashbuckle to generate the following two "GET" requests:
1. mydomain.com/api/books?apikey=12345567891011121314151617181920
2. mydomain.com/api/books/1234?apikey=12345567891011121314151617181920
Swashbuckle does fine on #1 and it works great from the Swagger UI. But for #2, it ends up generating (and calling):
mydomain.com/api/books/{Id}?id=1234&apikey==12345567891011121314151617181920
Needless to say, that GET fails. Swashbuckle is picking up the literal "Id" from the route attribute as well as the BookDetail object. In fact, it shows both IDs in the UI, but I was able to solve that by de-duping by hooking up a custom IOperationFilter, but that obviously didn't help with correcting the actual GET request path.
I already looked at Duplicate parameter output in Swagger 2 but that answer does not work for me. I am looking for having Swashbuckle use the "Id" that's part of the BookDetail object so that Swagger UI shows the description (from the XML comment) while supporting route based ID rather than query string based: mydomain.com/api/books/1234.... What am I doing wrong? (I am on Swashbuckle 5.2.2).
Code:
/// <summary>
/// Books controller
/// </summary>
[RoutePrefix("api")]
public class BooksController : ApiController
{
/// <summary>
/// Returns books matching the search query
/// </summary>
/// <param name="searchRequest"></param>
/// <returns></returns>
[Route("books")]
public IHttpActionResult Get(BookSearch searchRequest)
{
//Do stuff with request
return Ok();
}
/// <summary>
/// Retruns a single book for the given ID
/// </summary>
/// <param name="detailRequest"></param>
/// <returns></returns>
[Route("books/{id:int}")]
public IHttpActionResult Get(BookDetail detailRequest)
{
//Do stuff with request
return Ok();
}
/// <summary>
/// Book search
/// </summary>
public class BookSearch
{
/// <summary>
/// API key
/// </summary>
[Required]
public string ApiKey { get; set; }
/// <summary>
/// Search terms
/// </summary>
public string Query { get; set; }
}
/// <summary>
/// Book detail
/// </summary>
public class BookDetail
{
/// <summary>
/// API key
/// </summary>
[Required]
public string ApiKey { get; set; }
/// <summary>
/// Book of the ID you want to retrieve
/// </summary>
[Required]
public int Id { get; set; }
/// <summary>
/// Boolean indicating whether to include photos or not
/// </summary>
public bool IncludePhotos { get; set; }
}
}

Categories