Hot to put with httpclient? Rest(ish) API - c#

I'm working with the pipedrive API and trying to update a record (deal, but the endpoint isn't important). The format of the is as follows.
https://companyDomain.pipedrive.com/api/v1/deals/DealID?api_token=API-Token
Where companydomain specifies your account with them, dealID is the ID we're updating and API token is the token supplied by pipedrive to access the API. It's not a token that's returned by logging in, it's static one, given on day one and never changes.
HttpClient seems to want a base address so "https://companyDomain.pipedrive.com/", then something like the following:
HttpResponseMessage response = await client.PutAsJsonAsync(
$"api/v1/deals/{dealId}/", args);
Where args is a class with the field/s and value/s I want to update.
If I include the api_token as fields in "args", it returns a 404 not found. If I append it to the base url or the $api/v1/deals/{dealID}/ it returns permission denied.
Any suggestions as to how I can handle this?
I've managed to make a living coding for 30 years avoiding the web, now it's all anyone seems to want. Appears I have to finally get a handle on this, hence the recent questions! ;-)
Thanks in advance
Jim

Append it with a "?"
So your URL should look like api/v1/deals/YOUR_ID?api_token=THE_TOKEN
HttpResponseMessage response = await client.PutAsJsonAsync(
$"api/v1/deals/{dealId}?api_token={apiToken}", args);

Related

Pass parameters to Get request on swiftUI

