RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.69k stars 1.24k forks source link

Data Annotions for C# Generated Client missing [Display] annotation #2297

Open andrewmorris-me opened 5 years ago

andrewmorris-me commented 5 years ago

I'm currently using NSwag Studio to generate my C# Client. I have the setting "generate data annotation attributes" turned on and seems to work well for data annotations such as [Required], [MaxLength], [Range] etc...

I've noticed, however, that not all annotations are generated though. Annotations such as [Display(Name)] and [Description] are missing from the generated client, even though they've been added to the model class. For example:

[Required]
[Range(1.9, 3.9)]
[Display(Name = "Total Price")]
public decimal? TotalPrice { get; set; }

Generates the following:

[Newtonsoft.Json.JsonProperty("totalPrice", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Range(1.9D, 3.9D)]
public decimal TotalPrice { get; set; }
RicoSuter commented 5 years ago

I think they are generated as XML docs, no?

andrewmorris-dev commented 5 years ago

the [Description] attribute will generate as a comment in the code, but [Display] does not render anything.

RicoSuter commented 5 years ago

The problem is that json schema/swagger/openapi do not have properties to store both texts, or does it?

andrewmorris-dev commented 5 years ago

There is a screenshot in this corresponding thread of where both attribute details are being stored through openapi. These items I would have thought could be used to generate both the [Display] and [Description] attributes.

https://github.com/RicoSuter/NJsonSchema/issues/1011#issuecomment-508867987

andrewmorris-dev commented 5 years ago

@RicoSuter

Is there any guidance on how to implement this? I believe it can be done, just not sure how or where to start? Thanks

RicoSuter commented 5 years ago

Probably in the JsonSchemaGenerator in the NJsonSchema project?

andrewmorris-dev commented 5 years ago

Thanks for pointing me in the right direction @RicoSuter

I see in the Class.liquid (Line 34) template in the NJsonSchema project, you have the following code:

https://github.com/RicoSuter/NJsonSchema/blob/master/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid

{% for property in Properties -%} {% if property.HasDescription -%} /// {{ property.Description | csharpdocs }} {% endif -%}

I can modify the template code to create a DescriptionAttribute like so, which is great:

{% for property in Properties -%} {% if property.HasDescription -%} /// {{ property.Description | csharpdocs }} [System.ComponentModel.DataAnnotations.Display(Description = "{{ property.Description }}")] {% endif -%}

However, I can't seem to obtain the Title from the list of Properties to create a DisplayNameAttribute:

{% for property in Properties -%} {% if property.HasTitle -%} /// {{ property.Title | csharpdocs }} [System.ComponentModel.DataAnnotations.Display(Name = "{{ property.Title }}")] {% endif -%}

I saw from the following issue below that you added the Title property, based off of the DisplayNameAttribute, but I can't seem to access this title property from within the Class.liquid file?

https://github.com/RicoSuter/NJsonSchema/issues/9#issuecomment-165331280

Does this list of Properties have a Title attribute, or perhaps it's called something else? Where are all these properties defined so I can review them and perhaps add the title/display attribute if possible?

andrewmorris-dev commented 5 years ago

https://github.com/RicoSuter/NJsonSchema/blob/master/src/NJsonSchema.CodeGeneration.CSharp/Models/PropertyModel.cs

I believe that the PropertyModel class is missing the Title attribute:

Where you have the following inside the class for Description:

/// <summary>Gets a value indicating whether the property has a description.</summary>
public bool HasDescription => !string.IsNullOrEmpty(_property.Description);

/// <summary>Gets the description.</summary>
public string Description => _property.Description;

You would need to add the following for Title:

/// <summary>Gets a value indicating whether the property has a title.</summary>
public bool HasTitle => !string.IsNullOrEmpty(_property.Title);

/// <summary>Gets the title.</summary>
public string Title => _property.Title;
jmichas commented 2 years ago

Is there any update on this? Or any work around / instructions on how to get Display into the client generated code?

Hrjodr commented 10 months ago

I'm late to the party but this is also something I would like to see implemented.