Deleting an Azure Devops Test Case with c# - c#

Azure Devops test case work items cannot be simply deleted online. They need to be "permanently deleted". And the code for deleting work items programatically does not work for test cases:
workItemTrackingClient.DeleteWorkItemAsync(witID, true).SyncResult();
The MSFT documentation says to use their Rest API - but their documentation doesn't really explain how to do it - they simply show "delete" and a url. I tried to use that url in a DELETE method rest call. (I use Restsharp for its clear syntax usually), as follows:
string adoURLBase = #"https://dev.azure.com/{OrgName}/";
string urlToUse = adoURLBase +
"ProjectName}/_apis/test/testcases/{workItemId}?api-version=7.0";
RestClient client = new RestClient(urlToUse);
RestRequest request = new RestRequest(adoURLBase, Method.Delete);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Basic " + personalAccessToken);
RestResponse response = client.Execute(request);
This failed, with a StatusCode: NotFound, and the content message: "The provided HTTP Verb is not supported on this controller.".
FYI - I also tried using the full URL ("urlToUse" above) in the "new RestRequest" instantiation. Same response. And I tried adding trhe parameter "destroy=true" as noted in MSFT's documentation. Same response.
The MSFT documentation I am looking at is at:
https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-items/delete?view=azure-devops-rest-7.0&tabs=HTTP
Appreciate any help.

You may use DeleteTestCaseAsync method of Microsoft.TeamFoundationServer.Client
using Microsoft.VisualStudio.Services.TestManagement.TestPlanning.WebApi;
.............
TestPlanHttpClient TestPlanClient = Connection.GetClient<TestPlanHttpClient>();
TestPlanClient.DeleteTestCaseAsync("YOUR_TEAM_PROJECT", TESTCASE_ID).Wait();
or use Test Cases - Delete REST API method

Related

C# RestSharp No Response From Get With Json Body

My goal is to download a file with a RestSharp GET by passing along a Json body and a security token in the header. For now, I'm just trying to get a response.
I got this code from Postman, where the GET is working (I am prompted where to save the file).
var client = new RestClient(url);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", token);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", json, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
string responseMsg = "";
if (response.Content == "")
responseMsg = response.ErrorMessage
else
responseMsg = response.Content
return responseMsg;
The only response that I'm getting is the ErrorException "HTTP verb GET does not support body".
So I believe there is an issue with my logic, not my Json or token. Does anything in my code look incorrect?
Application framework: .Net 4.8
RestSharp version: 106.15.0
Thanks.
Edit:
As mentioned below, a GET request with a body parameter is invalid. After removing the the json body, the request is now working.
var client = new RestClient(url);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", token);
IRestResponse response = client.Execute(request);
In the case of my application, the unique identifier was appended to the endpoint, so only the security token was needed as a header.
GET requests cannot have bodies, or rather, they can, but that behaviour is not defined and so some implementations will reject the request entirely. It appears that RestSharp also intentionally does not support GET requests with bodies for the same reason. According to that thread, .NET itself may support them, so you might wish to try that if it's absolutely necessary.
Whether or not you should do that might come under the umbrella of personal opinion, however with that in mind I would caution against doing things outside of the specification, because any updates to libraries or frameworks have no guarantee of consistency of behaviour when they're being used out of spec. If this is an API you have control over, you should consider bringing it in-spec. If it's not, you should consider contacting the developer to have them look into it.

ADFS v4.0 and /userinfo endpoint giving 405

