Swagger Response Examples .Net 5 are not displayed - swagger

After updating my .net core 2.1 project to .net-5 and swagger swashbuckle from 2 to 5.6.3 the swagger response examples are not getting displayed anymore. Is there a new best practice way on how to solve this problem?
On 2.1 i have added some definitions on top of my controller.
[SwaggerResponse(409, Type = typeof(IEnumerable<ErrorObjects>))]
[SwaggerResponseExample(409, typeof(MethodResponseErrors))]
And in addition to this i implemented the MethodResponseErrors like this:
public class MethodResponseErrors : IExamplesProvider<List<ErrorObjects>>
{
List<ErrorObjects> IExamplesProvider<List<ErrorObjects>>.GetExamples()
{
return new List<ErrorObjects>
{
new Error1(),
new Error2(),
new Error3()
};
}
}
After this my response examples got displayed.

Related

How do i solve '"Reference to type 'BaseControlContext" claim.....' for AspNet.Security.OpenIdConnect.Server

I am facing weird issue.
I am reading and creating OpenID Connect server with ASOS this article ASOS - AspNet.Security.OpenIdConnect.Server.
I simply created new sample solution and added new subclass AuthorizationProvider class of OpenIdConnectServerProvider and override the virtual method i.e. ExtractAuthorizationRequest
AuthorizationProvider.cs
public class AuthorizationProvider : OpenIdConnectServerProvider
{
public override Task ExtractAuthorizationRequest(ExtractAuthorizationRequestContext context)
{
// If a request_id parameter can be found in the authorization request,
// restore the complete authorization request stored in the user session.
if (!string.IsNullOrEmpty(context.Request.RequestId))
{
var payload = context.HttpContext.Session.Get(context.Request.RequestId);
if (payload == null)
{
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "Invalid request: timeout expired.");
return Task.FromResult(0);
}
// Restore the authorization request parameters from the serialized payload.
using (var reader = new BsonReader(new MemoryStream(payload)))
{
foreach (var parameter in JObject.Load(reader))
{
// Avoid overriding the current request parameters.
if (context.Request.HasParameter(parameter.Key))
{
continue;
}
context.Request.SetParameter(parameter.Key, parameter.Value);
}
}
}
return Task.FromResult(0);
}
}
Issue:
As soon as i add Microsoft.AspNetCore.Identity (2.0.0) NuGet package to my project, context.Reject start giving the following error
"Reference to type 'BaseControlContext" claim it is defined in
Microsoft.AspNetCore.Authentication, but it could not be found.
But as soon as I remove Microsoft.AspNetCore.Identity NuGet dependency, the error goes away and all looks fine.
Note:
I am using VS 2017.
I am using dotnetcore 2.0 SDK.
I created solution using .Net Core 2.0.
Massive changes have been introduced in ASP.NET Core 2.0's authentication stack. The changes are so important that all the authentication middleware written for ASP.NET Core 1.x are not compatible (which includes all the aspnet-contrib projects).
You can read https://github.com/aspnet/Announcements/issues/262 for more information.
The good news is that we have an ASP.NET Core 2.0 RTM-compatible version of ASOS. You can find the 2.0.0-preview1-* bits on the aspnet-contrib MyGet feed (https://www.myget.org/F/aspnet-contrib/api/v3/index.json).

Swagger documentation: Swashbuckle (hide methods/properties)

I am using Swagger Swashbuckle to generate documentation. There are some methods in my controller and some properties in my models that I don't want to document.
Is there any arrtibute or the property to leave or ignore specific methods from documentation?
For the method, you have couple of option:
Use Obsolete attribute. Then, you have to set the action - c.IgnoreObsoleteActions(); within the swagger configuration
Create a custom attribute and a swagger document filter. The document filter should iterate through each method and remove the method documentation if the method is having the custom attribute
For the properties, you can use JsonIgnoreAttribute
In addition to c.IgnoreObsoleteActions(), there is also c.IgnoreObsoleteProperties(), which hides the property from the documentation.
JsonIgnoreAttribute will stop the property deserializing when being received as part of a POST request body, which may not be what you want if you only wish to change the documentation and not the functionality.
In more recent version of Swashbuckle (Core2/3) XmlIgnore/JsonIgnore don't seem to work for properties.
Alternatively you can change the property access modifier to internal. This should prevent serialization and generated documentation.
I'm not sure about hiding whole controllers, you will probably need to add filters in your Swagger setup. I do have an example of hiding certain endpoints (for convenience I have prefixed routes for running locally):
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSwaggerGen(config => {
config.SwaggerDoc("v1",
new OpenApiInfo {
Version = "v1",
Title = "Foo API",
Description = "Does foo things.",
Contact = new OpenApiContact {
Name = "nope",
Email = "mail#example.org",
},
});
// Include XML comments in Swagger docs
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
config.IncludeXmlComments(xmlPath);
// Filter out prefixed routes
config.DocInclusionPredicate(
(name, desc) => !desc.RelativePath.ToLower().StartsWith("MyDevPrefix"));
});
}
Just a note since I was also trying to figure out the JsonIgnore for properties not working...
The issue seems to be that newer versions of Swashbuckle for .Net Core do not support NewtonSoft out of the box.
Install from NuGet
Package Manager : Install-Package Swashbuckle.AspNetCore.Newtonsoft -Version 5.6.2
CLI : dotnet add package --version 5.6.2 Swashbuckle.AspNetCore.Newtonsoft
Add code to startup.cs
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});
services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs to be placed after AddSwaggerGen()
This worked for me, hope this helps someone else.
Here's a bit newer answer:
As other's mentioned - to ignore properties (both docs and real response) use attribute: [JsonIgnore]
To hide controller/actions from docs (the controller/action still exists, it is just hidden from docs) use attribute: [ApiExplorerSettings(IgnoreApi = true)]

