How to implement Search function and Add Comments in Swagger - swagger

guys:
I use swagger to make api document. I use ASP.NET WebAPI2 to develop WebAPI.
And I met three questions:
First: How could I Add Comments for the WebAPI Controller? I try to add Comment on Controller
namespace IMCAPI.Controllers
{
/// <summary>
/// Value API
/// </summary>
[Authorize]
public class ValuesController : ApiController
{
// GET api/values
/// <summary>
/// Get all Values
/// </summary>
/// <returns></returns>
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
, but not work.
Second:How could I search specific WebAPI in Swagger by brower Url? like this Browser Url Search
For example, if I want to search Value API, I input Value in the red section,I want the search result would just show Value API, I don't want other API appears(like Account). Or how to setting SwaggerConfig.cs that can have the search function?
Third:I want to know whether swagger could just read one xml file? I search the Internet, they demo like this
private static string GetXmlCommentsPath()
{
return String.Format("{0}/App_Data/IMCAPI.XML", AppDomain.CurrentDomain.BaseDirectory);
}
If I have multiple XML file, how could I integrate in the swagger?
that it. Hope somebody can help me. Thank you!

Your first question: The comments are appearing, you've put them on the Get method in your code, they're appearing on the Get method in your screenshot. If what you want is a description of the whole service, the Swagger documentation says to use the Description method.
Your second: You can't it shows all the methods on that API.
Third: The Swagger documentation says you call IncludeXmlComments multiple times with the path to each XML.

Related

Swagger not handling .net core optional parameter correctly

I've got a Web API controller method that has an optional parameter like so:
[HttpGet]
[Route("getOrder/{price?}")]
public async Task<IEnumerable<Product>> Get(int? price = null)
{
}
However, when running the API, the Swagger UI shows the parameter as required and I can't call the method without the parameter. Why is this and how can I resolve it so that it's handle as an optional parameter?
An alternative to #CodingMytra's suggestion if you don't want to modify any SwaggerGen configurations could be to break the GET Web API controller into two distinct methods: one where the price is required in the route and another where it is an optional query parameter
As an example:
// endpoint #1 with required route param
[HttpGet]
[Route("Products/getOrder/{price}")]
public async Task<IEnumerable<Product>> Get1(int price)
{
//...
}
// endpoint #2 with optional params passed in via query string
[HttpGet]
[Route("Products/getOrder")]
public async Task<IEnumerable<Product>> Get2([FromQuery]int price)
{
//...
}
Which will produce the following Swagger documentation:
Products/getOrder/{price} and Products/getOrder.
The benefit of using query params being that you can reduce or expand search criteria in the future without changing the endpoint route.

Annotations on model properties in SwaggerUI

I have built a ASP.Net Core 3.1 Web API, and I am interested in auto-generating documentation for my clients. I've followed the very simple instructions found here: Microsoft docs to install either NSwag or Swashbuckle in my project and in both cases I can see documentation for my APIs, but there are no descriptions on the model properties.
Java seems to have an #ApiModelProperty annotation for this, but I don't see a similar attribute in .Net. Is it possible to add descriptions for Model properties in either of these swagger implementations, that would show up in Schema section in the Swagger UI?
Standard xml doc summary works for me.
public class TokenRefreshRequest
{
/// <summary>
/// The JWT access token
/// </summary>
public string AccessToken { get; set; }
/// <summary>
/// The refresh token that was sent via the new token endpoint or the last refresh.
/// </summary>
public string RefreshToken { get; set; }
}
Shows on the swagger page as;
You can add limited markdown as well but I can't seem to find the link.

what does a specific method do in this open source solution

Recently I'm trying to understand how NopCommerce plugins work.
I'll try to make my question as clear as possible and making sense for you without having the solution opened on your computer.
In nopCommerce plugins everything start with having a class which must have the definition for IWidgetPlugin interface and being derived from BasePlugin.
In one of the predefined plugins there is a class called NivoSliderPlugin and this class overrides some of it's base class methods and has the definition for IWidgetPlugin's methods.
here is the code:
public class NivoSliderPlugin : BasePlugin, IWidgetPlugin
{
// Here there are some fields that are referencing to different interfaces and then
they're injected to the class throw it's constructor
// This method gets a configuration page URL
public override string GetConfigurationPageUrl()
{
return _webHelper.GetStoreLocation() + "Admin/WidgetsNivoSlider/Configure";
}
}
In the above code I only mentioned the part of the code that I have a question about.
_webHelper is a reference to an interface and accept the incoming parameter of type bool.
Regardless the second part of the return, I mean the URL path which is "Admin/WidgetsNivoSlider/Configure", I'm wondering how _webHelper.GetStoreLocation() works ?
As you know _webHelper.GetStoreLocation() has no definition !
I hope what I just asked makes sense.
If it's not clear please let me know to make it clearer.
I'll appreciate it.
Let's start with IWidgetPlugin. This interface is not required to implement for all plugins in NopCommerce. This is required when you are developing a Widget type plugin. Here Nivo Slider is a widget type plugin, that's why it implemented IWidgetPlugin interface. Here is the implementation for Nivo slider.
/// <summary>
/// Gets a value indicating whether to hide this plugin on the widget list page in the admin area
/// </summary>
public bool HideInWidgetList => false;
/// <summary>
/// Gets a name of a view component for displaying widget
/// </summary>
/// <param name="widgetZone">Name of the widget zone</param>
/// <returns>View component name</returns>
public string GetWidgetViewComponentName(string widgetZone)
{
return "WidgetsNivoSlider";
}
/// <summary>
/// Gets widget zones where this widget should be rendered
/// </summary>
/// <returns>
/// A task that represents the asynchronous operation
/// The task result contains the widget zones
/// </returns>
public Task<IList<string>> GetWidgetZonesAsync()
{
return Task.FromResult<IList<string>>(new List<string> { PublicWidgetZones.HomepageTop });
}
If you want to develop a payment plugin, then you have to implement IPaymentMethod (i.e. PayPal, Stripe, Cash on Delivery) and IShippingRateComputationMethod for shipping methods (i.e. UPS, USPS). Also there are many other types of plugins available in nopCommerce. See the list below.
BasePlugin is an abstract class, which is required to be inherited for all plugin class. It has a virtual method named GetConfigurationPageUrl() which returns null by default. But this virtual method can be overridden from each plugin class and can return admin side configuration url for that plugin. Here is the overridden method for Nivo slider plugin.
/// <summary>
/// Gets a configuration page URL
/// </summary>
public override string GetConfigurationPageUrl()
{
return _webHelper.GetStoreLocation() + "Admin/WidgetsNivoSlider/Configure";
}
Here _webHelper.GetStoreLocation() is a method which returns base url of the site. This method is implemented in Nop.Core.WebHelper class. The optional boolean parameter (useSsl) for this method is used whether to consider https:// or not for the site base url. If this method is overridden from a specific plugin, then a Configure button will be displayed in local plugin list page.

ASP.NET MVC Read Raw JSON Post Data

This is driving me crazy. I'm using ASP.NET MVC. I have a controller with an HttpPost action that acts as a callback URL that is called by another server (not under my control). I want to dynamically read JSON posted to it without using WebAPI or Model Binding. The URL also has a query string parameter passed to it.
The callback URL looks something like this:
http://domain.com/callback?secret=1234
I've tried reading the posted input using:
[HttpPost]
public ActionResult Callback( String secret )
{
String jsonData = new StreamReader(this.Request.InputStream).ReadToEnd();
// ...
}
However "jsonData" is always null or empty.
I just want to get the posted input and stick it into JsonFx so I can dynamically access the contents. Any ideas on how to do this the easiest possible way?
UPDATE
I've discovered the following ...
While the above DOES NOT work (jsonData will be null or empty), the following DOES if I configure what little options I have on the calling server so as to omit the "secret" query string parameter, which is about all I can do on that end since it is not my server. In this case, jsonData will have the correct posted JSON string:
[HttpPost]
public ActionResult Callback( /* String secret */ )
{
String jsonData = new StreamReader(this.Request.InputStream).ReadToEnd();
// ...
}
This is very frustrating to work around and I don't know an easy way to accept both a query string and posted JSON data on a standard MVC controller.
I have a "callback controller" with Action methods that accept various data (via GET, via form POST, via JSON POST, via JSON POST w/ a Query String, etc.) from different third-party servers. These are merchant-type callbacks where I have no control over the formats or methods used to convey information. I just need to accept the callbacks and process the information that should be there.
All of it works fine in my Controller, except the case of "JSON POST w/ a Query String".
This appears (at least to me) to be a shortcoming in standard ASP.NET MVC controllers. ???
Can anyone suggest a solution to this that can be used in a standard ASP.NET MVC controller?
Your initial approach should work if you take into consideration the fact, that ASP.NET MVC model binding has already read the stream, so you should rewind it:
[HttpPost]
public ActionResult Callback(string secret)
{
Request.InputStream.Seek(0, SeekOrigin.Begin);
string jsonData = new StreamReader(Request.InputStream).ReadToEnd();
// ...
}
Reset the position to Zero before reading the stream.
Request.InputStream.Position = 0
For ASP.NET Core 2,this works for me.
[HttpPost]
public ActionResult RawTest() {
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
string content = reader.ReadToEndAsync().Result;
//...
}
//...
}

Is this a bug in the MvcContrib TestHelper OutBoundUrl class?

I am trying to test the outbound URL of an action method in an MVC area using the MvcContrib TestHelper's static OutBoundUrl class. Here is what I have:
OutBoundUrl.Of<ErrorsController>(action => action.NotFound())
.ShouldMapToUrl("/errors/404");
I stepped into the source and found that the UrlHelper was returning null for the outbound URL. Basically it creates a new UrlHelper and delegates the task to UrlHelper.Action(action, controller, routeValues).
When invoked, routeValues does not contain anything (the action method takes no args). Is this a bug? Or do I need to do something extra to make this work with areas? The following line comes just before the above line in the unit test, so my routes are registered (the UrlHelper.RouteCollection contains 100+ routes).
"~/errors/404".WithMethod(HttpVerbs.Get)
.ShouldMapTo<ErrorsController>(action => action.NotFound());
The route is not named, and I don't want to name it, so please don't suggest I use the OfRouteNamed method.
Update
I made an extension method that could work, except for one thing. The OutBoundController Of<TController> method has this code:
var methodCall = ((MethodCallExpression)action.Body);
var methodName = methodCall.Method.Name;
There is similar, but critically different code in the RouteTestingExtensions ShouldMapTo<TController> method:
var methodCall = (MethodCallExpression) action.Body;
// this line is not important
string expectedAction = methodCall.Method.ActionName();
The ActionName() extension method is kind of awesome if you use ActionNameAttributes:
/// <summary>
/// Will return the name of the action specified in the ActionNameAttribute
/// for a method if it has an ActionNameAttribute.
/// Will return the name of the method otherwise.
/// </summary>
/// <param name="method"></param>
/// <returns></returns>
public static string ActionName(this MethodInfo method)
{
if (method.IsDecoratedWith<ActionNameAttribute>())
return method.GetAttribute<ActionNameAttribute>().Name;
return method.Name;
}
Back to the question... is this by design, and if so, why? The fact that OutBoundUrl does not use the .ActionName() extension is the one thing keeping me from writing an extension method to generate outbound url's for area actions decorated with [ActionName].

Resources