Xamarin Android send Post data to WebApi - c#

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;
}
}

Related

I am trying to submit an object that contains some data and a file from the client app to the API app using ASP.CORE 5

I have tried to submit an object from client app to an API which contains some data and a file, but I failed to do so.
Here is the code:
(1) The model:
public class ABC
{
public int Id { get; set; }
public string Image { get; set; }
public string Name { get; set; }
[NotMapped]
public IFormFile File { get; set; }
}
(2) The client app controller
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ABC aBC)
{
using (var httpClient = new HttpClient())
{
StringContent content = new StringContent(JsonConvert.SerializeObject(aBC), Encoding.UTF8, "application/json");
using (var response = httpClient.PostAsync(BaseURLManager.BaseUrl + "ABCs", content))
{
var apiResponse = response.Result.Content.ReadAsStringAsync();
aBC = JsonConvert.DeserializeObject<ABC>(apiResponse.Result);
}
}
return View(aBC);
}
(3) The API controller
// POST: api/ABCs
[HttpPost]
public async Task<ActionResult<ABC>> PostABC([FromForm] ABC aBC)
{
_context.ABC.Add(aBC);
await _context.SaveChangesAsync();
return CreatedAtAction("GetABC", new { id = aBC.Id }, aBC);
}
Could any one provide me a working code, I am using ASP.NET Core 5.
Thank you in advance
Since you use the FromForm attribute inside the api method, you should send request in formdata instead of json format.
More details, you could refer to below codes:
var client = new HttpClient
{
BaseAddress = new("https://localhost:7105/api/")
};
var path = $"{_hostEnvironment.ContentRootPath}test.json";
var stream = System.IO.File.OpenRead(path);
var request = new HttpRequestMessage(HttpMethod.Post, "PostABC");
var content = new MultipartFormDataContent
{
// file
{ new StreamContent(stream), "File", "test.json" },
// payload
{ new StringContent("1"), "Id" },
{ new StringContent("bbbb"), "Image" },
{ new StringContent("ccc"), "Name" }
};
request.Content = content;
var re = client.SendAsync(request).Result;
Result:

WebApi POST method not found but GET works

I tried many time today to call a web api function with POST (HttpClient.PostAsync) method . But unfortunately I can't.
Only the call with GET (HttpClient.GetAsync) method working with success.
I try to follow many sample on the net, but always the same error. ("Not Found")
Thank you so much if somebody can help me
Here is the C# Web API:
[RoutePrefix("NewAreaMap")]
public class NewAreaMapController: ApiController
{
[HttpPost]
[ActionName("PostCreateAreaTemp")]
public AreaTemp PostCreateAreaTemp(double southLatitude, double westLongitude, double northLatitude, double eastLongitude, int countryId, int worldId)
{
AreaTemp newTempMap = new AreaTemp();
//.....
* * Here is the C# code from client side: * *
using(var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["SrvWebApiPath"].ToString());
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var values = new Dictionary < string,
string > ()
{
{
"southLatitude", southLatitude.ToString()
},
{
"westLongitude", westLongitude.ToString()
},
{
"northLatitude", northLatitude.ToString()
},
{
"eastLongitude", eastLongitude.ToString()
},
{
"countryId", countryId.ToString()
},
{
"worldId", worldId.ToString()
}
};
var content = new FormUrlEncodedContent(values);
HttpResponseMessage response = await client.PostAsync("api/NewAreaMap/PostCreateAreaTemp", content)
if (response.IsSuccessStatusCode)
{
string jsonData = response.Content.ReadAsStringAsync().Result;
newAreTemp = JsonConvert.DeserializeObject < AreaTemp > (jsonData);
}
}
The GET call work well with the following Url :
HttpResponseMessage response = await client.GetAsync("api/NewAreaMap/GetAreaTemp/?latitudeAreaCenter=7.02&longitudeAreaCenter=9.05");
Since you're posting a JSON, you might as well send it as an object. Or if you still want to keep the dictionary and the signature for the method you could try:
var content = new StringContent(JsonConvert.SerializeObject(values),
Encoding.UTF8, "application/json");
Instead of
var content = new FormUrlEncodedContent(values);
Here's an example with an object.
public class SampleObject
{
public double SouthLatitude { get; set; }
public double WestLongitude { get; set; }
public double NorthLatitude { get; set; }
public double EastLongitude { get; set; }
public int CountryId { get; set; }
public int WorldId { get; set; }
}
And change your request.
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["SrvWebApiPath"].ToString());
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var obj = new SampleObject
{
SouthLatitude = southLatitude,
WestLongitude = westLongitude,
NorthLatitude = northLatitude,
EastLongitude = eastLongitude,
CountryId = countryId,
WorldId = worldId
};
// Send it as StringContent.
var request = new StringContent(JsonConvert.SerializeObject(obj),
Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync("api/NewAreaMap/PostCreateAreaTemp", request)
if (response.IsSuccessStatusCode)
{
string jsonData = response.Content.ReadAsStringAsync().Result;
newAreTemp = JsonConvert.DeserializeObject<AreaTemp>(jsonData);
}
}
And the signature on the server.
public AreaTemp PostCreateAreaTemp(SampleObject sampleObject)
Or if needed:
public AreaTemp PostCreateAreaTemp([FromBody]SampleObject sampleObject)
replace your method parameter with object because you are passing full object
"content" from the httpclient so in that case you need to use same object here also with [frombody] attribute
methodname([FromBody] Content content)
define all the properties in one class and use . Hope it will helpful for you.
Please try to use FromBody attribute with your action parameter.