How to perform a request to a REST API in ASP.net 5.0 (MVC6)

I am writing an ASP.Net 5, MVC 6 application (also referred to as 'ASP.net vNext') with Visual Studio 2015 RC.
How do I perform a simple GET request to a REST API? In .net 4.5 I would have used HttpClient but that no longer seems to be available.
I have tried adding both the 'System.Net.Http' and 'Microsoft.Net.Http' packages as advised by Visual Studio, however I still get "The type or namespace name 'HttpClient' could not be found" which leads me to believe that HttpClient is not the right way to do this in ASP.net 5?
Can anyone advise on the correct way to make HTTP GET requests in ASP.net 5?
Update: My question is not a duplicate of 'HttpClient in ASP.NET 5.0 not found?' bercause the answer given is out of date and not applicable to the latest version of ASP.net 5.0
Here is a solution for you, I just tried it out on the ASP.Net 5 Web site project template. Add the following method to HomeController
static async Task<string> DownloadPageAsync()
{
string page = "http://en.wikipedia.org/";
using (HttpClient client = new HttpClient())
using (HttpResponseMessage response = await client.GetAsync(page))
using (HttpContent content = response.Content)
{
string result = await content.ReadAsStringAsync();
return result.Substring(0, 50);
}
}
Then in the HomeControllers Index method
string test = DownloadPageAsync().Result;
And in project.json I added the following reference at dependencies
"Microsoft.Net.Http": "2.2.22"
I found an answer which was in part from a post called '
HttpClient in ASP.NET 5.0 not found?', but there were some missing gaps because the technology has moved on a bit now. I have blogged the full solution here: http://blogs.msdn.com/b/martinkearn/archive/2015/06/17/using-httpclient-with-asp-net-5-0.aspx

How can I return IQueyrable DTO from Webapi Get so I can use Odata filters

