POST from Form to external API - c#

I'm quite noob into asp.net
I'm building a simple solution in VS2019, using asp.net MVC, which is supposed to send a User data to another API which will be responsible for saving into database.
So far, both APIs are REST and I'm not using core
Basically, it is a form with a submit that will POST to the external project, pretty simple.
I'm following some tutorials and stuff but there are so many different ways that got me confused, so I decided to ask here
Here's what I have so far
[HttpPost]
public async ActionResult Index(User user)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://pathtoAPI.com/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
User newuser = new User()
{
email = user.email,
nome = user.nome,
cpf = user.cpf,
cnpj = user.cnpj,
userName = user.userName,
senha = user.senha,
telefone = user.telefone
};
var jsonContent = JsonConvert.SerializeObject(newuser);
var contentString = new StringContent(jsonContent, Encoding.UTF8, "application/json");
contentString.Headers.ContentType = new
MediaTypeHeaderValue("application/json");
//contentString.Headers.Add("Session-Token", session_token);
HttpResponseMessage response = await client.PostAsync("register", contentString);
return Content($"{response}");
}
I want to receive the "OK" message from the other API and just print it on my screen, I'm using the cshtml file to handle the front and the form as well.
The return though seems to be wrong, it's expecting either 'null, task, task, or something like.
Can someone please help me with this code?
Thanks

You need to return the content of the response, not the response object itself.
HttpResponseMessage response = await client.PostAsync("register", contentString);
string responseBody = await response.Content.ReadAsStringAsync();
return Content(responseBody);

Related

C# Post Variables can't be read on Website - HttpClient PostAsync()

I have a web server on which I'm hosting my own api for one of my projects.
This is the php-code of the api-website:
$user = $_POST['username'];
$password = $_POST['password'];
if(strcmp($user, "username") == 0 && strcmp($password, "password") == 0) {
...
} else {
die("No Permissions");
}
I want to send the two variables username and password with a HttpClient and the postAsync-method to this website and if the right log in data is detected, it returns the data I want.
For this I have the following code in C#:
Task<HttpResponseMessage> response;
var url = "www.url.de"; //not the url I'm actually calling!
var vars = "[{\"username\":\"username\", \"password\":\"password\"}]";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
response = client.PostAsync(url, new StringContent(vars, Encoding.UTF8));
Console.WriteLine(response.Result.Content.ReadAsStringAsync().Result);
if (response.IsCompleted)
{
Console.WriteLine(response.Result.Content.ReadAsStringAsync().Result);
}
}
But the problem is that no matter what I have tried the output from this code is, that i have no permissions. And I have changed the php-code, so that I can see which data is stored in $username and $password, but they are empty and I don't know why. I hope somebody can help me with this.
Your PHP code is expecting the data sent as application/x-www-form-urlencoded, but your C# code is sending it as JSON.
As mentioned in the comment by M. Eriksson, you either need to change your PHP to accept JSON, or change your C# to send as form data.
This answer shows how to use HTTPClient to send data like that.
Here's my modification of your code based on the above code (I did test it):
public static async Task DoSomething()
{
string url = "http://httpbin.org/post"; //not the url I'm actually calling!
Dictionary<string, string> postData = new();
postData["username"] = "username";
postData["password"] = "password";
using HttpClient client = new();
client.DefaultRequestHeaders.Accept.Add(new("application/json"));
HttpRequestMessage request = new(HttpMethod.Post, url);
request.Content = new FormUrlEncodedContent(postData);
HttpResponseMessage response = await client.SendAsync(request);
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
}

C# - Set header within HTTP POST request [duplicate]

I'm trying to add a custom header to the request header of my web application. In my web application im retrieving data from a web api, in this request i want to add a custom header which contains the string sessionID. I'm looking for a general solution so that I dont have to add the same code before every call I make.
My Controller looks like this:
[HttpGet]
public async Task<ActionResult> getCall()
{
string url = "http://localhost:51080/";
string customerApi = "customer/1";
using (var client = new HttpClient())
{
//get logged in userID
HttpContext context = System.Web.HttpContext.Current;
string sessionID = context.Session["userID"].ToString();
//Create request and add headers
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//Custom header
//Response
HttpResponseMessage response = await client.GetAsync(customerApi);
if (response.IsSuccessStatusCode)
{
string jsondata = await response.Content.ReadAsStringAsync();
return Content(jsondata, "application/json");
}
return Json(1, JsonRequestBehavior.AllowGet);
}
}
Hope anybody can help!
Thanks in advance!
Try this:
client.DefaultRequestHeaders.Add("X-Version","1");
Collection behind DefaultRequestHeaders has Add method which allows you to add whatever header you need:
client.DefaultRequestHeaders.Add("headerName", sesssionID);

C# to pause, turn on ssas server, backup cube.... how to?

