title: nswag generates proxy which spoils the URL
body: <p>The general idea of <code>nswag</code> software is amazing.</p>
  
  <p>The guys have totally ruined it though.</p>
  
  <p>I'm really now thinking of dropping it for the following reasons:</p>
  
  <ul>
  <li><p>overcomplicated</p></li>
  <li><p>problematic</p></li>
  <li><p>extremely poorly documented</p></li>
  <li><p>unpopular</p></li>
  </ul>
  
  <p>Regarding my version - <code>"nswag@11.17.19"</code>.</p>
  
  <p>My service is supposed to pass a compound structure (e.g. nested arrays) - but in recent versions it passes all of the content via the URL and here's what I mean:</p>
  
  <p><a href="https://i.stack.imgur.com/Arz3l.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Arz3l.png" alt="enter image description here"></a></p>
  
  <p>Moreover, recent versions of it don't generate input classes - e.g. my API controller has action <code>ImportEntries(ImportEntriesInput input)</code></p>
  
  <p><code>nswag</code> no longer generates input class (I mean <code>ImportEntriesInput</code>) - instead it just lists all of its members:</p>
  
  <p>For example compare</p>
  
  <pre><code>importEntries(input: ImportEntriesInput | null | undefined): Observable&lt;VocabularyDto&gt; {
  </code></pre>
  
  <p>with</p>
  
  <pre><code>importEntries(entries: CrawlerEntryDto[] | null | undefined, vocabularyId: number | undefined, newVocabulary: boolean | undefined, typeId: number | undefined, name: string | null | undefined, notes: string | null | undefined): Observable&lt;VocabularyDto | null&gt; {
  </code></pre>
  
  <p>Maybe the guys who develop it find it okay, but I'd say this totally overcomplicates the whole approach and is <strong>too bad</strong>.</p>
  
  <p>I wasn't really able to find documentation covering this part.</p>
  
  <p>Anyone knows how to solve this?</p>
  
  <hr>
  
  <p>Also, here's the bit where it creates the content being passes in URL:</p>
  
  <pre><code>importEntries(entries: CrawlerEntryDto[] | null | undefined, vocabularyId: number | undefined, newVocabulary: boolean | undefined, typeId: number | undefined, name: string | null | undefined, notes: string | null | undefined): Observable&lt;VocabularyDto | null&gt; {
      let url_ = this.baseUrl + "/api/Import/ImportEntries?";
      if (entries !== undefined)
          entries &amp;&amp; entries.forEach((item, index) =&gt; { 
              for (let attr in item)
                  url_ += "entries[" + index + "]." + attr + "=" + encodeURIComponent("" + item[attr]) + "&amp;";
          });
      if (vocabularyId === null)
          throw new Error("The parameter 'vocabularyId' cannot be null.");
      else if (vocabularyId !== undefined)
          url_ += "vocabularyId=" + encodeURIComponent("" + vocabularyId) + "&amp;"; 
      if (newVocabulary === null)
          throw new Error("The parameter 'newVocabulary' cannot be null.");
      else if (newVocabulary !== undefined)
          url_ += "newVocabulary=" + encodeURIComponent("" + newVocabulary) + "&amp;"; 
      if (typeId === null)
          throw new Error("The parameter 'typeId' cannot be null.");
      else if (typeId !== undefined)
          url_ += "typeId=" + encodeURIComponent("" + typeId) + "&amp;"; 
      if (name !== undefined)
          url_ += "name=" + encodeURIComponent("" + name) + "&amp;"; 
      if (notes !== undefined)
          url_ += "notes=" + encodeURIComponent("" + notes) + "&amp;"; 
      url_ = url_.replace(/[?&amp;]$/, "");
  
      let options_ : any = {
          observe: "response",
          responseType: "blob",
          headers: new HttpHeaders({
              "Content-Type": "application/json", 
              "Accept": "application/json",
              'Authorization': 'Bearer ' + localStorage.getItem('token')
          })
      };
  
      return this.http.request("post", url_, options_).flatMap((response_ : any) =&gt; {
          return this.processImportEntries(response_);
      }).catch((response_: any) =&gt; {
          if (response_ instanceof HttpResponseBase) {
              try {
                  return this.processImportEntries(&lt;any&gt;response_);
              } catch (e) {
                  return &lt;Observable&lt;VocabularyDto | null&gt;&gt;&lt;any&gt;Observable.throw(e);
              }
          } else
              return &lt;Observable&lt;VocabularyDto | null&gt;&gt;&lt;any&gt;Observable.throw(response_);
      });
  }
  </code></pre>
  
  <p><strong>Quite appalling, isn't it?</strong></p>
  
  <p><code>swaggerToTypeScriptClient</code> bit from config:</p>
  
  <pre><code>"codeGenerators": {
      "swaggerToTypeScriptClient": {
        "className": "{controller}ServiceProxy",
        "moduleName": "",
        "namespace": "",
        "typeScriptVersion": 2.0,
        "template": "Angular",
        "promiseType": "Promise",
          "httpClass": "HttpClient",
        "dateTimeType": "MomentJS",
        "nullValue": "Undefined",
        "generateClientClasses": true,
        "generateClientInterfaces": false,
        "generateOptionalParameters": false,
        "wrapDtoExceptions": false,
        "wrapResponses": false,
        "generateResponseClasses": true,
        "responseClass": "SwaggerResponse",
        "useTransformOptionsMethod": false,
        "useTransformResultMethod": false,
        "generateDtoTypes": true,
        "operationGenerationMode": "MultipleClientsFromPathSegments"
        "markOptionalProperties": false,
        "generateCloneMethod": true,
        "typeStyle": "Class",
        "extensionCode": "service.extensions.ts",
        "generateDefaultValues": true,
        "excludedTypeNames": [],
        "handleReferences": false,
        "generateConstructorInterface": true,
        "importRequiredTypes": true,
        "useGetBaseUrlMethod": false,
        "baseUrlTokenName": "API_BASE_URL",
        "injectionTokenType": "InjectionToken",
        "output": "../src/shared/service-proxies/service-proxies.ts"
      },
  </code></pre>