Unable to send string as HTTPContent - c#

I have created an API, which shall have the capability to connect to en external API via POST and with a request body in form of a string.
I am able to connect directly to the API from Postman without trouble.. But it does not work via my own API.
Any ideas?
This is the Pastebin.
private string EncodeExternalApiLink = "https://blabla.dk";
private string EncodeExternalApiLinkPostFilter = "searchstring/blabla/api/search";
[HttpPost("getdata/filtered")]
public async Task<IActionResult> GetDataFromExternalFiltered([FromBody] string filter)
{
var filterString = new StringContent(filter);
EncodeExternalToken token = GetExternalToken().Result;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(EncodeExternalApiLink);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.access_token);
using (var response = await client.PostAsync(EncodeExternalApiLinkPostFilter, filterString))
{
return Json(response);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
return Content(content, "application/json");
}
else
{
return NotFound();
}
}
}
}

Salutations. You might need to add a "/" to the end of your base address EncodeExternalApiLink or to the beginning of EncodeExternalApiLinkPostFilter.

Related

sending headrs to web API from winForm client

i have a simple demo winform app and im trying to make a post request with header to web api.
i received access token and refreash token form the server and i stored that in text file.
and im trying to make a post request by sending the refreash token with the body and sending the access token with the header but i dont know how to include the header with the post request.
this my post method
public static async Task<string> sendMessage(string name, string contents)
{
using (HttpClient client = new HttpClient())
{
//reading the access token and refreash token from file
StreamReader sr = new StreamReader(#"C:\Users\noorm\Desktop\noor.txt");
string accessToken, refreashToken;
accessToken = sr.ReadLine();
refreashToken = sr.ReadLine();
//defining new instance of message opject
var newMessage = new messages()
{
name = name,
content = contents,
refreashToken = refreashToken
};
//sening the opject using post async and returning the response
var newPostJson = JsonConvert.SerializeObject(newMessage);
var payLoad = new StringContent(newPostJson, Encoding.UTF8, "application/json");
using (HttpResponseMessage res = await client.PostAsync(baseURL + "/messages", payLoad))
{
using (HttpContent content = res.Content)
{
string data = await content.ReadAsStringAsync();
if (data != null)
{
return data;
}
}
}
}
return string.Empty;
}
and this is the button
private async void btnSend_Click(object sender, EventArgs e)
{
var responce = await restHelper.sendMessage(txtName.Text.Trim(),txtContent.Text.Trim());
rtxt.Text = responce;
}
You can try something like the following:
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Your Oauth token");
this is how i was able to send the access token with the header
client.DefaultRequestHeaders.Add("x-auth-token", accessToken);

How to pass request content with HttpClient GetAsync method in c#

How do I pass request content in the HttpClient.GetAsync method? I need to fetch data depending upon request content.
[HttpGet]
public async Task<HttpResponseMessage> QuickSearch()
{
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
HttpResponseMessage response =await client.GetAsync("http://localhost:8080/document/quicksearch");
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
If you are using .NET Core, the standard HttpClient can do this out-of-the-box. For example, to send a GET request with a JSON body:
HttpClient client = ...
...
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("some url"),
Content = new StringContent("some json", Encoding.UTF8, ContentType.Json),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
If you want to send content, then you need to send it as query string (According to your API route)
HttpResponseMessage response =await client.GetAsync("http://localhost:8080/document/quicksearch/paramname=<dynamicName>&paramValue=<dynamicValue>");
And in API check for "paramName" and "paramValue"
this works for me:
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("your url"),
Content = new StringContent("your json", Encoding.UTF8, ContentType.Json),
};
using (var response = await httpClient.SendAsync(request))
{
string apiResponse = await response.Content.ReadAsStringAsync();
}
}
EDITED:
This is minor different then #SonaliJain answer above:
MediaTypeNames.Application.Json instead of ContentType.Json
I'm assuming that your "request content" would be POST data, no?
If you're sending it using the standard form content way of doing it, you would first have to build the content:
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", "theperplexedone"),
new KeyValuePair<string, string>("password", "mypassword123"),
});
And then submit it using PostAsync instead:
var response = await client.PostAsync("http://localhost:8080/document/quicksearch", content);
Hi all thank you for your comments, i got the solution
[HttpGet]
public async Task<HttpResponseMessage> QuickSearch(HttpRequestMessage Query)
{
Debugger.Launch();
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
Console.WriteLine(Query);
HttpResponseMessage response = await client.GetAsync("http://localhost:8080/document/quicksearch/"+ Query.RequestUri.Query);
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
else
{
Console.Write("Failure");
}
return response;
}
}
catch (Exception e)
{
throw e;
}

