Swagger UI erases Parameters - c#

The error that I'm seeing is that as soon as I enter something into a Parameter on the UI it disappears.
I am creating Controllers on the fly based on method decorations, so I can't create the XML that drives swagger.json at build-time. As a way around it, I created another controller which inspects the controllers that were added to the runtime and outputs valid swagger.json (or so I think). This works okay with POST, but seems fails peculiarly when trying to add route parameters to GET.
This is the json I generate for my GET:
"openapi": "3.0.1",
... // cutting out unrelated other stuff
"/api/v1/test4/{Value2}": {
"get": {
"tags": [
],
"summary": "A sample GET",
"parameters": [
{
"name": "Value2",
"in ": "path",
"required": true,
"schema": {
"type": "string",
"format": ""
}
},
,
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"$ref": "#/components/schemas/TestReply"
}
}
}
}
}
}
}
The project is a .Net Framework 4.8 one, and the packages I'm using are Microsoft.AspNetCore 2.2.0 and Swashbuckle.AspNetCore 5.5.1.

There's an extra space in the name of the in attribute:
"in ": "path",
^
^
Remove that space.
You can also use https://editor.swagger.io to check your API definition for syntax errors.

Related

C# How to get exact error message from Logic App triggered by HttpRequest instead of default error message?

I have a simple console application and it calls a Logic App by HttpRequest.
When the Logic App fails at any step I want to get exact the error message saying why it fails.
In the Logic App I can see the error.
Example: in the image, it fails at step 2 which it can't convert a string into an int. It's saying:
InvalidTemplate. Unable to process template language expressions in action 'Parse_JSON' inputs at line '0' and column '0': 'Required property 'content' expects a value but got null. Path ''.'.
which is what's I expect.
Here is my Logic App design:
But when I debug in a console application, it gives me a message "The server did not receive a response from an upstream server. Request tracking id 'some random Ids'." which is not very useful.
Here is my console application:
var obj = new
{
Age = "Twenty",
Name = "James"
};
using (var client = new HttpClient())
{
var content = new StringContent(JsonConvert.SerializeObject(obj));
content.Headers.ContentType.MediaType = "application/json";
var response = await client.PostAsync(url, content);
var errorMessage = await response.Content.ReadAsStringAsync();
//errorMessage: {"error":{"code":"NoResponse","message":"The server did not receive a response from an upstream server. Request tracking id 'some random Ids'."}}
}
So is there anyway to make the C# response return the error message in the step 2 of the Logic App?
What I expect is:
InvalidTemplate. Unable to process template language expressions in action 'Parse_JSON' inputs at line '0' and column '0': 'Required property 'content' expects a value but got null. Path ''.'.
Not:
{"error":{"code":"NoResponse","message":"The server did not receive a response from an upstream server. Request tracking id 'some random Ids'."}}
Thank you in advanced.
You can use actions('<Your_Previous_Step>')['error'] in your case actions('Parse_JSON')['error'] doing so you can able to retrieve the error message of that particular action.
Here is my logic app
I'm testing this through postman. Below is the response I received in postman.
Make sure you set Configure run after options to make the flow work even after it gets failed.
Updated Answer (General Solution)
In this case you can initialise a string variable and then add Append to string variable for each step so that it can catch the previous steps error. Below is the screenshot of my logic app.
Response in my postman
NOTE: Make sure you set Configure run after property for each action.
You can use the Scope action to encase the vast majority of other actions and then if something fails, you can catch the step for which it fails at.
You can load this JSON definition into your own tenant and see a working version.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Filter_array": {
"inputs": {
"from": "#variables('Result')",
"where": "#equals(item()['status'], 'Failed')"
},
"runAfter": {
"Initialize_Result": [
"Succeeded"
]
},
"type": "Query"
},
"Initialize_Error_Message": {
"inputs": {
"variables": [
{
"name": "Error Message",
"type": "string",
"value": "#{body('Filter_array')[0]['error']['message']}"
}
]
},
"runAfter": {
"Filter_array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Integer_Variable": {
"inputs": {
"variables": [
{
"name": "Integer Variable",
"type": "integer",
"value": 1
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_Result": {
"inputs": {
"variables": [
{
"name": "Result",
"type": "array",
"value": "#result('Scope')"
}
]
},
"runAfter": {
"Scope": [
"Succeeded",
"FAILED"
]
},
"type": "InitializeVariable"
},
"Scope": {
"actions": {
"Set_Integer_Variable_(Step_1)": {
"inputs": {
"name": "Integer Variable",
"value": 2
},
"runAfter": {},
"type": "SetVariable"
},
"Set_Integer_Variable_(Step_2)": {
"inputs": {
"name": "Integer Variable",
"value": "#string('Test')"
},
"runAfter": {
"Set_Integer_Variable_(Step_1)": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Set_Integer_Variable_(Step_3)": {
"inputs": {
"name": "Integer Variable",
"value": 3
},
"runAfter": {
"Set_Integer_Variable_(Step_2)": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"runAfter": {
"Initialize_Integer_Variable": [
"Succeeded"
]
},
"type": "Scope"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"Recurrence": {
"evaluatedRecurrence": {
"frequency": "Month",
"interval": 12
},
"recurrence": {
"frequency": "Month",
"interval": 12
},
"type": "Recurrence"
}
}
},
"parameters": {}
}
Naturally, it's a little more intensive and follows the same principals as a normal flow for continuing to the next step after a failure but this will help you with larger flows.
This is what the test flow looks like ...
To explain it quickly, the middle steps are simple Set Variable actions that can be changed to cause the failure.
In the definition I've given you, step 2 will fail but you can change it to step 1 or 3 and you should still see the error come out at the end regardless of the step in the scope action that fails.
I suggest playing with it and looking at the output to the scope action, which is written to variable Result in the Initialize Result step.
For reference, this is the sort of information that comes out of the Scope action that you can use to determine what has failed.
{
"variables": [
{
"name": "Result",
"type": "Array",
"value": [
{
"name": "Set_Integer_Variable_(Step_1)",
"inputs": {
"name": "Integer Variable",
"value": 2
},
"outputs": {
"body": {
"name": "Integer Variable",
"value": 2
}
},
"startTime": "2022-04-22T06:55:57.8965917Z",
"endTime": "2022-04-22T06:55:57.9281959Z",
"trackingId": "0c93fa70-a552-4776-bce1-8ac889933de9",
"clientTrackingId": "08585509963278112157168286283CU11",
"status": "Succeeded"
},
{
"name": "Set_Integer_Variable_(Step_2)",
"startTime": "2022-04-22T06:55:57.9434709Z",
"endTime": "2022-04-22T06:55:57.9434709Z",
"trackingId": "f82b494b-0ecd-412b-887a-d4b08f4a5751",
"clientTrackingId": "08585509963278112157168286283CU11",
"code": "BadRequest",
"status": "Failed",
"error": {
"code": "BadRequest",
"message": "The variable 'Integer Variable' of type 'Integer' cannot be initialized or updated with value of type 'String'. The variable 'Integer Variable' only supports values of types 'Integer'."
}
},
{
"name": "Set_Integer_Variable_(Step_3)",
"startTime": "2022-04-22T06:55:57.9590957Z",
"endTime": "2022-04-22T06:55:57.9590957Z",
"trackingId": "f761d71f-8ec0-4a29-9a8a-a39a81faf660",
"clientTrackingId": "08585509963278112157168286283CU11",
"code": "ActionSkipped",
"status": "Skipped",
"error": {
"code": "ActionConditionFailed",
"message": "The execution of template action 'Set_Integer_Variable_(Step_3)' is skipped: the 'runAfter' condition for action 'Set_Integer_Variable_(Step_2)' is not satisfied. Expected status values 'Succeeded' and actual value 'Failed'."
}
}
]
}
]
}
Take note, you still need to apply the Configure run after properties to ensure it continues on after the Scope action finishes ...
You'd need to put some more error checking in but my suggestion would be to wrap all of that functionality into another LogicApp that you can reuse across your tenant. That's the thinking anyway.

Pass custom screenshot consumer though json config

Hi,
I use Atata framework with ExtentReports, based on this project: https://github.com/atata-framework/atata-samples/tree/master/ExtentReports
Now I want switch from fluent context build to json config. My fluent context build looks like:
AtataContext.GlobalConfiguration
.UseChrome()
.WithArguments("--start-maximized")
.WithLocalDriverPath()
.WithFixOfCommandExecutionDelay()
.UseCulture("en-US")
.UseAllNUnitFeatures()
.AddDebugLogging()
.AddScreenshotFileSaving()
.WithArtifactsFolderPath()
.AddLogConsumer(new ExtentLogConsumer())
.WithMinLevel(LogLevel.Info)
.EventSubscriptions.Add(new ExtentScreenshotFileEventHandler());
AtataContext.GlobalConfiguration.AutoSetUpDriverToUse();
I can implement via json config almost all, except this line:
.EventSubscriptions.Add(new ExtentScreenshotFileEventHandler());
My config:
{
"driver": {
"type": "chrome",
"alias": "chrome",
"options": {
"arguments": [ "start-maximized" ],
"userProfilePreferences": {
"download.default_directory": "{artifacts}"
}
}
},
"culture": "en-US",
"useAllNUnitFeatures": true,
"logConsumers": [
{
"type": "nlog-file",
"folderPath": "{artifacts}",
"minLevel": "Debug"
},
{
"type": "AtataUITests1.Core.Reporting.ExtentLogConsumer, AtataUITests1",
"minLevel": "Info"
}
],
"screenshotConsumers": [
{
"type": "file",
"folderPath": "{artifacts}"
}
]
}
When I try to add new screenshotConsumer to json:
"screenshotConsumers": [
{
"type": "file",
"folderPath": "{artifacts}"
},
{
"type": "AtataUITests1.Core.Reporting.ExtentScreenshotFileEventHandler, AtataUITests1"
}
]
it shows error:
System.InvalidCastException : Unable to cast object of type 'AtataUITests1.Core.Reporting.ExtentScreenshotFileEventHandler' to type 'Atata.IScreenshotConsumer'.
My question is: is it possible to pass this custom screenshot consumer via json?
Thanks
ExtentScreenshotFileEventHandler is not a screenshot consumer but an event handler. So it should be placed in "eventSubscriptions" section as below:
"eventSubscriptions": [
{
"handlerType": "AtataUITests1.Core.Reporting.ExtentScreenshotFileEventHandler, AtataUITests1"
}
]
There is also an example on Atata.Configuration.Json / JSON Schema section.

How to represent an array of longs as a query parameter in Swagger 2.0?

I am having a hard time figuring out what would be the correct Swagger 2.0 spec for the case where I am expecting a parameter in the query to be a list of long (C#). This is what I tried based on seeing examples where the parameter being passed in query is simple datatypes like int or boolean. But this does not seem to work. It does not look like it is getting parsed correctly.
My URI is somethng like this :
https://.../testinstance/FeatureTexts?api-version=2016-09-13&featureIds=1629988727&featureIds=1924980024
And in my API-level test it does not gets resolved to anything similar after the part api-version=2016-09-13&featureIds=
"get": {
"tags": [
"FeatureText"
],
"operationId": "RenderFeatureTexts",
"description": "The operation to get feature texts for specified features",
"parameters": [
{
"name": "featureIds",
"in": "query",
"required": true,
"schema": {
"type": "array",
"collectionFormat": "multi",
"items": {
"type": "integer",
"format": "int64"
}
},
.......
C# code generated by Swagger Codegen:
public static async System.Threading.Tasks.Task<object> ListFeatureTextsAsync(this IAgentClient operations, object featureIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
{
using (var _result = await operations.ListFeatureTextsWithHttpMessagesAsync(featureIds, null, cancellationToken).ConfigureAwait(false))
{
return _result.Body;
}
}
Change the parameter definition as shown below, that is, move type, items and collectionFormat out of schema. In OpenAPI 2.0, schema is only used for body parameters, and other parameter types use type etc. directly.
"parameters": [
{
"name": "featureIds",
"in": "query",
"required": true,
"type": "array",
"collectionFormat": "multi",
"items": {
"type": "integer",
"format": "int64"
}
You can easily catch syntax errors like this by pasting your spec into Swagger Editor.

TFS 2015: Release Definition REST API Issue

Visual Studio 2017 15.7.5
.Net Core 2.1
TFS 2015 Update 3
I'm trying to make a POST request to create a release. This is the documentation I'm referring to. But I get the following error message:
"VS402881: No artifact version is specified corresponding to artifact
source 'example0'. Specify a valid value and try
again.\",\"typeName\":\"Microsoft.VisualStudio.Services.ReleaseManagement.Data.Exceptions.InvalidRequestException,
Microsoft.VisualStudio.Services.ReleaseManagement2.Data,
Version=14.0.0.0, Culture=neutral,
PublicKeyToken=...\",\"typeKey\":\"InvalidRequestException\",\"errorCode\":0,\"eventId\":3000}"
This is an example of my request.
{
"definitionId": 1,
"description": "Creating Sample release",
"artifacts": [
{
"alias": "example0",
"instanceReference": [
{
"id": "39194",
"name": "example"
}
]
},
{
"alias": "example0",
"instanceReference": [
{
"id": "39194",
"name": "example"
}
]
}
]
}
EDIT1: Although the documentation doesn't refer to any "artifact version", I've found the variable through this GET call which returns a "version" under the artifacts. I've updated my Request Body with the version number as seen below but I still receive the same error.
{
"definitionId": 1,
"description": "Creating Sample release",
"artifacts": [
{
"alias": "example0",
"instanceReference": [
{
"id": "123",
"name": "example0_0"
}
],
"version": {
"id": "12345"
}
},
{
"alias": "exmaple1",
"instanceReference": [
{
"id": "1234",
"name": "example1_0"
},
{
"id": "42616",
"name": "example1_1"
},
{
"id": "42617",
"name": "example1_2"
}
],
"version": {
"id": "123456"
}
}
]
}
The REST API to create a release in TFS 2015 is as below, you could check your api:
POST http://TFS2015:8080/tfs/DefaultCollection/{teamproject}/_apis/Release/releases?api-version=2.3-preview.1
{
"definitionId":1,
"description":"",
"artifacts":[
{
"alias":"CAT0604",
"instanceReference":{
"name":"20180621.2",
"id":"57",
"sourceBranch":"$/Scrum-TFVC"
}
}
],
"isDraft":false,
"manualEnvironments":[]
}
You could also press F12 and create a release in web portal to capture the api to see which part of your api is incorrect.
Found a solution to my problem. It turns out for the Instance Reference, you need to refer to the builds not the build artifacts as one of the documentation suggests.

Hosting a custom skill to Alexa by implementing a web service

I am working on developing a web service which is used to Handling Requests Sent by Alexa and respond back with specific response in .net framework. The request body sent by Alexa to your service in JSON format like below :
{
"version": "string",
"session": {
"new": true,
"sessionId": "string",
"application": {
"applicationId": "string"
},
"attributes": {
"string": {}
},
"user": {
"userId": "string",
"accessToken": "string"
}
},
"context": {
"System": {
"application": {
"applicationId": "string"
},
"user": {
"userId": "string",
"accessToken": "string"
},
"device": {
"supportedInterfaces": {
"AudioPlayer": {}
}
}
},
"AudioPlayer": {
"token": "string",
"offsetInMilliseconds": 0,
"playerActivity": "string"
}
},
"request": {}
}
and Response Body Syntax in Json format below:
{
"version": "string",
"sessionAttributes": {
"string": object
},
"response": {
"outputSpeech": {
"type": "string",
"text": "string",
"ssml": "string"
},
"card": {
"type": "string",
"title": "string",
"content": "string",
"text": "string",
"image": {
"smallImageUrl": "string",
"largeImageUrl": "string"
}
},
"reprompt": {
"outputSpeech": {
"type": "string",
"text": "string",
"ssml": "string"
}
},
"directives": [
{
"type": "string",
"playBehavior": "string",
"audioItem": {
"stream": {
"token": "string",
"url": "string",
"offsetInMilliseconds": 0
}
}
}
],
"shouldEndSession": boolean
}
}
I researched on Amazon Developer Forum Hosting a Custom Skill as a Web Service , Handling Requests Sent by Alexabut i am not able to achieve this thing and one thing i am not using Lambda function i want to make a custom skill and my location is not in North US.
I got the Lib. from github here and used in my web service but not able to sync with this library, anyone here to give me a direction how can i do this or how can i started thanks in advance.
I've just published a project that uses the same AlexaSkillsKit.NET package that you mention. The goal is to help everyone create Alexa Custom Skills using .NET + Visual Studio that you can easily deploy to Azure.
https://github.com/tamhinsf/Azure4Alexa
There's a sample skill implementation that you can use as a pattern for your own Custom Skill. It makes use of httpClient and the usual async patterns.
Just download and fire up Visual Studio to get started!
It's been some time that the last answer was written, plus the example which Azure4Alexa sample implements, uses deprecated base classes, for cases where you might want to use the 'context' part of your Alexa request, you would want to implement SpeechletBase, ISpeechWithContext in your final Speechlet class.
To be honest, I know the README.md on AlexaSkillsKit.net is very dense, but if you do give it some time, and go through the AlexaSkillsKit.Sample project, and go through the definitions of the implemented base classes, you will understand the request handling through and through.
Let me also take this opportunity to breakdown how I understand the classes and their structures:
SampleSessionSpeechlet Class - Is just the final class that Logs your request, and implements the ISpecchletWithContext(which mandates the implementation of OnSessionStarted(), OnLaunch(), OnIntent() & OnSessionEnded()) these four functions are basically handlers of all the requests that Alexa can send to your Web Service.
SpecchletBase Class - Basically Wraps around the SpeechletService Class which actually does the all heavy lifting.
SpeechletService Class - You basically call its GetResponseAsync()(which the SpeechletSerive's GetResponse() wraps) which takes the passed Alexa Request, parses it into a cute little dataClass called SpeechletRequestEnvelope, does session management, passes the SpeechletRequestEnvelope to your your implementation of the OnSessionStarted(), OnLaunch(), OnIntent() or OnSessionEnded() methods, gets your returned objects and Returns your Alexa Response as a class called the SpeechletResponseEnvelope
Hope that helps with some quick implementation, but I highly recommend going through the Lib directory and understand how things work. And who knows? Contribute!

Categories