POST Data To ASP.NET API With Xamarin - c#

I am using C# asp.net and attempting to create my first Xamarin app. I have altered my asp.net API to hold the below syntax
private SqlConnection con;
private SqlCommand com;
private void connection()
{
string constr = ConfigurationManager.ConnectionStrings["getconn"].ToString();
con = new SqlConnection(constr);
}
[HttpPost]
public string AddUser(User user)
{
connection();
com = new SqlCommand("InsertData", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#FName", user.FName);
com.Parameters.AddWithValue("#Lname", user.LName);
com.Parameters.AddWithValue("#Phone", user.Phone);
com.Parameters.AddWithValue("#Compnay", user.Company);
com.Parameters.AddWithValue("#Email", user.Email);
com.Parameters.AddWithValue("#Pass", user.Pass);
com.Parameters.AddWithValue("#Registrationdate", user.Registrationdate);
con.Open();
int i = com.ExecuteNonQuery();
con.Close();
if (i >= 1)
{
return "New User Added Successfully";
}
else
{
return "Failed to Add User";
}
}
[HttpGet]
public string Get()
{
return "";
}
And I Have in my Xamarin syntax the below
void OnRegisterTap(object sender, EventArgs e)
{
InsertUser().ConfigureAwait(true);
}
private async Task InsertUser()
{
try
{
var httpClient = new HttpClient();
var url = "http://XXX.XXX.X.XXX:8888/api/user/adduser";
var data = new
{
FName = fname.Text,
LName = lname.Text,
Company = company.Text,
Email = Email.Text,
Pass = Password.Text,
Registrationdate = DateTime.UtcNow.ToString()
};
var jsonData = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
var result = await httpClient.PostAsync(url, jsonData);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Now there is no error thrown when I press the button from my Xamarin app, I have verified that all the variables holds the appropriate values, however my issue is that no data is actually input into the database.
What step did I miss or did I improperly code that is keeping the data from being inserted?

Try changing
var result = await client.PostAsync(url, jsonData);
To
var response = await client.PostAsync(url, jsonData);
var result = await response.Content.ReadAsStringAsync();
Add FromBody to your controller (assuming User class is correct)
[HttpPost]
public string AddUser([FromBody] User user)
Use fiddler to Watch your request & response also your controller should return a proper HTTP response.

Related

C# script to load data into SQL Server database doesn't work as expected

I am trying to query the APIs and insert the responses from it in to the SQL Server table using the script task. The script task is behaving in consistent that one time loads the data the other time the execution shows succeeded there is no data in the table.
Here is the C# code I am using to load the data:
public void Main()
{
// TODO: Add your code here
executeInsert();
}
public async void executeInsert()
{
try
{
var sqlConn = new System.Data.SqlClient.SqlConnection();
ConnectionManager cm = Dts.Connections["SurplusMouse_ADONET"];
string serviceUrl = Dts.Variables["$Project::RM_ServiceUrl"].Value.ToString();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(serviceUrl);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string APIUrl = string.Format(serviceUrl + "/gonogo");
var response = await client.GetAsync(APIUrl);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
try
{
sqlConn = (System.Data.SqlClient.SqlConnection)cm.AcquireConnection(Dts.Transaction);
const string query = #"INSERT INTO [dbo].[RM_Approved_Room_State]
(APPROVED_ROOM_STATEID,SOURCE_ROOMID,DEST_ROOMID,ENTITY_TYPEID)
SELECT id, sourceRoomRefId, destinationRoomRefId,entityRefId
FROM OPENJSON(#json)
WITH (
id int,
sourceRoomRefId int,
destinationRoomRefId int,
entityRefId int
) j;";
using (var sqlCmd = new System.Data.SqlClient.SqlCommand(query, sqlConn))
{
sqlCmd.Parameters.Add("#json", SqlDbType.NVarChar, -1).Value = result;
await sqlCmd.ExecuteNonQueryAsync();
}
}
catch (Exception ex)
{
Dts.TaskResult = (int)ScriptResults.Failure;
}
finally
{
if (sqlConn != null)
cm.ReleaseConnection(sqlConn);
}
}
}
catch (Exception ex)
{
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
Can anyone help me how this script shows succeeded no data loaded but other time it loads. I am kind of stuck any help is greatly appreciated
Seems you have async calls inside your method, so it should be a Task
Try this way:
public void Main()
{
// TODO: Add your code here
executeInsert().GetAwaiter().GetResult();
}
public async Task executeInsert()
{
....
The calling method should also be async in order to await the result. In this case I guess you are doing a simple test on a console application

How to refactoring database connection method with data from API - c#

I try to change my database connection method with data from API and want to remove connection to database.
This is my database connection and I want to replace data from database with data from API.
public IEnumerable<AlertLevel> DataBaseConnection(int mapCode)
{
string ConnectionString = "server=192.168.1.1;uid=user;port=3333;pwd=password;database=dbName;";
MySqlConnection Conn = new MySqlConnection(ConnectionString);
var listAlert = new List<AlertLevel>();
try
{
Conn.Open();
//replace(2) with mapCode
string query = "CALL Get_Alert_levels_Station(" + mapCode + ");";
MySqlCommand myCommand = new MySqlCommand(query, Conn);
MySqlDataReader myReader;
myReader = myCommand.ExecuteReader();
try
{
while (myReader.Read())
{
var currentData = new AlertLevel()
{
dateForecast = myReader.GetDateTime(0),
levelForecast = myReader.GetInt32(1)
};
listAlert.Add(currentData);
}
}
finally
{
myReader.Close();
Conn.Close();
}
}
catch (Exception ex)
{
Console.WriteLine("Database Connection", "Not Connected ..." + Environment.NewLine + ex.ToString(), "OK");
}
return listAlert;
}
This is my methods with API data:
string GenerateRequestUri(string endpoint)
{
string requestUri = endpoint;
requestUri += $"?id=16";
return requestUri;
}
string GenerateRequestUriStations(string endpoint)
{
string requestUri = endpoint;
requestUri += $"stations";
return requestUri;
}
public WaterBindingData GetData()
{
var reusult = _restServiceData.GetWaterDataForecast(GenerateRequestUriStations(Constants.EndPoint), GenerateRequestUri(Constants.EndPoint));
foreach (var item in reusult.WaterData.Ardaforecast[0].Items)
{
item.DateTimeForecast.ToString();
item.AlertLevelForecast.ToString();
}
return reusult;
}
I want to put inside in DataBaseConnection method my API logic and want to put item.DateTimeForecast.ToString(); and item.AlertLevelForecast.ToString(); in AlertLevel and also I don't know how to put dynamic variable in GenerateRequestUri(string endpoint): requestUri += $"?id=16"; 16 Have to be mapCode
I assume you want to do something like this
string GenerateRequestUri(string endpoint, mapCode)
{
string requestUri = endpoint;
requestUri += $"?id={mapCode}";
return requestUri;
}
public IEnumerable<AlertLevel> GetDataFromAPI(int mapCode)
{
var listAlert = new List<AlertLevel>();
var reusult = _restServiceData.GetWaterDataForecast(GenerateRequestUriStations(Constants.EndPoint), GenerateRequestUri(Constants.EndPoint), mapCode);
foreach (var item in reusult.WaterData.Ardaforecast[0].Items)
{
var currentData = new AlertLevel()
{
dateForecast = item.DateTimeForecast.ToString(),
levelForecast = item.AlertLevelForecast.ToString()
};
listAlert.Add(currentData);
}
return listAlert;
}

ASP MVC Core 3x Async database call - What am I not getting?

I am hoping someone can bring the light here because I am bouncing between one exception and another in VS and I am getting really fed up. I have read articles on how to perform async calls and seen code examples, yet for some reason I am somehow just not getting it according to VS.
I have a simple POCO, GetCompaniesResponse which will contain a collection of companies or errors depending on what happens:
public class GetCompanyResponse
{
public List<Company> Companies { get; set; }
public List<ErrorResult> Errors { get; set; }
public GetCompanyResponse()
{
Companies = new List<Company>();
Errors = new List<ErrorResult>();
}
}
All I am trying to do is convert a synchronous call that loads the companies from a database into an async call in order to free up the UI, whilst the data loads.
Here is the method I have converted:
public async Task<GetCompanyResponse> GetCompaniesByQuery()
{
var response = new GetCompanyResponse();
try
{
using (var conn = new SqlConnection(_configuration["Settings:DBConn"]))
{
var cmd = conn.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT TOP (1000) company_id, company_name, postcode FROM dbo.tbl_companies";
conn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
response.Companies.Add(new Company
{
CompanyId = Convert.ToInt32(reader["company_id"]),
CompanyName = reader["company_name"].ToString(),
PostCode = reader["postcode"].ToString()
});
}
}
}
catch (Exception e)
{
response.Errors.Add(new ErrorResult
{
ErrorMessage = e.Message
});
}
return response;
}
And my controller action is:
public async Task<IActionResult> ByQuery()
{
var service = new TestService(_configuration);
var response = await service.GetCompaniesByQuery();
return View(response);
}
The above method in VS simply keeps telling me I cannot return response because it cannot be converted. What am I doing wrong?
Severity Code Description Project File Line Suppression State
Error CS0029 Cannot implicitly convert type 'TestApp.Models.GetCompanyResponse' to 'System.Threading.Tasks.Task<TestApp.Models.GetCompanyResponse>' TestApp C:\Working Copies\TestApp\TestApp\Services\TestService.cs 59 Active
If I then try to extract the element of the task that strictly deals with the Companies property of the response POCO like so:
public async Task<IActionResult> ByQuery()
{
var service = new TestService(_configuration);
var response = new GetCompanyResponse();
response.Companies = (await service.GetCompaniesByQuery()).ToList();
return View(response);
}
public async Task<IEnumerable<Company>> GetCompaniesByQuery()
{
var response = new List<Company>();
try
{
using (var conn = new SqlConnection(_configuration["Settings:DBConn"]))
{
var cmd = conn.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT TOP (1000) company_id, company_name, postcode FROM dbo.tbl_companies";
conn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
response.Add(new Company
{
CompanyId = Convert.ToInt32(reader["company_id"]),
CompanyName = reader["company_name"].ToString(),
PostCode = reader["postcode"].ToString()
});
}
}
}
catch (Exception e)
{
//not implemented yet
}
await Task.WhenAll((IEnumerable<Task>)response);
return response;
}
Whilst VS stops complaining about it, I then start running into invalid cast errors when the code is ran.
InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List`1[TestApp.Models.Company]' to type 'System.Collections.Generic.IEnumerable`1[System.Threading.Tasks.Task]'.
TestApp.Services.TestService.GetCompaniesByQuery() in TestService.cs
+
await Task.WhenAll((IEnumerable<Task>)response);
TestApp.Controllers.HomeController.ByQuery() in HomeController.cs
+
response.Companies = (await service.GetCompaniesByQuery()).ToList();
It makes no sense to me why this is the cause when the examples I have seen do exactly the same thing as above. What am I failing to comprehend here?

How to consume DELETE request from windows client application

In my web API delete request, which containing multiple parameters.I need to consume this DELETE request using C# windows form application and my code as bellow.
private void btnDelete_Click(object sender, EventArgs e)
{
using (var client = new HttpClient())
{
person p = new person { ID = 1, SID = 5, Name = "paul"};
client.BaseAddress = new Uri("http://localhost:2733/");
var response = client.DeleteAsync("api/person/").Result;
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
else
Console.Write("Error");
}
}
This is how I consume this using Postman, and its works finehttp://localhost:2733/api/person/1/5/"paul" How to consume this using my windows client. I try these two way,
var response = client.DeleteAsync("api/person/",p).Result;
and
var response = client.DeleteAsync("api/person/"+1+5+"paul").Result;
But those are not working. How can I pass parameters to DELETE request.
Updated:
This is my controller class,
[Route("api/person/{id:int}/{pid:int}/{pname}")]
[HttpDelete]
public void Delete(int id, int pid, string pname)
{
var pModel = new PModel
{
ID = id,
SID = pid,
Name= pname
};
Person p = new Person();
p.deletePerson(pModel);
}
This is Person class
public void deletePerson(PModel p)
{
try
{
string sql = $"DELETE from person WHERE ID = {p.ID} AND SID = {p.SID} AND Name= {p.Name}"; ;
MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand(sqlString, conn);
cmd.ExecuteNonQuery();
long x = cmd.LastInsertedId;
}
catch (MySqlException x)
{
int errr = x.Number;
Console.WriteLine(errr);
}
}
Try the below. It should replicate the way you have tried consuming your API through PostMan.
var response = client.DeleteAsync($"api/person/{p.ID}/{p.SID}/\"{p.Name}\"").Result;

Executing Query via C# MVC API

I'm having trouble with some code, and I just can't seem to figure this out. I am attempting to send some data to a backend API that connects to our SQL Server and executes a query that I don't expect any kind of results from. The problem I'm having is that the SQL command isn't being sent to the server, and I'm getting a "404 - This file doesn't exist".
Here is the front part of the request:
public async Task ExportNewLists (string pid, string list)
{
var endpointUrl = string.Concat(baseEndpoint, "ExportLists", "/", pid, "/", list);
AddAuthorization();
using (HttpResponseMessage response = await client.GetAsync(endpointUrl))
{
if (!response.IsSuccessStatusCode)
{
Response.StatusCode = (int)response.StatusCode;
var result = response.Content.ReadAsStringAsync().Result;
var message = JsonConvert.DeserializeObject<ResponseError>(result);
}
}
}
And here is the API function I'm trying to call:
[Route("api/Lists/ExportLists/{pid}/{list}")]
[HttpGet]
[ResponseType(typeof(void))]
private async Task<IHttpActionResult> ExportList(string pid, string list)
{
using (var connection = db.Database.Connection)
{
try
{
connection.Open();
var command = connection.CreateCommand();
command.Connection = connection;
command.CommandText = "EXEC LIST_EXPORT_SINGLE";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#PID");
command.Parameters["#PID"].Value = pid;
command.Parameters.Add("#LIST");
command.Parameters["#LIST"].Value = list;
await command.ExecuteNonQueryAsync();
connection.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return Ok();
}
You have marked ExportScrubList as private. You cannot call an action marked as private via http.

Categories

Resources