Integrating older ASP.NET server-side application into ADFS for authentication, which means I pretty much had to write everything from scratch. have everything working (/authorize, /token) up until the /userinfo call.
My code, in a nutshell -
HttpClient client = new HttpClient();
var req = new HttpRequestMessage {
RequestUri = new Url("https://<server_ip>/adfs/oauth2/userinfo"),
Method = HttpMethod.Get,
};
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
req.Headers.UserAgent.Clear();
req.Headers.UserAgent.Add(new ProductInfoHeaderValue("OldApp", "11.3.0"));
var result = await client.SendAsync(req);
The result is a HTTP error 405 - Method Not Allowed. Doing searches online, I see this as a common issue when the trailing "/" is left off the url, but I get the same result with a trailing slash.
After poking around, there are a lot of examples that use newer libraries and such that I can't use, sadly. None mention usage of the /userinfo, and I'm thinking that the issue isn't necessarily in how I'm calling the URL, but configuration of the 'Application Group' in ADFS.
Okay - I found the issue, and will document it here in case others come across the same thing..
While I am not sure why /userinfo is giving a 405 - the URL I was using is wrong, despite it being listed in the Endpoints folder. There shouldn't be any "oauth2" in the URL. The correct code (and URL) is:
var req = new HttpRequestMessage {
RequestUri = new Url("https://<server_ip>/adfs/userinfo"),
Method = HttpMethod.Get,
};
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
req.Headers.UserAgent.Clear();
req.Headers.UserAgent.Add(new ProductInfoHeaderValue("OldApp", "11.3.0"));
var result = await client.SendAsync(req);
Also something to keep in mind - this has been stated elsewhere, but not as clearly as here, I hope:
The /userinfo will ONLY give you the NameIdentifier ("sub") claim. (As far as I can see.) No matter what scope you pass it. You will get all your information (that should normally be in the /userinfo call) in the "id_token" parameter from you /token call, encoded as JWT.
Personally I was led to do the same thing as you, the only solution was to download the ADAL library (You will find the link below) and debug the code in order to re-produce the same HTTP stream from ADAL.
You can create a new project so that you can integrate ADAL, for debugging or else intercepting the HTTP stream
Link ADAL

HTTP Request works in postman but doesn't work in code

I'm trying to access a website that requires login via a form.
I used the Postman HTTP client.
I tried to do the normally http post request but didn't seem to work, I get a successful status code (200 OK) but it doesn't log in, eventually did work with a GET request with BODY parameters (I hadn't seen GET request with body parameters).
Well, I tried to simulate this request in C# code with no luck, I even tried the generated code that Postman offers with no luck again.
Down below is the Postman request and the C# code snippet based on auto-generated Postman code. Does anyone know if is there to make this request with any library or if there is something that I miss?
Thank you in advance.
var client = new RestClient("https://thessalia-3.teilar.gr/login.asp");
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Referer", "https://thessalia-3.teilar.gr/login.asp");
var parameters = new Dictionary<string, string>();
parameters["userName"] = JsonConvert.SerializeObject("myusername");
parameters["pwd"] = JsonConvert.SerializeObject("mypass");
parameters["loginTrue"] = JsonConvert.SerializeObject("extravalue");
var content = new FormUrlEncodedContent(parameters);
request.AddParameter("application/x-www-form-urlencoded", content);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Console.WriteLine(response.StatusCode);
Postman Request Photo
Edit:
Postman Request Body Parameters
I've also tried to run this but also not logged in.
Auto-generated code form Postman
If the request was successful (200) and you got the HTML page for "Invalid Credentials", then your code that's making the request should be fine and the issue is with the credentials. Like I said in my first comment, don't serialize the parameters to JSON, URL-encode them instead:
parameters["userName"] = HttpUtility.UrlEncode("myusername");
parameters["pwd"] = HttpUtility.UrlEncode("mypass");
parameters["loginTrue"] = HttpUtility.UrlEncode("extravalue");
This is the standard way and it works with writing the parameters directly to the request stream, or with a utility class like StringContent. However, since you're using the utility class FormUrlEncodedContent, it URL-encode them for you, so you don't have to. In that case, simply assign them directly as string:
parameters["userName"] = "myusername";
parameters["pwd"] = "mypass";
parameters["loginTrue"] = "extravalue";

Yelp Fusion API v3 returns 401 Unauthorized with TOKEN_MISSING error when called from c#

I've created my app in Yelp, got my api key, and things work fine from Postman when executing a business search.
However, when testing from c#, I receive a 401 unauthorized error with a TOKEN_MISSING error that says ""{\"error\": {\"code\": \"TOKEN_MISSING\", \"description\": \"An access token must be supplied in order to use this endpoint.\"}}"".
I'm supplying my api key correctly though, and the Yelp documentation says that's all I need, so I'm not sure what the problem is. Here are 2 separate c# code samples that do NOT work (I've replaced my actual api key with for security concerns):
Example using WebRequest:
var webRequest = WebRequest.Create("http://api.yelp.com/v3/businesses/search?term=Clayton+Bicycle+Center&location=5411+Clayton+Rd%2c+Clayton%2c+CA+94517%2c+US");
webRequest.Method = "GET";
webRequest.Headers.Add("Cache-Control", "no-cache");
webRequest.Headers.Add("Authorization", "Bearer <my_api_key>");
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
var stream = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8);
var content = stream.ReadToEnd();
Console.Write(content);
Example using RestSharp:
var client = new RestClient("http://api.yelp.com/v3/businesses/search?term=Clayton+Bicycle+Center&location=5411+Clayton+Rd%2c+Clayton%2c+CA+94517%2c+US");
var request = new RestRequest(Method.GET);
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("Authorization", "Bearer <my_api_key>");
var response = client.Execute(request);
Console.Write(response.Content);
I've examined the requests in Fiddler, and both are sending the same headers as the working Postman search, but both return 401 unauthorized error while Postman returns the search results. Any ideas?
Edit:
Well this is embarrassing, apparently my issue was I was attempting to access the Yelp API via http instead of https. Once I changed to https, everything worked as expected.
Changed endpoint to use https instead of http, works now.