I'm having trouble with passing in parameters to a get request. This request is intended to return a list of warehouses after the user entered some search parameters such as Date, State, ZIP and/or warehouse number, which is the only mandatory field. So when the search button is pressed the query is executed, but im getting this error:
2021-04-19 15:49:00 +0000
2021-11-02 13:06:44.670511-0600 WAREHOUSE_IOS-Master[3142:186324] GET method must not have a body
2021-11-02 13:06:44.670799-0600 WAREHOUSE_iOS-Master[3142:186324] Task <C7839029-C527-490E-8747-137012285F14>.<3> finished with error [-1103] Error Domain=NSURLErrorDomain Code=-1103 "resource exceeds maximum size" UserInfo={NSLocalizedDescription=resource exceeds maximum size,
error: invalidResponse
Okay so what im doing is passing a body to the get request that includes the search parameters as such:
struct WarehouseBody : Codable {
let dateRegistration : String?
let state : String?
let zip : String?
let warehouseNumber : String
}
and I'm expecting a response of this type:
struct WareHouseResponse: Codable {
let status: String?
let code: Int?
let responseCode, message: String?
let error: Bool?
let errorMessage: String?
let result: Result?
enum CodingKeys: String, CodingKey {
case status = "Status"
case code = "Code"
case responseCode = "ResponseCode"
case message = "Message"
case error = "Error"
case errorMessage = "ErrorMessage"
case result = "Result"
}
}
but according to what I've reading on other posts this is not the correct way of using a get request, but I really really need to do some testing. Is there a way that I can achieve this without needing to alter the backend? Just to mention that I ´m also the developer of the backend (c# using .net framework and dapper)so if the easiest way is to achieve this is by altering it I can also do that. Any ideas are very much appreciated.
On the backend I was thinking of implementing a post Request that sends the search parameters to the server and then a get request that pulls out the requested information, but I don't know if that's the correct approach. But this not feasible at the moment because the Web API are already publish and I cannot re publish with the changes at the moment, and is really urgent to test the response so that's why I would like to know if all this can be done from the front end first. Thank you very much for all the help!
Thank you very much for your help!
EDIT: Also I forgot to mention that the api has been previously tested on POSTMAN and is working perfectly.
Since iOS 13. you cannot pass in parameters to a GET request. There’s no easy way around this. You need to change your request from a GET to a POST on the backend. In my case, this was an easy task because I had access to the API source— but, if you don’t, just ask the backend team to change it, and pass in the parameters as in any other POST request. That should work.

CreateCheckStatusResponse Durable Functions attach Data

I have an Durable Azure Function and I was hoping to add data to the response. Just one field really. I cant seem to find any possible way to do it and this is where I am basically leaving off on code wise. I thought about maybe adding to the request a deliminating character but that just adds to the entirety of the string for the urls.
So my question is: Is there a way for me to append a value to the CreateCheckStatusResponse so that way I can have an Id of the object instead of polling against the url for that response?
string instanceId = await starter.StartNewAsync("SendCorrespondence", request);
var correspondenceId = Guid.NewGuid().ToString();
req.HttpContext.Items.Add("correspondenceId", correspondenceId);
req.Headers.Add("correspondenceId", correspondenceId);
var test = starter.CreateCheckStatusResponse(req, instanceId+"."+correspondenceId);
return test;
We can add the object id to the URL in the HttpStart Class and the durable client by default polls the URL in the location header if the function is in Async operation.
To add the object id, this Microsoft documentation may helps you

Web Service capture Response

My web service calls a url which returns a value which I must capture and use in a different function.
I've only recently starting working with web services and am very new to the concept of calling a url within a web service (Previously asked and answered on this forum for those requiring more information)
Webservice method to call a url
My web service is: Insurance Service.
My client sends me data through the Insurance service which calls a url which returns an Insurance Number.
How do I capture this insurance number? I thought I could use session to capture it but I was so wrong insurance Number comes as null with an object reference error.
int insuranceNo;
insuranceNo = Convert.ToInt16(HttpContext.Current.Session["insuranceNo"]);
It must have something to do with response right?
I thought I could try google what I am looking for but I honestly don't know what to call this in order to search for it. Thought I'd give it another shot in this forum since I found the answer to the first part of this function here.
code to call url:
string url = string.Format("www.insuranceini.com/insurance.asp?fileno1={0},&txtfileno2={1‌​}&username={2}&userid={3}&dteinsured={4}&dteDob={5}&InsurerName={6}", txtfileno1, txtfileno2, username, userid, dteinsured,dteDob,InsurerName)
WebRequest request = HttpWebRequest.Create(url);
using(WebResponse response = request.GetResponse())
{
using(StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string urlText = reader.ReadToEnd();
//Do whatever you need to do
}
}
I would be grateful for any sort of pointers or places to start looking or any advice.
Code began giving different errors. Closing this and referring to : Datetime Conversion and Parsing
Thank you everyone for the helpful comments.

Creating Facebook Event in C# Returns #100 Invalid Parameter

I'm trying to put together a small app that will allow me to create events in Facebook. I've already got my Facebook app set up and have successfully tested a post to my feed through the application using the code below.
wc.UploadString("https://graph.facebook.com/me/feed", "access_token=" + AccessToken + "&message=" + Message);
When I try to take things to the next step, I've just hit a brick wall.
The code that I've written is here:
JavaScriptSerializer ser = new JavaScriptSerializer();
wc.UploadString("https://graph.facebook.com/me/events?" + "access_token=" + AccessToken, ser.Serialize(rawevent));
rawevent is a small object I wrote that puts together the elements of an event so I can pass it around my application.
I'm using a similar method using ser.Deserialize to parse the user data coming back from Facebook, so I believe this should work the other way too.
Setting the above code aside for a moment, I also have tried simply putting plain text in there in various formats and with differing levels of parameters, and nothing seems to work.
Is there something wrong with the way I'm approaching this? I've read over everything I could get my hands on, and very few of the samples out there that I could find deal with creating events, and when they do, they're not in C#.
I would appreciate any help on this. If you even just have a clean copy of JSON code that I can look at and see where mine should be tweaked I would appreciate it.
I have included a copy of what the ser.Serialize(rawevent) call produces below:
{"name":"Dev party!","start_time":"1308360696.86778","end_time":"1310952696.86778","location":"my house!"}
EDIT:
thanks to bronsoja below, I used the code below to successfully post an event to Facebook!
System.Collections.Specialized.NameValueCollection nvctest = new System.Collections.Specialized.NameValueCollection();
nvctest.Add("name", "test");
nvctest.Add("start_time", "1272718027");
nvctest.Add("end_time", "1272718027");
nvctest.Add("location", "myhouse");
wc.UploadValues("https://graph.facebook.com/me/events?" + "access_token=" + AccessToken, nvctest);
All the posting examples in the graph api examples in FB docs show using curl -F, which indicates values be POSTed as normal form data. Just key value pair like you did in your first example.
The error is likely due to sending JSON. If you are using WebClient you may be able to simply create a NameValueCollection with your data and use WebClient.UploadValues to send the request.
I've recently found that Facebook returns (#100) Invalid parameter when we are trying to post data when there is already a record on file with the same name. So for example, if you are creating a FriendList via the API, and the name is "foo", submitting another identical request for the same name will immediately return that error.
In testing events you probably deleted the "Dev party!" event after each test, or maybe changing the time since you don't want two events to collide. But I'm wondering if you duplicated your wc.UploadValues(...) statement just as a test if you would see that error again. You're either deleting your 'test' event or maybe changing names and didn't notice that two events with the same name might return the error.
What's really bad here is that the error comes back as a OAuthException, which seems very wrong. This isn't a matter of authentication or authorization, it's purely a data issue.
Facebook Engineers, if I'm right about how this works, it's a bug to return this error under these conditions, and this forum has many examples of related confusion. Please return more appropriate errors.

Consuming a void service operation in a WCF data service

from a Wcf data service client (inherited from System.Data.Services.Client.DataServiceContext) I would like to invoke a service operation defined on a Wcf Data Service that returns void
[WebGet]
public void Operation()
{
// logic
}
The only reasonable method I found is the Execute, but how could I use it with a void operation?
Thank you
You can use just plain HttpWebRequest to do this. I think it will need to be POST service operation (as GET would assume some response, but since you declare it as void it would have no response). In which case Execute can't be used anyway (as it always issues a GET request).
Using plain HttpWebRequest just issue a simple POST to the service operation URL and just check the response status code (should be 204 No Content).
Currently WCF Data Services doesn't have native client support for service operations, so you need to write one for yourself.
I have found a workaround for this problem.
This website solved me quite a few problems before, so I thought it would be nice to share back.
The quick answer to your question is:
string empty = context.Execute<string>(new Uri("Operation", UriKind.Relative)).FirstOrDefault();
The "empty" string should be null or empty upon response. It "works around" the HttpWebRequest method mentioned on the post above.
Further more, it is also possible to get primitive types back using this technique.
Lets say I have this Method:
[WebGet]
public bool Authenticate(string Username, string Password)
{...do stuff here...}
When you try the normal execution it fails (Vitek Karas explains it well in his reponse above):
var query = context.CreateQuery<bool>("Authenticate").AddQueryOption("Username", "'itye'").AddQueryOption("Password","'123456'");
DataServiceCollection<bool> list = new DataServiceCollection<bool>();
list.Load(query);
But the following will do the trick:
var query = context.CreateQuery<bool>("Authenticate").AddQueryOption("Username", "'itye'").AddQueryOption("Password","'123456'");
bool authenticated = context.Execute<bool>(new Uri(query.RequestUri.ToString().Replace("Authenticate()", "Authenticate"))).FirstOrDefault();
Please note the Replace("Authenticate()", "Authenticate"), which omits () from the query string (otherwise it will cause error).
Hope it helps.
- Itye
Thanks Itye
I was looking for similar solution. Did using HttpWebRequest way first. But your two lines of code helped me doing the same task. Very Happy. Thanks Once Again..
var query = context.CreateQuery("Authenticate").AddQueryOption("Username", "'itye'").AddQueryOption("Password","'123456'");
bool authenticated = context.Execute(new Uri(query.RequestUri.ToString().Replace("Authenticate()", "Authenticate"))).FirstOrDefault();

Categories

Resources