Skip to content
2 changes: 2 additions & 0 deletions JsonApiDotNetCore.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$, $NAME$);</s:String>
<s:Int64 x:Key="/Default/CodeEditing/NullCheckPatterns/PatternTypeNamesToPriority/=JetBrains_002EReSharper_002EFeature_002EServices_002ECSharp_002ENullChecking_002ETraceAssertPattern/@EntryIndexedValue">50</s:Int64>
<s:Boolean x:Key="/Default/CodeInspection/CodeAnnotations/PropagateAnnotations/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=swagger_002Ejson/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedFileMasks/=swagger_002Eg_002Ejson/@EntryIndexedValue">swagger.g.json</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedFileMasks/=swagger_002Ejson/@EntryIndexedValue">swagger.json</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">SOLUTION</s:String>
<s:Boolean x:Key="/Default/CodeInspection/Highlighting/IdentifierHighlightingEnabled/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/Highlighting/IncludeWarningsInSwea/@EntryValue">True</s:Boolean>
Expand Down
25 changes: 25 additions & 0 deletions src/JsonApiDotNetCore.OpenApi.Client/ApiException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using JetBrains.Annotations;

// We cannot rely on generating ApiException as soon as we are generating multiple clients, see https://github.com/RicoSuter/NSwag/issues/2839#issuecomment-776647377.
// Instead, we configure NSwag to point to the exception below in the generated code.

// ReSharper disable once CheckNamespace
namespace JsonApiDotNetCore.OpenApi.Client.Exceptions;

