Swashbuckle wraps number examples with double quotes from VS XML comments - asp.net-core

I have a class representing a body for an endpoint, in that class is an Amount property, it looks like this:
/// <summary>
/// The transaction amount; it must be greater than 0
/// </summary>
/// <example>1.23</example>
[JsonProperty("Amount")]
[Required]
public decimal Amount { get; set; }
The problem I'm having is that when Swashbuckle generates the JSON for this Request body example, it ends up wrapping the Amount value with double quotes like this:
{
"Amount": "1.23"
}
I want it to look like a number, like this:
{
"Amount": 1.23
}
If I give no XML example tag, the Request Body example generated in the SwaggerUI is just 0.0 with no double quotes, like this:
{
"Amount": 0.0
}
The portion of the XML comments that is generated from this example doesn't have quotes:
<member name="P:MyAPI.Models.SaleRequest.Amount">
<summary>
The transaction amount; it must be greater than 0
</summary>
<example>1.23</example>
</member>
But the JSON generated from Swashbuckle does:
"SaleRequest": {
"required": [
"Amount"
],
"type": "object",
"properties": {
"Amount": {
"format": "decimal",
"description": "The transaction amount; it must be greater than 0",
"type": "number",
"example": "1.23"
}
}
}
Is there a way I can tell Swashbuckle not to wrap this XML example tag for a number property with double quotes? I've been searching for a while and can't find anything. I've tried c.MapType<decimal>(() => new Schema { Type = "number", Format = "decimal" }); from another post when configuring swagger but that didn't change anything. I didn't see any attributes I could apply to the property in the source code either. I'm using Swashbuckle 4.0.1

Related

ASP .NET Core Generated Swagger Descriptions missing on object attributes

I am attempting to generate swagger json from an API that I am building with ASP Net Core 3.1 and Swashbuckle SwaggerGen. I'm using the below in my Startup.cs in order to generate documentation based on summaries of methods and models.
services.AddSwaggerGen( options =>
{
var xmlFile = $"{Assembly.GetExecutingAssembly( ).GetName( ).Name}.xml";
var xmlPath = Path.Combine( AppContext.BaseDirectory, xmlFile );
options.IncludeXmlComments( xmlPath );
} );
This does work in most instances. But it does not work with custom objects. Take these two attributes for example:
/// <summary>
/// ExampleValue description.
/// </summary>
public string ExampleValue{ get; set; }
/// <summary>
/// ExampleValue2 description.
/// </summary>
public CustomObject ExampleValue2{ get; set; }
In the generated json, you can see the description does not show up for ExampleValue2
"exampleValue": {
"type": "string",
"description": "ExampleValue description.",
"nullable": true
},
"exampleValue2": {
"$ref": "#/components/schemas/CustomObject"
},
To my understanding, if I put a summary on top of the CustomObject that will show up for all references of the object but that's not what I would expect here. If I use this custom object in lots of places, I would like to have unique descriptions for each instance of it in any of my models that are used for requests.
When I look at the .xml file of the assembly the summary is indeed there on the CustomObject so I do not believe it is a problem with the assembly file.

What is an efficient way to generate vb classes from json schemas?

Is there any way to generate vb classes from jsonschema files like we can generate classes from wsdls and xsds using wsdl.exe in one go.
I don't want to use Edit > Paste special > paste JSON as class feature of Visual Studio because I tried for one file and it did not give me the result I am expecting and also there are about 15 schema files so want a generic way.
On using Edit > Paste special > paste JSON as class feature of Visual Studio,
The schema have is:
{
"title": "MyObject",
"type": "object",
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"id": {
"type": "string"
}
},
"required": [ "id", "description", "name" ]
}
The generated classes:
Public Class Rootobject
Public Property title As String
Public Property type As String
Public Property properties As Properties
Public Property required() As String
End Class
Public Class Properties
Public Property description As Description
Public Property name As Name
Public Property id As Id
End Class
Public Class Description
Public Property type As String
End Class
Public Class Name
Public Property type As String
End Class
Public Class Id
Public Property type As String
End Class

Does Swashbuckle and Swagger allow specifying maximum string lengths? [duplicate]

I am using ASP.NET and Swagger that exposes a complex type that accepts a POST. It has a number of string fields that have different restricted lengths. How can I reflect that in the Swagger UI?
You can annotate the properties with the StringLengthAttribute from System.ComponentModel.DataAnnotations.
For instance:
[StringLength(10)]
public String Name {get;set;}
will become:
"name": {
"minLength": 0,
"maxLength": 10,
"type": "string"
}
And this:
[StringLength(10, MinimumLength = 5)]
public String Name {get;set;}
becomes:
"name": {
"minLength": 5,
"maxLength": 10,
"type": "string"
}
Besides StringLength Swashbuckle also supports the Range and RegularExpression attributes.
Update
MaxLength does not work. StringLength does. However, discovering this information in Swagger UI is a bit clumsy. You have to navigate to the Model of your object and then hover over the property:

