How to call a POST-action in a API-controller? - c#

I don't know how send values strings or models to a HttpPost-action
I want to send a value to a HttpPost-action in a API.
He reach the HttpPost-action. But the value of parameter name is NULL.
What do I wrong?
By example the value of "name" = "Netherlands".
public async Task<long> UpdateCountry(string name)
{
string url = $"{myApi}/Address/UpdateCountry";
var model = JsonConvert.SerializeObject(new KeyValuePair<string, string>("name", name));
long id = await Post(url, model);
return id;
}
than the process starts in the BaseClass... in the function Post.
protected async Task<dynamic> Post(string url, string data)
{
var client = new HttpClient();
var httpContent = new StringContent(data);
HttpResponseMessage responseMessage = await client.PostAsync(url, httpContent);
var result = await responseMessage.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<dynamic>(result);
}
And in the API the value of parameter name is NULL.
[HttpPost("UpdateCountry")]
public async Task<long> UpdateCountry(string name)
{
var countryId = _countryService.GetIdByName(name);
if (countryId == null)
{
var dto = new CountryDto() { Name = name };
....
countryId = await _countryService.Insert(dto);
}
else
{
dto.Name = name;
countryId = await _countryService.Update(dto);
}
return countryId.Value;
}

in the Client
public async Task<long> UpdateCountry(string name)
{
string url = $"{myApi}/Address/UpdateCountry";
var json = JsonConvert.SerializeObject(name);
long id = await Post(url, json, "text/json"); // or "application/json" when you use a model.
return id;
}
... and the BaseClass
protected async Task<dynamic> Post(string url, string data, string mediaType)
{
var client = new HttpClient();
var content = new StringContent(data, Encoding.UTF8, mediaType);
var response = await client.PostAsync(url, content);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<dynamic>(result);
}
return null;
}
... and in the API
[HttpPost("UpdateCountry")]
public async Task<long> UpdateCountry([FromBody] string name)
{
var countryId = _countryService.GetIdByName(name);
if (!countryId.HasValue)
{
var dto = new CountryDto() { Name = name };
....
countryId = await _countryService.Insert(dto);
}
else
{
....
dto.Name = name;
countryId = await _countryService.Update(dto);
}
return countryId.Value;
}

Related

Empty respond when Post data in C#

when I post username and password and IP address I got only an empty response.
my C# code is:
public async void APILogin(string user, string pass, string ip)
{
var person = new Userinfo { username = user, password = pass, ip = ip };
var json = JsonConvert.SerializeObject(person);
var data = new StringContent(json, Encoding.UTF8, "application/x-www-form-urlencoded");
var url = new Uri("http://localhost/login/dblogin.php") ;
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync(url,content:data);
HttpContent content = response.Content;
string myContent = await content.ReadAsStringAsync();
MessageBox.Show(myContent, "Info");
}
public class Userinfo
{
public String username { get; set; }
public String password { get; set; }
public String ip { get; set; }
}
I used this and it is worked.
var url = "http://localhost/login/dblogin.php";
HttpClient client = new HttpClient();
StringContent data = new StringContent("username="+user+"&password="+pass+"&ip="+ip);
data.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
HttpResponseMessage response = await client.PostAsync(url, data);
response.EnsureSuccessStatusCode();
HttpContent content = response.Content;
string myContent = await content.ReadAsStringAsync();
loginResp apiResponse = JsonConvert.DeserializeObject<loginResp>(myContent);

Send FromForm Object between APIS C#

I want to send an Object between apis
but my controller is waiting for this
public async Task<IActionResult> Post([FromForm]UserViewModel input, CancellationToken ct = default(CancellationToken))
How can I send that model as a FromForm?
My Current call:
var userContent = JsonConvert.SerializeObject(userRequest);
HttpRequestMessage request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri($"{_apiUrl}users"),
Content = new StringContent(userContent, Encoding.UTF8, "application/json")
};
var result = await _httpClient.SendAsync(request);
My model:
public class UserViewModel
{
public string name;
public string lastname;
public List<IFormFile> GalleryImages { get; set; }
}

Xamarin Android send Post data to WebApi