I'm building some function apps in C# (via REST API) to make refreshes of tabular cube located on an azure ssas server. So far, no problem. However, I can't find a way to pause/start the ssas server (I saw some doc in powershell but I'd like to stay in C# so as not to mix languages)
Has anyone ever created anything like this?
I tried to make a POST suspend but no solution for now.
See the ResumeAzureAS() method here:
protected async Task<bool> ResumeAzureAS()
{
HttpClient client = new HttpClient();
var apiURI = new Uri(string.Format("https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.AnalysisServices/servers/{2}/resume?api-version=2016-05-16", subscriptionID, resourcegroup, server));
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
HttpResponseMessage response = await client.PostAsync(apiURI.ToString(), null);
response.EnsureSuccessStatusCode();
return true;
}
The rest of the API calls (such as suspend) are documented here.
private async Task<string> AASAcquireToken()
{
// Get auth token and add the access token to the authorization header of the request.
string authority = "https://login.windows.net/" + tenant + "/oauth/authorize";
AuthenticationContext ac = new AuthenticationContext(authority);
ClientCredential cred = new ClientCredential(clientID, keyID);
AuthenticationResult ar = await ac.AcquireTokenAsync(audience, cred);
return ar.AccessToken;
}
With audience set as "https://management.azure.com"
and for the "pause" itself :
I use as servername the complete name mention in the portal azure as "asazure://northeurope.asazure.windows...."
For the version of the api , well I don't know where to find it so I use one I found on the net.
var apiURI = new Uri(string.Format("https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.AnalysisServices/servers/{2}/suspend?api-version=2016-05-16", subscription, ressourceID, servername));
audience = "https://management.azure.com";
myClient.BaseAddress = new Uri(location);
myClient.DefaultRequestHeaders.Accept.Clear();
myClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
myClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await AASAcquireToken());
HttpResponseMessage response = await myClient.PostAsync(apiURI.ToString(), null);
var output = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode();
The right audience was :
audience = "https://management.core.windows.net/";

Using DefaultRequestHeaders sends requests twice?

I have a WebAPI that sends BASIC authorization information as following.
var client = new HttlpClient();
client.BaseAddress = new Uri(GlobalConstants.LdapUri);
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password))));
Task<HttpResponseMessage> results = client.GetAsync(GlobalConstants.FortressAPIUriDev);
var response = await results;
I've built this API using MVC Core 1.x and the receiving API is built using MVC5.
The problem is that this GetAsync sends two requests at the same time, and I have no clue how to resolve this. I've done some Googling myself to see if I can find a fix for this but so far no luck. Did anyone experience this problem and know how to resolve it?
Thank you very much in advance.
Long story short, found a solution as follows:
using (var client = new HttpClient())
{
var requestMessage = new HttpRequestMessage(HttpMethod.Get, GlobalConstants.LdapUri + GlobalConstants.FortressAPIUriDev);
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password))));
var response = await client.SendAsync(requestMessage);
}
After replacing with this code, it is sending one request at a time.
Found a hint at :
Adding headers when using httpClient.GetAsync

Xamarin Android POSTing to WebAPI

I have a WebAPI service running on a server, and I am able to hit against it all day long in an MVC app I have. I am now trying to create an Xamarin Android app that also hits against the same WebAPI. I put together some code in a console app to test, and it works just fine. However, when I put the same code in my Xamarin Android app, it cannot connect to the service, I get back an aggregate exception that basically wraps a WebException. Digging into the exception further, it seems it is a System.Net.WebExceptionStatus.ConnectFailure type of error.
Here is the code:
using (HttpClient webAPI = new HttpClient())
{
// hardcode the request to try and see why it errors
AuthUserRequest thisUser = new AuthUserRequest
{
UserName = "username",
Password = "password",
AppName = "Dashboard"
};
webAPI.MaxResponseContentBufferSize = 256000;
string json = Newtonsoft.Json.JsonConvert.SerializeObject(thisUser);
var content = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response;
try
{
response = await webAPI.PostAsync("It'sOurURL", content);
}
catch (Exception err)
{
string sHold = err.Message;
throw;
}
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
Context thisContext = Application.Context;
Toast toast = Toast.MakeText(thisContext, "Successful", ToastLength.Short);
toast.Show();
}
}
As I said it's weird it works just fine from a Console app, just not the Xamarin Android app. Any insight at all into this?
All looks pretty good. My API calls are working in Xamarin Android and iOS. My code is pretty much the same with two real minor differences. I have set ConfigureAwait(false) on the PostAsync call. Additionally I have created a URI variable with the address for the API endpoint and passed that into the PostAsync method, rather then using a hard coded string.
using (var client = new HttpClient())
{
var user = new CredentialsModel
{
Password = password,
Username = username,
};
var uri = new Uri("YOUR_URL_GOES_HERE");
var json = JsonConvert.SerializeObject(user);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(uri, content).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
var authData = JsonConvert.DeserializeObject<ResponseModel>(responseContent);
return authData;
}
return null;
}
It was my own bone-headed mistake... When I tried the URL this morning, it was there, but the IT department has been mucking about with the server, so it's no longer available externally. Sorry to bother everyone with this.

Categories