0

How do I use a Swagger API (JSON) to C# code generator like SwaggerHub or NSwagStudio to generate C# Client Code for a larger API such as Clio? (https://app.clio.com/api_v4.json).

These tools seem to work fine for smaller APIs, but when you put a large schema in they output code which does not compile and seems to have multiple issues.

        /// <summary>Return the data for all triggers</summary>
    /// <param name="x_API_VERSION">The [API minor version](#section/Minor-Versions). Default: latest version.</param>
    /// <param name="x_BULK">An indicator if [bulk actions](#section/Bulk-Actions) should be performed.
    /// When performing a bulk action, the id path parameter is not required.</param>
    /// <param name="fields">The fields to be returned. See response samples for what fields are available. For more information see the [fields section](#section/Fields).</param>
    /// <param name="is_requirements_required">Filter JurisdictionsToTrigger records to those which require addition requirements to be checked (usually specifying trigger time).</param>
    /// <param name="is_served">Filter JurisdictionsToTrigger records to those which require a service type to be selected.</param>
    /// <param name="jurisdiction_id">The unique identifier for the Jurisdiction.</param>
    /// <param name="limit">A limit on the number of JurisdictionsToTrigger records to be returned. Limit can range between 1 and 200. Default: `200`.</param>
    /// <param name="page_token">A token specifying which page to return.</param>
    /// <param name="query">Wildcard search for `description` matching a given string.</param>
    /// <returns>Ok</returns>
    /// <exception cref="ClioAPIException">A server side error occurred.</exception>
    public System.Threading.Tasks.Task<JurisdictionsToTriggerList> CourtRulesJurisdictionsId}Triggers.jsonAsync(string x_API_VERSION, bool? x_BULK, string fields, bool? is_requirements_required, bool? is_served, int jurisdiction_id, int? limit, string page_token, string query)
    {
        return CourtRulesJurisdictionsId}Triggers.jsonAsync(x_API_VERSION, x_BULK, fields, is_requirements_required, is_served, jurisdiction_id, limit, page_token, query, System.Threading.CancellationToken.None);
    }

For instance, in the above routine, it adds a "}" to the name CourtRulesJurisdictions}Triggers

I have tried both SwaggerHub and NSwagStudio for this particular API and neither work. The NSwagStudio has the above issue and the SwaggerHub generates code which has this issue. At the end of a client API call to get data, this call to the JsonConvert.DeserializeObject fails. The data is in the Response. Content as I can see it in the debugger, and the type is set to the correct model, but no data is placed in the model.

        try
        {
            return JsonConvert.DeserializeObject(response.Content, type, serializerSettings);
        }
        catch (Exception e)
        {
            throw new ApiException(500, e.Message);
        }

I reduced the code to this, which doesn't even use anything but the generated model and it fails.

    Dim x = "{""data"":{""name"":""Fred G. Jones"",""last_name"":""Jones"",""id"":345171548}}"
    u = Newtonsoft.Json.JsonConvert.DeserializeObject(x, GetType(Clio_API.Model.UserShow))

This is the generated model UserShow

using System;
using System.Linq;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.ComponentModel.DataAnnotations;
using SwaggerDateConverter = Clio_API.Client.SwaggerDateConverter;

namespace Clio_API.Model
{
/// <summary>
/// UserShow
/// </summary>
[DataContract]
public partial class UserShow :  IEquatable<UserShow>, IValidatableObject
{
    /// <summary>
    /// Initializes a new instance of the <see cref="UserShow" /> class.
    /// </summary>
    [JsonConstructorAttribute]
    protected UserShow() { }
    /// <summary>
    /// Initializes a new instance of the <see cref="UserShow" /> class.
    /// </summary>
    /// <param name="Data">User Object Response (required).</param>
    public UserShow(User Data = default(User))
    {
        // to ensure "Data" is required (not null)
        if (Data == null)
        {
            throw new InvalidDataException("Data is a required property for UserShow and cannot be null");
        }
        else
        {
            this.Data = Data;
        }
    }

    /// <summary>
    /// User Object Response
    /// </summary>
    /// <value>User Object Response</value>
    [DataMember(Name="data", EmitDefaultValue=false)]
    public User Data { get; set; }

    /// <summary>
    /// Returns the string presentation of the object
    /// </summary>
    /// <returns>String presentation of the object</returns>
    public override string ToString()
    {
        var sb = new StringBuilder();
        sb.Append("class UserShow {\n");
        sb.Append("  Data: ").Append(Data).Append("\n");
        sb.Append("}\n");
        return sb.ToString();
    }

    /// <summary>
    /// Returns the JSON string presentation of the object
    /// </summary>
    /// <returns>JSON string presentation of the object</returns>
    public string ToJson()
    {
        return JsonConvert.SerializeObject(this, Formatting.Indented);
    }

    /// <summary>
    /// Returns true if objects are equal
    /// </summary>
    /// <param name="input">Object to be compared</param>
    /// <returns>Boolean</returns>
    public override bool Equals(object input)
    {
        return this.Equals(input as UserShow);
    }

    /// <summary>
    /// Returns true if UserShow instances are equal
    /// </summary>
    /// <param name="input">Instance of UserShow to be compared</param>
    /// <returns>Boolean</returns>
    public bool Equals(UserShow input)
    {
        if (input == null)
            return false;

        return 
            (
                this.Data == input.Data ||
                (this.Data != null &&
                this.Data.Equals(input.Data))
            );
    }

    /// <summary>
    /// Gets the hash code
    /// </summary>
    /// <returns>Hash code</returns>
    public override int GetHashCode()
    {
        unchecked // Overflow is fine, just wrap
        {
            int hashCode = 41;
            if (this.Data != null)
                hashCode = hashCode * 59 + this.Data.GetHashCode();
            return hashCode;
        }
    }

    /// <summary>
    /// To validate all properties of the instance
    /// </summary>
    /// <param name="validationContext">Validation context</param>
    /// <returns>Validation Result</returns>
    IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
    {
        yield break;
    }
}
}
Gavin Miller
  • 43,168
  • 21
  • 122
  • 188
  • 2
    Issues, like what? – gunr2171 Jul 10 '18 at 19:14
  • The `csharp` codegen in [Swagger Editor](https://editor.swagger.io) and SwaggerHub generates `public async System.Threading.Tasks.Task JurisdictionsToTriggerIndexAsync (...)` without `}`, so I assume you used NSwagStudio to generate this code. It looks like a bug in NSwagStudio's codegen. Just use the other codegen. – Helen Jul 10 '18 at 21:03
  • Looks like this bug: https://github.com/RSuter/NSwag/issues/1222 – Helen Jul 10 '18 at 21:08

0 Answers0