I have an Android app created with Xamarin in Visual Studio and I want to send a form data in json format to a Web Api created in C#. I tried a lot of methods from web an none worked.
Sometimes I get 500 Internal Server Error or sometimes I get null.
The last version I tried in WebApi is:
public HttpResponseMessage Post([FromBody]string value)
{
if (value == null || value == "") Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not read subject/tutor from body");
var user = JsonConvert.DeserializeObject<UsersModel>(value);
dynamic json = System.Web.Helpers.Json.Decode(value);
string newName = json.Name;
string newSurname = json.Surname;
string newUsername = json.Username;
string newPassword = json.Password;
string insertNewUser = "INSERT INTO USERS(NAME,SURNAME,USERNAME,PASSWORD) VALUES (:name,:surname,:username,:password) ";
using (OracleConnection conn = new OracleConnection(ConfigurationManager.ConnectionStrings["Licenta"].ConnectionString))
{
OracleCommand cmd = new OracleCommand(insertNewUser, conn);
cmd.Parameters.Add("name", newName);
cmd.Parameters.Add("surname", newSurname);
cmd.Parameters.Add("username", newUsername);
cmd.Parameters.Add("password", newPassword);
cmd.ExecuteNonQuery();
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch(Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
The message I want to send to Web api is
{
"name": "Ionescu",
"surname": "Ralu",
"username": "ralucuta",
"password": "1235555",
"usertype":1
}
This is my Xamarin Android app code:
public async Task<UserAccount> SaveProduct(UserAccount product)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://blabla:80/test/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
StringContent content = new StringContent(JsonConvert.SerializeObject(product), Encoding.UTF8, "application/json");
// HTTP POST
HttpResponseMessage response = await client.PostAsync("api/Users/", content);
if (response.IsSuccessStatusCode)
{
string data = await response.Content.ReadAsStringAsync();
product = JsonConvert.DeserializeObject<UserAccount>(data);
}
}
return product;
}
public class UserAccount
{
public string name { get; set; }
public string surname { get; set; }
public string username { get; set; }
public string password { get; set; }
public int usertype { get; set; }
}
Your rest api won't be called since you are passing UserAccount object and you are expecting string. change your web api signature like this
[HttpPost]
[Route("api/Users/save")]
public HttpResponseMessage MyMethod(UserAccount userAccount)
{
//your api code
}
And in your android code
public async Task<UserAccount> SaveProduct(UserAccount product)
{
try {
using (var client = new HttpClient ()) {
client.BaseAddress = new Uri ("http://blabla:80/test/");
client.DefaultRequestHeaders.Accept.Clear ();
client.DefaultRequestHeaders.Accept.Add (new MediaTypeWithQualityHeaderValue ("application/json"));
var uri = new Uri ("http://blabla:80/test/api/Users/save");
string serializedObject = JsonConvert.SerializeObject (product);
HttpContent contentPost = new StringContent (serializedObject, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync (uri, contentPost);
if (response.IsSuccessStatusCode) {
var data = await response.Content.ReadAsStringAsync ();
UserAccount product = JsonConvert.DeserializeObject<UserAccount>(data);
return product;
}
}
}
catch (Exception) {
return null;
}
}

Sending json response using Authentication filter in Web api controller?

I have an authentication filter in my controller
[ArcGISAuthentication]
I have defined the filter like below
public class ArcGISAuthenticationAttribute : Attribute, IAuthenticationFilter
{
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
return Task.Run(async () =>
{
var queryParameters = HttpUtility.ParseQueryString(context.Request.RequestUri.Query);
var token = queryParameters["token"];
if (!string.IsNullOrWhiteSpace(token))
{
var userInfo = await CommunityManager.GetUserInfoAsync(token);
context.Principal = new ArcGISUserPrincipal(userInfo, token);
context.Request.SetUserPrincipal(context.Principal);
}
else{
//What shoudld I do here to send a json response
}
});
}
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
return Task.Run(() => { });
}
public ArcGISAuthenticationAttribute()
{
}
}
The problem is I want to send a json repsonse when the authentication fail. As in the else statement in the AuthenticateAsync above.
How can I do this?
Create a custom error result
public class ErrorResult : IHttpActionResult {
public ErrorResult(HttpRequestMessage request, string message, HttpStatusCode status = HttpStatusCode.InternalServerError, string reasonPhrase = "Internal Server Error") {
ReasonPhrase = reasonPhrase;
Request = request;
Message = message;
Status = status;
}
public HttpStatusCode Status { get; private set; }
public string ReasonPhrase { get; private set; }
public string Message { get; private set; }
public HttpRequestMessage Request { get; private set; }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) {
return Task.FromResult(Execute());
}
private HttpResponseMessage Execute() {
var status = Status;
var responseBody = new Models.envelope {
meta = new Models.metadata {
code = (int)status,
type = ReasonPhrase ?? status.ToString().ToCamelCase(),
message = Message
},
data = null
};
var response = Request.CreateResponse(status, responseBody);
response.RequestMessage = Request;
response.ReasonPhrase = ReasonPhrase;
return response;
}
}
and set it to the context.Error property
if (!string.IsNullOrWhiteSpace(token))
{
var userInfo = await CommunityManager.GetUserInfoAsync(token);
context.Principal = new ArcGISUserPrincipal(userInfo, token);
context.Request.SetUserPrincipal(context.Principal);
}
else
{
context.Error = new ErrorResult(context.Request, "Some message to return");
}
In the Execute of the result you can set the response message to JSON or let the content negotiator determine what media type to return based on request headers.

Call HttpPut with parameter C#

So I create an HttpPut method in an ASP.NET web api.
[Route("api/Account/Save")]
[HttpPut]
public IHttpActionResult SaveAccount(Account acc) {
// do stuff
}
I pass in an instant of the Account class.
class Account
{
public int AccountID { get; set; }
public string AccountName { get; set; }
}
Now I want to call this from a console application. I am trying to do this but it's not working. It's not throwing any exception either.
var acc = new Account() { AccountID = 1234, AccountName = "zzzzP" };
string json = JsonConvert.SerializeObject(acc);
HttpContent content = new StringContent(json);
response = await client.PutAsync("api/Account/Save", content);
Json returned:
"{\"AccountID\":1234,\"AccountName\":\"zzzzP\"}"
You probably want something like this
static async Task PutAccount()
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://yourWebSite.com");
var acc = new Account() { AccountID = 1234, AccountName = "zzzzP" };
string json = JsonConvert.SerializeObject(acc);
using (HttpResponseMessage response = await client.PutAsync("api/Account/Save", new StringContent(json)))
{
return response.EnsureSuccessStatusCode();
}
}
}

Categories