I have the Odata service, in order to perform a PUT we need to set the Header with If-Match: * In Post man I giving like below and it works
How do I set this If-Match in the Odata Service call to perform a PUT operation.I tried the below
private async Task<HttpResponseMessage> PutJsonAsync(string messageBody,string B_Code)
{
string userName = ConfigurationManager.AppSettings["Username"];
string password = ConfigurationManager.AppSettings["Password"];
string BaseURL = ConfigurationManager.AppSettings["BaseURL"];
try
{
using (var httpClient = new HttpClient())
{
var request = new StringContent(messageBody, Encoding.UTF8, "application/json");
string apiUrl = "SAM('" + B_Code + "')";
request.Headers.ContentType = new MediaTypeHeaderValue("application/json");
request.Headers.TryAddWithoutValidation("If-Match", "*");
var url = string.Format("{0}{1}", BaseURL, apiUrl);
var creds = userName + ":" + password;
var credentials = Encoding.ASCII.GetBytes(creds);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(credentials));
response = await httpClient.PutAsync(new Uri(url), request);
}
}
catch (Exception ex)
{
throw ex;
}
return response;
}
But it is not working and throws error 501:Not Implemented
`response {StatusCode: 501, ReasonPhrase: 'Not Implemented', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
OData-Version: 4.0
Date: Mon, 30 Oct 2017 20:42:28 GMT
Set-Cookie: JSESSIONID=XYZ; Path=/; Secure; HttpOnly
Set-Cookie: XYZ;PATH=/;SECURE;HTTPONLY
Server: Apache-Coyote/1.1
Vary: Accept-Encoding
Connection: keep-alive
Content-Length: 277
Content-Type: application/json; odata.metadata=minimal
}} System.Net.Http.HttpResponseMessage`
Your "request" object, is your content object, not the HttpRequestMessage object. How did I realise that? ContentType isn't available on the HttpRequestMessage.
If-Match is not a content-level header (I don't know why Microsoft make this distinction). You can't add it here, you have to add it to the request header. If you add it to the content object, it gets disregarded.
Something like this should work:
string apiUrl = "SAM('" + B_Code + "')";
var url = string.Format("{0}{1}", BaseURL, apiUrl);
var creds = userName + ":" + password;
var credentials = Encoding.ASCII.GetBytes(creds);
var request = new HttpRequestMessage(HttpMethod.Put, new Uri(url));
request.Content = new StringContent(messageBody, Encoding.UTF8, "application/json");
request.Headers.TryAddWithoutValidation("If-Match", "*");
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(credentials));
response = await httpClient.SendAsync(request);
Related
I am learning Xamarin forms. I am using Google Place API for searching nearby
I have managed to call the API in .NET, but I only get 20 results as it is written in the Google document.
Here is my code :
string lati = location.Latitude.ToString().Replace(",", ".");
string longi = location.Longitude.ToString().Replace(",", ".");
string latitude = lati;
string longitude = longi;
string Myradius = "3000";
var URL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?";
string urlParameters = "?location=" + latitude + "," + longitude + "&radius=" + Myradius + "&key=My_GOOGLE_KEY";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
// List data response.
HttpResponseMessage response = await client.GetAsync(urlParameters);
if (response.IsSuccessStatusCode)
{
JObject joResponse = JObject.Parse(await response.Content.ReadAsStringAsync());
JArray MyJsonResult = (JArray)joResponse["results"];
// I want to have the second page result of my API Call
string token = joResponse["next_page_token"].ToString(); // I have manage to get the token
JArray MyJsonResult2 = await GetnextPageData(latitude, longitude, Myradius, token); //no result
}
async Task<JArray> GetnextPageData(string latitude, string longitude, string Myradius , string token)
{
var URL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?";
string urlParameters = "?location=" + latitude + "," + longitude + "&radius=" + Myradius + "&key=My_GOOGLE_KEY&pagetoken=" + token;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// List data response
HttpResponseMessage response = await client.GetAsync(urlParameters);
Console.WriteLine("MyPrint " + response);
if (response.IsSuccessStatusCode)
{
JObject joResponse = JObject.Parse(await response.Content.ReadAsStringAsync());
Console.WriteLine("MyPrint " + response);
JArray MyJsonResult = (JArray)joResponse["results"];
if (MyJsonResult != null)
{
return MyJsonResult;
}
else
{
return null;
}
}
return null;
}
I have found those link but still cannot add the parameter for the rest of the result:
Obtaining more than 20 results with Google Places API
How to get 20+ result from Google Places API?
Problem: I have manage to get the token but when I put it in the parameter I get no result - MyJsonResult2 is empty.
When I print "response" for the second call I have this :
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.NSUrlSessionHandler+NSUrlSessionDataTaskStreamContent, Headers:
{
server-timing: gfet4t7; dur=30
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
Server: scaffolding
Server: on
Server: HTTPServer2
x-xss-protection: 0
Cache-Control: public, max-age=300
Date: Sun, 13 Nov 2022 02:19:16 GMT
X-Frame-Options: SAMEORIGIN
Vary: Accept-Language
Content-Type: application/json; charset=UTF-8
server-timing: gfet4t7; dur=30
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
Content-Encoding: gzip
x-xss-protection: 0
Expires: Sun, 13 Nov 2022 02:24:16 GMT
Content-Length: 86
X-Frame-Options: SAMEORIGIN
}
And when I print "joResponse" for the second call I have this :
{
"html_attributions": [],
"results": [],
"status": "INVALID_REQUEST"
}
Thanks for your help.
I have found the solution. I must add in my request the parameters :"hasNextPage=true&nextPage()=true"
I can accomplish all other tasks with the rest API, like uploading and downloading files, navigating through the file directory. I just keep getting either 400 Bad Request or sometimes with some tries I'll get 500 Internal Server Error. Also, I can create the request on postman and its successful
this is what the request should look like the rest is me creating it in c#
POST https://{site_url}/_api/web/folders
Authorization: "Bearer " + accessToken
Accept: "application/json;odata=verbose"
Content-Type: "application/json"
Content-Length: {length of request body as integer}
X-RequestDigest: "{form_digest_value}"
{
"__metadata": {
"type": "SP.Folder"
},
"ServerRelativeUrl": "/document library relative url/folder name"
}
private async Task PostFolderSharePoint(string url, string serverRelativeUrl)
{
string accessToken = GetAccessToken().GetAwaiter().GetResult();
string jsoncontent = JsonConvert.SerializeObject("{\"__metadata\": {\"type\": \"SP.Folder\"},\"ServerRelativeUrl\": serverRelativeUrl}");
var content = new StringContent(jsoncontent, Encoding.UTF8, "application/json");
var FormDiGestValue = await GetFormDigestValue(accessToken);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var requestMessage = new HttpRequestMessage(HttpMethod.Post,url) { Content = content };
requestMessage.Headers.Add("X-RequestDigest", FormDiGestValue);
HttpResponseMessage response = await _httpClient.SendAsync(requestMessage).ConfigureAwait(false);
return response;
}
This is how I create a folder with the Sharepoint REST API:
public async Task<string> CreateFolder(string folderName, string relativeUrl)
{
try
{
var url = "https://your.sharepoint.com/sites/devsite/_api/web/folders";
var json = "{\"ServerRelativeUrl\": \"" + relativeUrl + "/" + folderName + "\"}";
var payload = new StringContent(json, Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("X-User-Agent", "spoc");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
var response = await client.PostAsync(url, payload);
return await response.Content.ReadAsStringAsync();
}
catch (WebException we)
{
throw new SomethingException(we);
}
}
and to use it:
var modFolder = await spocRest.CreateFolder("MOD1", "Shared Documents");
When I run this from a browser manually, it returns a response, that looks like this:
{"value":[{"ID":4}]}
Now, I am POSTing it from a Windows IoT Device, using the following code:
private async Task SendPostRequest(string username, string password, Dictionary<string, string> parameters)
{
try
{
// using Windows.Web.Http
HttpFormUrlEncodedContent formattedData = new HttpFormUrlEncodedContent(parameters);
using (HttpBaseProtocolFilter clientHandler = new HttpBaseProtocolFilter())
{
clientHandler.ServerCredential = GetCredentials(username, password);
using (HttpClient httpClient = new HttpClient(clientHandler))
{
//txtCommand.Text = "PostAsync";
HttpResponseMessage response = await httpClient.PostAsync(postUrl, formattedData);
txtResponse.Text = response.ToString();
response.EnsureSuccessStatusCode();
string responseString = await response.Content.ReadAsStringAsync();
txtResponse.Text += " responseString: " + responseString;
}
}
The result in responseString is an empty string.
The result of response.ToString() looks like this:
StatusCode: 200, ReasonPhrase: 'OK', Version: 2, Content: Windows.Web.Http.HttpStreamContent, Headers:
{
Persistent-Auth: true
Server: Microsoft-IIS/10.0
Transfer-Encoding: chunked
Date: Fri, 27 Aug 2021 15:16:38 GMT
X-Powered-By: ASP.NET
dbgate-version: 1.0
}{
Content-Type: text/plain
}
I made an auto scheduler where data is forwarded to my AWS Server.
I created a Window Service that runs every min to forward the new data.
I have an existing API that received the data in AWS Server.
Window Service works fine with API on network server
API Address1 : http:\\192.168.0.1\api\data\getdata (Working in network 100%)
API Address2 : https:\\api.mydomain.com\api\data\getdata (Tested in winform and postman
working 100%)
But encountered a problem when window services send data to API Address 2
Here is the code
public static void SendData()
{
var PostData = new Profile
{
ID = 99,
Code = "123",
Email = 'xyz#yahoo.com'
};
try
{
var PostBody = JsonConvert.SerializeObject(PostData);
var PostContent = new StringContent(PostBody, Encoding.UTF8, "application/json");
//BaseAddress = "https:\\api.mydomain.com";
using (var Client = API_Client.GetClient("api/data/getdata"))
{
var Sending = Client.PostAsync(Client.BaseAddress.ToString(), PostContent);
Sending.Wait();
var Response = Sending.Result;
if (Response.IsSuccessStatusCode)
{
Logger.WriteLine("Sending Info to API '" + PostData.ID.ToString() + "'", "Success");
}
else
{
Logger.WriteLine("Sending Info to API '" + PostData.ID.ToString() + "'", Response.ReasonPhrase);
}
}
}
catch (Exception ex)
{
Logger.WriteLine("Error '" + PostData.ID.ToString() + "' To Server", ex.Message);
}
}
Here is Error Message
{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Pragma: no-cache
Connection: close
Cache-Control: no-cache
Date: Thu, 13 Dec 2018 06:40:34 GMT
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 41
Content-Type: application/json; charset=utf-8
Expires: -1
}}
API Client Helper
public class API_Client
{
protected static string API_BASE_ADDRESS = "https:\\api.mydomain.com\";
public static HttpClient GetClient(string URL_Target)
{
var Client = new HttpClient()
{
BaseAddress = new Uri(API_BASE_ADDRESS + URL_Target),
Timeout = new TimeSpan(0, 0, 90)
};
Client.DefaultRequestHeaders.Accept.Clear();
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Client.DefaultRequestHeaders.ConnectionClose = true;
return Client;
}
}
Postman
I'm getting a "Bad Request" when I try to create a new OneNote API Notebook.
private async Task<string> CreateSimpleNotebook(string notebookName, string apiRoute)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
}
catch (Exception ex)
{
string tempEx = ex.ToString();
}
var createMessage = new HttpRequestMessage(HttpMethod.Post, apiRoute )
{
Content = new StringContent("{ name : '" + WebUtility.UrlEncode(notebookName) + "' }", Encoding.UTF8, "application/json")
};
HttpResponseMessage response = await client.SendAsync(createMessage);
return response.Headers.Location.ToString();
}
And I call the method with the following:
string url = "https://graph.microsoft.com/v1.0/me/onenote/notebooks/";
// string url = "https://www.onenote.com/api/v1.0/me/notes/notebooks/";
string tempResponse = await CreateSimpleNotebook("EMRTest2", url);
Here is the response:
{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
client-request-id: acacd4f5-8738-4c46-8150-17aa23413eb5
request-id: acacd4f5-8738-4c46-8150-17aa23413eb5
Transfer-Encoding: chunked
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"South Central US","Slice":"SliceB","Ring":"NA","ScaleUnit":"002","Host":"AGSFE_IN_10","ADSiteName":"SAN"}}
Duration: 772.4124
Cache-Control: private
Date: Sun, 19 Nov 2017 20:59:10 GMT
Content-Type: application/json
}}
You should use Content-Type JSON
The name of the property you are looking for is not "name", it is "displayName"
Additionally, crafting JSON by appending string is not best practice - I recommend using a JSON library, like NewtonSoft JSON.NET.