Can't make Post requests to Web API

So I've looked around for an answer for this but nothing I've found even comes close to solving it.
I'm trying to set up a Post method on my Web API but no matter what I do it just gives me an internal server error.
I've tried adding [FromBody] (it's a simple type).
HttpClient client {get;set;}
public APICall()
{
client = new HttpClient
{
BaseAddress = new Uri("http://localhost:1472/api/")
};
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-protobuf"));
}
public void PostTimeTaken(long timeTaken)
{
var response = client.PostAsJsonAsync("Logging", timeTaken).Result;
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.ReasonPhrase);
}
}
and then my controller action looks like this:
public void Post([FromBody] long timeTaken)
{
_api.DataBuilder.NumberOfAPICalls += 1;
_api.DataBuilder.ResponseTimes.Add(timeTaken);
}
I get no error message that could actually explain what's going on, just "Internal server error"
------SOLVED-------
Just in case anyone stumbles across this looking for the same answer, the issue was I was sending the data to the server in an incorrect format, it needed to be ProtoBuf serialised first, code snippet for anyone it might help:
public void PostToAPI(int ThingToSend)
{
using (var stream = new MemoryStream())
{
// serialize to stream
Serializer.Serialize(stream, ThingToSend);
stream.Seek(0, SeekOrigin.Begin);
// send data via HTTP
StreamContent streamContent = new StreamContent(stream);
streamContent.Headers.Add("Content-Type", "application/x-protobuf");
var response = client.PostAsync("Logging", streamContent);
Console.WriteLine(response.Result.IsSuccessStatusCode);
}
}
using (var client = new HttpClient())
{
string url = "http://localhost:7936";
client.BaseAddress = new Uri(url);
var jsonString = JsonConvert.SerializeObject(contentValue);
var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
var result = await client.PostAsync("/Api/Logger/PostActionLog", content);
string resultContent = await result.Content.ReadAsStringAsync();
}
Have you tried to convert
long timeTaken to A model like;
public class TimeModel {
public long TimeTaken {get;set;}
}
public void Post([FromBody] TimeModel time){
// Do Stuff
}
Here the code of creating a simple server
baseUrl = "http://localhost:1472/"; // change based on your domain setting
using (WebApp.Start<StartUp>(url: baseUrl))
{
HttpClient client = new HttpClient();
var resp = client.GetAsync(baseUrl).Result;
}
Here some changes in your code
var requestData = new List<KeyValuePair<string, string>> // here
{
new KeyValuePair<string, string>( "Logging",timeTaken),
};
Console.WriteLine("request data : " + requestData);
FormUrlEncodedContent requestBody = newFormUrlEncodedContent(requestData);
var request = await client.PostAsync("here pass another server API", requestBody);
var response = await request.Content.ReadAsStringAsync();
Console.WriteLine("link response : " + response);
Pls add your controller
[HttpPost] // OWIN - Open Web Interface for .NET
public HttpResponseMessage Post([FromBody] long timeTaken)
{
_api.DataBuilder.NumberOfAPICalls += 1;
_api.DataBuilder.ResponseTimes.Add(timeTaken);
return Request.CreateResponse(HttpStatusCode.OK); //Using Post Method
}

Executing POST request for Microsoft Graph API to add members to an AD group

