Skip to content

Commit

Permalink
openapi: support validation attributes (#1477)
Browse files Browse the repository at this point in the history
* openapi: support validation attributes

* wip

* Improve NSwag tests

* Fix some warnings

* Address some comments

* more stuff

* Discard unrelated changes

* Discard more unrealted changes

* Add test for length attribute on collection

* Address PR comments

* stuff

* More stuff

* Fix .NET 8 things

* Fix coding style

* Set ConvertValueInInvariantCulture

* Add Kiota tests

* Address some PR comments

* Add missing properties in happy test

* Fix CS

* Convert DateTime to UTC server-side

* Seal classes

* Apply suggestions from code review

Co-authored-by: Bart Koelman <[email protected]>

* Address PR comments

* Update test/OpenApiTests/ModelStateValidation/ModelStateValidationTests.cs

Co-authored-by: Bart Koelman <[email protected]>

* Address comments

* Add back exclusive range

* Address comment

---------

Co-authored-by: Bart Koelman <[email protected]>
  • Loading branch information
verdie-g and bkoelman authored Jun 21, 2024
1 parent 459ced3 commit e35da84
Show file tree
Hide file tree
Showing 41 changed files with 6,237 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package-versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<CodeAnalysisFrozenVersion>4.1.0</CodeAnalysisFrozenVersion>
<DemystifierFrozenVersion>0.4.1</DemystifierFrozenVersion>
<HumanizerFrozenVersion>2.14.1</HumanizerFrozenVersion>
<SwashbuckleFrozenVersion>6.6.1</SwashbuckleFrozenVersion>
<SwashbuckleFrozenVersion>6.6.2</SwashbuckleFrozenVersion>
<NewtonsoftJsonFrozenVersion>13.0.3</NewtonsoftJsonFrozenVersion>

<!-- Non-published dependencies (these are safe to update, won't cause a breaking change) -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// <auto-generated/>
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Store;
using Microsoft.Kiota.Abstractions;
using Microsoft.Kiota.Serialization.Form;
using Microsoft.Kiota.Serialization.Json;
using Microsoft.Kiota.Serialization.Multipart;
using Microsoft.Kiota.Serialization.Text;
using OpenApiKiotaEndToEndTests.ModelStateValidation.GeneratedCode.SocialMediaAccounts;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System;
namespace OpenApiKiotaEndToEndTests.ModelStateValidation.GeneratedCode {
/// <summary>
/// The main entry point of the SDK, exposes the configuration and the fluent API.
/// </summary>
public class ModelStateValidationClient : BaseRequestBuilder
{
/// <summary>The socialMediaAccounts property</summary>
public SocialMediaAccountsRequestBuilder SocialMediaAccounts
{
get => new SocialMediaAccountsRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>
/// Instantiates a new <see cref="ModelStateValidationClient"/> and sets the default values.
/// </summary>
/// <param name="backingStore">The backing store to use for the models.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ModelStateValidationClient(IRequestAdapter requestAdapter, IBackingStoreFactory backingStore = default) : base(requestAdapter, "{+baseurl}", new Dictionary<string, object>())
{
ApiClientBuilder.RegisterDefaultSerializer<JsonSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultSerializer<TextSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultSerializer<FormSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultSerializer<MultipartSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultDeserializer<JsonParseNodeFactory>();
ApiClientBuilder.RegisterDefaultDeserializer<TextParseNodeFactory>();
ApiClientBuilder.RegisterDefaultDeserializer<FormParseNodeFactory>();
if (string.IsNullOrEmpty(RequestAdapter.BaseUrl))
{
RequestAdapter.BaseUrl = "http://localhost";
}
PathParameters.TryAdd("baseurl", RequestAdapter.BaseUrl);
RequestAdapter.EnableBackingStore(backingStore);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// <auto-generated/>
using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Abstractions.Store;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System;
namespace OpenApiKiotaEndToEndTests.ModelStateValidation.GeneratedCode.Models {
#pragma warning disable CS1591
public class DataInResponse : IBackedModel, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores model information.</summary>
public IBackingStore BackingStore { get; private set; }
/// <summary>The id property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Id {
get { return BackingStore?.Get<string?>("id"); }
set { BackingStore?.Set("id", value); }
}
#nullable restore
#else
public string Id {
get { return BackingStore?.Get<string>("id"); }
set { BackingStore?.Set("id", value); }
}
#endif
/// <summary>The type property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Type {
get { return BackingStore?.Get<string?>("type"); }
set { BackingStore?.Set("type", value); }
}
#nullable restore
#else
public string Type {
get { return BackingStore?.Get<string>("type"); }
set { BackingStore?.Set("type", value); }
}
#endif
/// <summary>
/// Instantiates a new <see cref="DataInResponse"/> and sets the default values.
/// </summary>
public DataInResponse()
{
BackingStore = BackingStoreFactorySingleton.Instance.CreateBackingStore();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="DataInResponse"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static DataInResponse CreateFromDiscriminatorValue(IParseNode parseNode)
{
_ = parseNode ?? throw new ArgumentNullException(nameof(parseNode));
var mappingValue = parseNode.GetChildNode("type")?.GetStringValue();
return mappingValue switch
{
"socialMediaAccounts" => new SocialMediaAccountDataInResponse(),
_ => new DataInResponse(),
};
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{"id", n => { Id = n.GetStringValue(); } },
{"type", n => { Type = n.GetStringValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
_ = writer ?? throw new ArgumentNullException(nameof(writer));
writer.WriteStringValue("id", Id);
writer.WriteStringValue("type", Type);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// <auto-generated/>
using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Abstractions.Store;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System;
namespace OpenApiKiotaEndToEndTests.ModelStateValidation.GeneratedCode.Models {
#pragma warning disable CS1591
public class ErrorLinks : IBackedModel, IParsable
#pragma warning restore CS1591
{
/// <summary>The about property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? About {
get { return BackingStore?.Get<string?>("about"); }
set { BackingStore?.Set("about", value); }
}
#nullable restore
#else
public string About {
get { return BackingStore?.Get<string>("about"); }
set { BackingStore?.Set("about", value); }
}
#endif
/// <summary>Stores model information.</summary>
public IBackingStore BackingStore { get; private set; }
/// <summary>The type property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Type {
get { return BackingStore?.Get<string?>("type"); }
set { BackingStore?.Set("type", value); }
}
#nullable restore
#else
public string Type {
get { return BackingStore?.Get<string>("type"); }
set { BackingStore?.Set("type", value); }
}
#endif
/// <summary>
/// Instantiates a new <see cref="ErrorLinks"/> and sets the default values.
/// </summary>
public ErrorLinks()
{
BackingStore = BackingStoreFactorySingleton.Instance.CreateBackingStore();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="ErrorLinks"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static ErrorLinks CreateFromDiscriminatorValue(IParseNode parseNode)
{
_ = parseNode ?? throw new ArgumentNullException(nameof(parseNode));
return new ErrorLinks();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{"about", n => { About = n.GetStringValue(); } },
{"type", n => { Type = n.GetStringValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
_ = writer ?? throw new ArgumentNullException(nameof(writer));
writer.WriteStringValue("about", About);
writer.WriteStringValue("type", Type);
}
}
}
Loading

0 comments on commit e35da84

Please sign in to comment.