calling mailchimp api v3.0 with C#

I am trying to subscribe a client to a list, I have created a method to call mailchimp api but it is giving me bad request everytime I try, I tried calling a Get Method and it worked, I don't know what I am doing wrong I tried this one already Calling MailChimp API v3.0 with .Net
this is my code so far
try
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
var info = new Info() { email_address = "example#example.com", status = "subscribed" };
var infoJson = serializer.Serialize(info);
string url = #"https://us12.api.mailchimp.com/3.0/lists/xxxxx/members";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==");
HttpResponseMessage response = client.PostAsJsonAsync(url, infoJson).Result;
if (response.IsSuccessStatusCode)
{
//something
}
else
{
//something else
}
return Ok();
}
catch (Exception ex)
{
return InternalServerError(ex);
}
public class Info
{
public string email_address { get; set; }
public string status { get; set; }
}
Thanks for you help in advance

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();
}
}
}

why does my web api client call not work in Raspberry Pi2 Iot

I have this code:
private const string route = "/api/Print";
public bool Update(string header, string tc)
{
bool success = false;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("my uri");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var print = new Print { CompanyRef = new Guid(), Header = header, TC = tc };
var response = client.PutAsJsonAsync(route, print);
}
success = true;
return success;
}
public sealed class Print
{
public string Header { get; set; }
public string TC { get; set; }
public System.Guid CompanyRef { get; set; }
}
I call it like so:
Update(" header", " string tc");
In C# desktop app it works.
In Windows 10 IoT on a Raspberry Pi2 device it does not work.
Yet, when i am calling a Get from my Web API server *in Iot) it works fine.
?
I am using this code for a year now and it works:
using Windows.Web.Http;
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
try
{
var o = new
{
operation = "NewEvent",
location_id = locationID,
eventName = eventName
};
HttpStringContent content = new HttpStringContent(JsonConvert.SerializeObject(o), Windows.Storage.Streams.UnicodeEncoding.Utf8, "application/json");
HttpResponseMessage response = await httpClient.PostAsync(new Uri(urlPostData), content);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
// TODO: Do something with the responseBody
}
catch (Exception)
{
// TODO: Deal with exception - could be a server not found, 401, 404, etc.
}
}

Categories