[UsedImplicitly(ImplicitUseTargetFlags.Members)]
public sealed class ApiException : Exception
{
public int StatusCode { get; }

public string? Response { get; }

public IReadOnlyDictionary<string, IEnumerable<string>> Headers { get; }

public ApiException(string message, int statusCode, string? response, IReadOnlyDictionary<string, IEnumerable<string>> headers, Exception innerException)
: base($"{message}\n\nStatus: {statusCode}\nResponse: \n{response ?? "(null)"}", innerException)
{
StatusCode = statusCode;
Response = response;
Headers = headers;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
using JsonApiDotNetCore.Resources;

namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;

// Types in the current namespace are never touched by ASP.NET ModelState validation, therefore using a non-nullable reference type for a property does not
// imply this property is required. Instead, we use [Required] explicitly, because this is how Swashbuckle is instructed to mark properties as required.
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
internal sealed class NullableResourceIdentifierResponseDocument<TResource> : NullableSingleData<ResourceIdentifierObject<TResource>>
where TResource : IIdentifiable
{
[JsonPropertyName("meta")]
public IDictionary<string, object> Meta { get; set; } = null!;

[JsonPropertyName("jsonapi")]
public JsonapiObject Jsonapi { get; set; } = null!;

[Required]
[JsonPropertyName("links")]
public LinksInResourceIdentifierDocument Links { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
Expand All @@ -10,10 +11,13 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;
internal sealed class NullableSecondaryResourceResponseDocument<TResource> : NullableSingleData<ResourceObjectInResponse<TResource>>
where TResource : IIdentifiable
{
[JsonPropertyName("meta")]
public IDictionary<string, object> Meta { get; set; } = null!;

[JsonPropertyName("jsonapi")]
public JsonapiObject Jsonapi { get; set; } = null!;

[Required]
[JsonPropertyName("links")]
public LinksInResourceDocument Links { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
using JsonApiDotNetCore.Resources;

namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;

// Types in the current namespace are never touched by ASP.NET ModelState validation, therefore using a non-nullable reference type for a property does not
// imply this property is required. Instead, we use [Required] explicitly, because this is how Swashbuckle is instructed to mark properties as required.
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
internal sealed class PrimaryResourceResponseDocument<TResource> : SingleData<ResourceObjectInResponse<TResource>>
where TResource : IIdentifiable
{
[JsonPropertyName("meta")]
public IDictionary<string, object> Meta { get; set; } = null!;

[JsonPropertyName("jsonapi")]
public JsonapiObject Jsonapi { get; set; } = null!;

[Required]
[JsonPropertyName("links")]
public LinksInResourceDocument Links { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
Expand All @@ -10,10 +11,13 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;
internal sealed class ResourceCollectionResponseDocument<TResource> : ManyData<ResourceObjectInResponse<TResource>>
where TResource : IIdentifiable
{
[JsonPropertyName("meta")]
public IDictionary<string, object> Meta { get; set; } = null!;

[JsonPropertyName("jsonapi")]
public JsonapiObject Jsonapi { get; set; } = null!;

[Required]
[JsonPropertyName("links")]
public LinksInResourceCollectionDocument Links { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
Expand All @@ -10,10 +11,13 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;
internal sealed class ResourceIdentifierCollectionResponseDocument<TResource> : ManyData<ResourceIdentifierObject<TResource>>
where TResource : IIdentifiable
{
[JsonPropertyName("meta")]
public IDictionary<string, object> Meta { get; set; } = null!;

[JsonPropertyName("jsonapi")]
public JsonapiObject Jsonapi { get; set; } = null!;

[Required]
[JsonPropertyName("links")]
public LinksInResourceIdentifierCollectionDocument Links { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
Expand All @@ -10,10 +11,13 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;
internal sealed class ResourceIdentifierResponseDocument<TResource> : SingleData<ResourceIdentifierObject<TResource>>
where TResource : IIdentifiable
{
[JsonPropertyName("meta")]
public IDictionary<string, object> Meta { get; set; } = null!;

[JsonPropertyName("jsonapi")]
public JsonapiObject Jsonapi { get; set; } = null!;

[Required]
[JsonPropertyName("links")]
public LinksInResourceIdentifierDocument Links { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
Expand All @@ -10,10 +11,13 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;
internal sealed class SecondaryResourceResponseDocument<TResource> : SingleData<ResourceObjectInResponse<TResource>>
where TResource : IIdentifiable
{
[JsonPropertyName("meta")]
public IDictionary<string, object> Meta { get; set; } = null!;

[JsonPropertyName("jsonapi")]
public JsonapiObject Jsonapi { get; set; } = null!;

[Required]
[JsonPropertyName("links")]
public LinksInResourceDocument Links { get; set; } = null!;
}
5 changes: 5 additions & 0 deletions src/JsonApiDotNetCore.OpenApi/JsonApiObjects/JsonapiObject.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
using System.Text.Json.Serialization;
using JetBrains.Annotations;

namespace JsonApiDotNetCore.OpenApi.JsonApiObjects;

[UsedImplicitly(ImplicitUseTargetFlags.Members)]
internal sealed class JsonapiObject
{
[JsonPropertyName("version")]
public string Version { get; set; } = null!;

[JsonPropertyName("ext")]
public ICollection<string> Ext { get; set; } = null!;

[JsonPropertyName("profile")]
public ICollection<string> Profile { get; set; } = null!;

[JsonPropertyName("meta")]
public IDictionary<string, object> Meta { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;

namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
Expand All @@ -7,8 +8,10 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
internal sealed class LinksInRelationshipObject
{
[Required]
[JsonPropertyName("self")]
public string Self { get; set; } = null!;

[Required]
[JsonPropertyName("related")]
public string Related { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;

namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
Expand All @@ -7,16 +8,22 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
internal sealed class LinksInResourceCollectionDocument
{
[Required]
[JsonPropertyName("self")]
public string Self { get; set; } = null!;

[JsonPropertyName("describedby")]
public string Describedby { get; set; } = null!;

[Required]
[JsonPropertyName("first")]
public string First { get; set; } = null!;

[JsonPropertyName("last")]
public string Last { get; set; } = null!;

[JsonPropertyName("prev")]
public string Prev { get; set; } = null!;

[JsonPropertyName("next")]
public string Next { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;

namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
Expand All @@ -7,7 +8,9 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
internal sealed class LinksInResourceDocument
{
[Required]
[JsonPropertyName("self")]
public string Self { get; set; } = null!;

[JsonPropertyName("describedby")]
public string Describedby { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;

namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
Expand All @@ -7,19 +8,26 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
internal sealed class LinksInResourceIdentifierCollectionDocument
{
[Required]
[JsonPropertyName("self")]
public string Self { get; set; } = null!;

[JsonPropertyName("describedby")]
public string Describedby { get; set; } = null!;

[Required]
[JsonPropertyName("related")]
public string Related { get; set; } = null!;

[Required]
[JsonPropertyName("first")]
public string First { get; set; } = null!;

[JsonPropertyName("last")]
public string Last { get; set; } = null!;

[JsonPropertyName("prev")]
public string Prev { get; set; } = null!;

[JsonPropertyName("next")]
public string Next { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;

namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
Expand All @@ -7,10 +8,13 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
internal sealed class LinksInResourceIdentifierDocument
{
[Required]
[JsonPropertyName("self")]
public string Self { get; set; } = null!;

[JsonPropertyName("describedby")]
public string Describedby { get; set; } = null!;

[Required]
[JsonPropertyName("related")]
public string Related { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;

namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
Expand All @@ -7,5 +8,6 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
internal sealed class LinksInResourceObject
{
[Required]
[JsonPropertyName("self")]
public string Self { get; set; } = null!;
}
2 changes: 2 additions & 0 deletions src/JsonApiDotNetCore.OpenApi/JsonApiObjects/ManyData.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;

Expand All @@ -9,5 +10,6 @@ internal abstract class ManyData<TData>
where TData : ResourceIdentifierObject
{
[Required]
[JsonPropertyName("data")]
public ICollection<TData> Data { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;

Expand All @@ -9,5 +10,6 @@ internal abstract class NullableSingleData<TData>
where TData : ResourceIdentifierObject
{
[Required]
[JsonPropertyName("data")]
public TData? Data { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
Expand All @@ -11,7 +12,9 @@ internal sealed class NullableToOneRelationshipInResponse<TResource> : NullableS
where TResource : IIdentifiable
{
[Required]
[JsonPropertyName("links")]
public LinksInRelationshipObject Links { get; set; } = null!;

[JsonPropertyName("meta")]
public IDictionary<string, object> Meta { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Links;
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
Expand All @@ -11,7 +12,9 @@ internal sealed class ToManyRelationshipInResponse<TResource> : ManyData<Resourc
where TResource : IIdentifiable
{
[Required]
[JsonPropertyName("links")]
public LinksInRelationshipObject Links { get; set; } = null!;

[JsonPropertyName("meta")]
public IDictionary<string, object> Meta { get; set; } = null!;
}
Loading