Desk.com and RestSharp (oAuth)

This feels like it should be easy but...it's not. It definitely doesn't help that there's no library for Desk.com, and the documentation is (in my opinion) extremely thin and lacking.
Anyway, I'm trying to use RestSharp to do something simple: grab recent cases. I'm using the Single Access Token method as we don't need to interact as any of our users.
Here's the code:
var client = new RestClient();
client.Authenticator = RestSharp.Authenticators.OAuth1Authenticator.ForProtectedResource("key","secret","token","token secret");
client.BaseUrl = "http://xxx.desk.com/api/v1/";
var request = new RestRequest();
request.Method = Method.GET;
request.Resource = "cases.json?count=10&status=new";
request.RequestFormat = DataFormat.Json;
var result = client.Execute(request);
Result always just says the auth request was invalid and is unauthorized. Tried a bunch of different combinations, looked through the tests that are part of the RestSharp library, and read every meager word of the Desk.com documentation. Just not sure what to try next.
You may have figured this out already, but you get that unauthorized message when you try to add the querystring to the RestRequest's Resource.
I was having the same problem. Daniel's "account/verify_credentials.json" worked for me too, so that's when I started to wonder if it had something to do with the querystring.
var request = new RestRequest();
request.Method = Method.GET;
request.Resource = "cases.json";
request.RequestFormat = DataFormat.Json;
request.AddParameter("count", 10);
request.AddParameter("status", "new");
I just wanted to say, that after following a lot of examples on making the Desk API work with C#, yours was actually the only one that did work.
I did not test with the resource you specified above, but used your code together with the "account/verify_credentials.json" resource. It returns an OK response for me, so your code works. So, first of all...thank you :)
Second (sorry if I am stating the obvious), I assume that you do not use the ("key", "secret", "token", "token secret") parameters as you specified them here, but use valid ones. You most probably do, but mayyybe there is a small chance that you may have found and copied that piece of code from somewhere else, and perhaps missed filling in your info.
EDIT: Since my first answer, I have put together a small (really small) SDK that can be used to connect to and work with the API in C#. You can grab the source code here: http://danielsaidi.github.com/desk-csharp-sdk/
Hope you get it to work.

Categories

Resources