I'm trying to use a Odata filters with ODP.net with Entity framework inside of web api project ASP.NET MVC 4.0 RC. I want to return an IQueryable of OwnDTO . I get an internal 500 error without any details. I know there is an error generation bug with webapi RC, but I dont think that bug is my issue.
Get http://localhost:51744/api/Owner called using Fiddler
[Queryable]
public IQueryable<OwnDTO> Get()
{
using (Entities context = new Entities())
{
var query = from item in context.Owners
select
new OwnDTO
{
Name = item.Name
};
return query.AsQueryable();
}
}
//very simple for example
public class OwnDTO
{
public string Name;
}
I do not want to have use my Oracle EF generated classes (DAO) to return from my Get, but I know I can if I replace EntityObject with a more friendly interface. If I return IEnumerable it works, but I want Odata filters.
Update incase someone wants a working example.. Automapper or simliar should be used in the linq and the context should injected.
[Queryable]
public IQueryable<OwnDTO> Get()
{
{
var query = from item in Hack._EFContext.Owners
select
new OwnDTO
{
Name = item.Name
};
return query.AsQueryable();
}
}
That works fine, but it looks like Odata is removed post RC. So I need to search down another path.
It does work in RC but perhaps not in RTM when it ships - not quite clear yet.
Your problem is that you are disposing your context since you are using a using block. So context get disposed before the data is retrieved.
So instead of using register your object for disposal at the end of request. Tugberk has a post here.

Using the Json.NET serializer in an MVC4 project

I'm starting to learn Json.NET, but I'm having trouble using its serializer. I have a new MVC4 project with a Web.API service:
public class PTE_TestsController : ApiController {
PTE_TestsRepository _repository = new PTE_TestsRepository();
// GET /api/PTE_Tests/5
public HttpResponseMessage<string> Get(int id) {
try {
PTE_Test test = _repository.GetTest(id);
return new HttpResponseMessage<string>(JsonConvert.SerializeObject(test));
} catch {
return new HttpResponseMessage<string>(HttpStatusCode.NotFound);
}
}
}
JsonConvert.SerializeObject() works as expected and returns a string. My Web.API controller returns that as part of an HttpResponseMessage. The end result, when viewed in Fiddler, is not JSON data, but JSON data being serialized again (I think):
"{\"ID\":1,\"Name\":\"Talar Tilt\",\"TagID\":1,\"PracticeID\":1,
\"SpecificAreaID\":1,\"TypeID\":1,\"VideoID\":1,\"PicID\":1}"
Does someone know how to turn off the default serializer so I can use Json.NET directly? By the way, I'm not using the default serializer because I can't figure out how to make it work with complex objects (PTE_Test will eventually contain members of type List).
Alternately, it will also solve my problem if someone can explain how to use the default serializer with complex objects. MSDN's explanation didn't help me.
Rick Strahl has a blog on that here with a code that works.
As others have pointed out, you need to create a formatter and replace the DataContractSerializer with the JSON.NET serializer. Although, if you're not in a rush for JSON.NET specifically, rumor has it that next beta/rc is going to have support for JSON.NET built in.
Conceptually, however, you're missing part of the magic of WebAPI. With WebAPI you return your object in it's native state (or IQueryable if you want OData support). After your function call finishes the Formatter's take over and convert it into the proper shape based on the client request.
So in your original code, you converted PTE_Test into a JSON string and returned it, at which point the JSON Formatter kicked in and serialized the string. I modified your code as follows:
public class PTE_TestsController : ApiController {
PTE_TestsRepository _repository = new PTE_TestsRepository();
public HttpResponseMessage<PTE_Test> Get(int id) {
try {
PTE_Test test = _repository.GetTest(id);
return new HttpResponseMessage(test);
} catch {
return new HttpResponseMessage<string>(HttpStatusCode.NotFound);
}
}
}
Notice how your function returns PTE_Test instead of string. Assuming the request came in with a request header of Accept = application/json then the JSON formatter will be invoked. If the request had a header of : Accept = text/xml the XML formatter is invoked.
There's a decent article on the topic here. If you're a visual learner, Scott Gu shows some examples using fiddler in this video, starting around 37 minutes. Pedro Reys digs a little deeper into content negotiation here.
The way to do this is to use formatters.
Check out: https://github.com/WebApiContrib/WebAPIContrib/tree/master/src/WebApiContrib.Formatting.JsonNet.
Json.NET support will be in the RC release of Web API.

Resources