Data annotations in Swagger

I am using ASP.NET and Swagger that exposes a complex type that accepts a POST. It has a number of string fields that have different restricted lengths. How can I reflect that in the Swagger UI?
You can annotate the properties with the StringLengthAttribute from System.ComponentModel.DataAnnotations.
For instance:
[StringLength(10)]
public String Name {get;set;}
will become:
"name": {
"minLength": 0,
"maxLength": 10,
"type": "string"
}
And this:
[StringLength(10, MinimumLength = 5)]
public String Name {get;set;}
becomes:
"name": {
"minLength": 5,
"maxLength": 10,
"type": "string"
}
Besides StringLength Swashbuckle also supports the Range and RegularExpression attributes.
Update
MaxLength does not work. StringLength does. However, discovering this information in Swagger UI is a bit clumsy. You have to navigate to the Model of your object and then hover over the property:

SignalR and serializing object array

I'm new to SignalR and have done a simple test hack. I wish to serialize an object array with typed objects. By default SignalR has configured the JSon.NET serializer to not provide with type information. And I found that I could register a custom serializer in the DependencyResolver by:
var serializer =
new EventHubJsonSerializer(
new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
TypeNameHandling = TypeNameHandling.Objects
});
GlobalHost.DependencyResolver.Register(typeof(IJsonSerializer), () => serializer);
However when I recieve my object array it will not resolve the types, instead it is a JSonContainer. Can I solve this in any way?
The event emitted from the Hub:
public sealed class SignalREvent
{
public string Group { get; set; }
public string EventName { get; set; }
public string TypeFullName { get; set; }
public IList<object> EventArguments { get; set; }
}
And the receptor have to unwrap the boolean via casting to dynamic:
public sealed class TestEventArgs : EventArgs
{
#region Public Properties
/// <summary>
/// Gets or sets a value indicating whether do not print.
/// </summary>
public bool DoNotPrint { get; set; }
/// <summary>
/// Gets or sets the event name.
/// </summary>
public string EventName { get; set; }
#endregion
}
this.subscription = this.client.On<SignalREvent>(
"PushEvent",
data =>
{
dynamic eventArg1 = data.EventArguments[0];
if (eventArg1.DoNotPrint.Value)
{
return;
}
});
What I've done is a postsharp aspect to apply on events in order to allow them to propagate via SignalR via my EventHub. For example:
[ExternalizeEvent]
public event ASimpleDelegate SimpleEvent;
It's a darn simple aspect, but it would really be good to have type info when in the .net world - other clients would of course not benefit of this.
Update
This is the output for my JSon.NET configuration - types are propagated in the $type but it seems that it is not used during deseralization.
{
"$id": "11",
"$type": "<>f__AnonymousType0`3[[System.String, mscorlib],[System.String, mscorlib],[System.Object[], mscorlib]], SignalR",
"Hub": "Externalize.EventHub",
"Method": "PushEvent",
"Args": [
{
"$id": "12",
"$type": "DataDuctus.SignalR.Aspects.SignalREvent, DataDuctus.SignalR.Aspects",
"Group": "all",
"EventName": "SimpleEvent",
"TypeFullName": "TestConsole.TestEvents",
"EventArguments": [
{
"$id": "13",
"$type": "TestConsole.TestEventArgs, TestConsole",
"DoNotPrint": false,
"EventName": "second event (test)"
}
]
}
]
}
Cheers,
Mario
The SignalR .NET client does not use the DependencyResolver from the server and currently does not have an IoC container of its own. Because of this, as you note in your question, your custom JsonSerializerSettings are used for serialization on the server but not for deserialization on the client.
In the next release of SignalR we plan to add a DependencyResolver to the .NET client that will allow you to provide your own Newtonsoft.Json.JsonSerializer or Newtonsoft.Json.JsonSerializerSettings to be used during deserialization. There are currently no plans to allow the use of a non-Json.NET (de)serializer in the .NET client.
If you need this functionality now, you could clone https://github.com/SignalR/SignalR.git and modify the private static T Convert<T>(JToken obj) method in SignalR.Client\Hubs\HubProxyExtensions.cs to return obj.ToObject<T>(yourJsonSerializer).