I am trying to add members to an AD groups invoking Microsoft Graph API through an Azure Function
It is very easy and straightforward to execute GET requests through Graph API's, but I can't find any examples how I could execute post requests for the Graph API
I do have an example of a post request for the Graph API which is
POST https://graph.microsoft.com/v1.0/groups/{id}/members/$ref
Content-type: application/json
Content-length: 30
{
"#odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/{id}"
}
Here is the code I successfully use to retrieve the Graph response
public static async Task<HttpResponseMessage> GetDirectoryUsers(string graphToken, TraceWriter log, string displayName)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", graphToken);
string requestUrl = "https://graph.microsoft.com/v1.0/groups?$top=2&$filter=displayName eq '" + displayName + "'&$expand=Members";
var request = new HttpRequestMessage(new HttpMethod("GET"), requestUrl);
var response = await client.SendAsync(request);
return response;
}
However, I am completely lost how I could execute the request through a C# code within the Azure function to ADD the retrieved users to another AD. How can construct the request URL? How should I handle the odata id within that request URL?
If anyone could help me in any way, I would greatly appreciate it
A reuse method for add sub-group/member to group(O365 doesn't support add sub-group to group now)
/// <param name="graphClient"></param>
/// <param name="groupId"></param>
/// <param name="memberId">memberId/sub-group id</param>
/// <returns></returns>
public static async Task AddGroupMember1(GraphServiceClient
graphClient, string groupId, string memberId)
{
User memberToAdd = new User { Id = memberId };
//Group memberToAdd= new Group { Id = memberId };
await graphClient.Groups[groupId].Members.References.Request().AddAsync(memberToAdd);
}
Here is the answer that worked for me
public static async Task<string> AddGroupMember(string accessToken, string groupId, string memberId)
{
var status = string.Empty;
try
{
string endpoint = "https://graph.microsoft.com/v1.0/groups/" + groupId + "/members/$ref";
string queryParameter = "";
// pass body data
var keyOdataId = "#odata.id";
var valueODataId = "https://graph.microsoft.com/v1.0/directoryObjects/" + memberId;
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>(keyOdataId, valueODataId)
};
var jsonData = $#"{{ ""{keyOdataId}"": ""{valueODataId}"" }}";
var body = new StringContent(jsonData, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Post, endpoint + queryParameter))
{
request.Content = body;
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
using (var response = await client.SendAsync(request))
{
if (response.StatusCode == HttpStatusCode.NoContent)
status = "Member added to Group";
else
status = $"Unable to add Member to Group: {response.StatusCode}";
}
}
}
}
catch (Exception ex)
{
status = $"Error adding Member to Group: {ex.Message}";
}
return status;
}
I'm using graph api for sending email. The code in below
public async Task<dynamic> SendMail(string accessToken, MailWrapper mail)
{
try
{
GraphServiceClient graphClient = SDKHelper.GetMicrosoftAuthenticatedClient(accessToken);
Message message = await BuildEmailMessage(graphClient, mail);
await graphClient.Me.SendMail(message, true).Request().PostAsync(CancellationToken.None);
var response = await graphClient.Me.MailFolders.SentItems.Messages.Request()
.OrderBy(sendDateTimeDesc)
.Top(1)
.GetAsync();
return await Task.FromResult(response);
}
catch (ServiceException ex)
{
throw ex;
}
}
Assembly Microsoft.Graph, Version=1.9.0.0
That's what worked for me
public void AddUserToGroup(string groupId)
{
var requestUri = $"{_graphApiUrl}/v1.0/groups/{groupId}/members/$ref";
var id = "user_id";
var OdataId = "#odata.id";
var ODataValue = $"https://graph.microsoft.com/v1.0/users/{id}";
var content = $#"{{ ""{OdataId}"": ""{ODataValue}"" }}";
using (var httpClient = new HttpClient())
using (var httpRequest = CreateHttpRequest(HttpMethod.Post, requestUri, content))
{
var response = httpClient.SendAsync(httpRequest).GetAwaiter().GetResult();
if (!response.IsSuccessStatusCode)
{
var reason = $"Status code: {(int)response.StatusCode}, Reason: {response.StatusCode}";
throw new Exception(reason);
}
}
}
And important thing was when creating a request to use:
request.Content = new StringContent(content, Encoding.UTF8, "application/json");
it didn't work with:
request.Content = new StringContent(content);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json;odata=verbose");

POST Request UWP

I writing UWP app.
I need to send POST request with json to server
Here is my code for downloading JSON and writing to value:
public async void AllOrders_down()
{
string url = "http://api.simplegames.com.ua/index.php/?wc_orders=all_orders";
var json = await FetchAsync(url);
List<RootObject> rootObjectData = JsonConvert.DeserializeObject<List<RootObject>>(json);
OrdersList = new List<RootObject>(rootObjectData);
}
public async Task<string> FetchAsync(string url)
{
string jsonString;
using (var httpClient = new System.Net.Http.HttpClient())
{
var stream = await httpClient.GetStreamAsync(url);
StreamReader reader = new StreamReader(stream);
jsonString = reader.ReadToEnd();
}
return jsonString;
}
How I need to send POST request with this json to server?
Thank's for help.
Here is an example Post request that I have used in a UWP application.
using (HttpClient httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(#"http://test.com/");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("utf-8"));
string endpoint = #"/api/testendpoint";
try
{
HttpContent content = new StringContent(JsonConvert.SerializeObject(yourPocoHere), Encoding.UTF8, "application/json");
HttpResponseMessage response = await httpClient.PostAsync(endpoint, content);
if (response.IsSuccessStatusCode)
{
string jsonResponse = await response.Content.ReadAsStringAsync();
//do something with json response here
}
}
catch (Exception)
{
//Could not connect to server
//Use more specific exception handling, this is just an example
}
}
You should be using httpClient.PostAsync().

Categories

Resources