NOT RECIEVING The Datas on GET Method - MVC WEB API - c#

I got a problem that my asp.net mvc solution isn't reading my json, and I need some help with this.
First of all, let me introduce you guys to the problem.
I need just to put a GET METHOD, read some information and that's all.
But, the problem is, when i am using a simple j-son it works. As you guys can see above:
.
https://i.imgur.com/d3DyCiB.jpg "The Postman"
.
https://i.imgur.com/e5b6DYA.jpg "The View showing the data"
.
Here what I'm using on my controller/mycodes
https://i.imgur.com/LEYDDUF.jpg "The Code"
.
https://i.imgur.com/wRjYPet.jpg "The Code2"
.
And here what i really need to receive, but comes null:
.
https://i.imgur.com/mbj5lB8.jpg "The J-Son"
.
https://i.imgur.com/vitUQvr.jpg "Returns null"
-- FindAll Clients:
public class ProductClient
{
private string BASE_URL = "http://localhost:50166/api/Clientes";
public IEnumerable<Cliente> findAll()
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(BASE_URL);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync(BASE_URL).Result;
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsAsync<IEnumerable<Cliente>>().Result;
}
return null;
}
catch
{
return null;
}
}
}
My Index
public ActionResult Index()
{
ProductClient pc = new ProductClient();
ViewBag.Clientes = pc.findAll();
return View();
}

You have to specify [FromUri] in the method's parameter. Web API expecting it to come from the Request body by default. You can add the [FromUri] like this:
public IEnumerable<string> findAll([FromUri]List<string> stringColumnNames)
{
return Ok(pc.findAll(stringColumnNames));
}
add call like this
http://localhost:59511/api/Values?str[]="abc"&str[]="xyz"

Related

How do i call a Put-method from WEB API in separate project?

I have built a Web API that is connected to a database for persons. I am now trying to call this Web API from a separate MVC-application which is supposed to have full CRUD. So far i have managed to do so with the Get and Post-methods to create a new person and see a list of the persons currently in the database.
When trying to do a similar call for the Put-method, i get the following error:
This is how my method UpdatePerson is written in my API-application:
[HttpPut]
[Route("{id:guid}")]
public async Task<IActionResult> UpdatePerson([FromRoute] Guid id, UpdatePersonRequest updatePersonRequest)
{
var person = await dbContext.Persons.FindAsync(id);
if (person != null)
{
person.Name = updatePersonRequest.Name;
person.Email = updatePersonRequest.Email;
person.Phone = updatePersonRequest.Phone;
person.Address = updatePersonRequest.Address;
await dbContext.SaveChangesAsync();
return Ok(person);
}
And this is how i am trying to consume the API in my separate MVC-project:
[HttpGet]
public IActionResult Edit()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Edit(PersonViewModel pvm)
{
HttpClient client = new();
StringContent sContent = new StringContent(JsonConvert.SerializeObject(pvm), Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PutAsync("https://localhost:7281/api/Persons/", sContent);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
return RedirectToAction("Get");
}
else
{
return NotFound();
}
}
Everything is working fine when i try to update the database through the API-app so i am not really sure what is wrong with my request. I hope that someone here can spot the issue right away or at least help me out as i am quite a beginner with WEB APIs.
I have mostly tried changing the URL in my MVC-project but the issue remains.
Are you sure you are receiving the request? It seems that your URI is
"https://localhost:7281/api/Persons/"
and your API is expecting
"https://localhost:7281/api/Persons/{id}" -> where {id} should be the guid
you need to append the guid in the URI
Looks like the request doesn't receive the correct the correct parameters, because the URI that appears in your picture seems a generic method.

How to call one service from another with parameter and get response

Currently, I have two services running at different endpoints. For example (this is not my real scenario):
StudentService
CheckHomeWorkService
CheckHomeWorkService can be used from many services (For example TeacherService, WorkerService). It has one controller with CheckHomeWork action. It has some parameters:
HomeWorkNumber (int)
ProvidedSolution (string).
It will return success or failed.
Now, In my StudentService, I have a controller with SubmitHomeWork Action. It needs to check homework using CHeckHomeWorkService and save results to a database. How can I implement this?
I was using Ocelot Api GateWay but it can 'redirect' to another service and I need to save the result of the response to the database
As suggested in the comments, you can use HttpClient to call the other APIs. However, if you want a more safe and performant solution, you can use also the HttpClientFactory.
see this why to use it
and see the official docu
After your comment you say that you have separate WEB API services
in this case you can do this service to retrieve the result :
public async Task<List<HomeWorkModel>> CheckHomeWorkService(int
homeWorkNumber, string providedSolution)
{
using (var httpClient = new HttpClient())
{
using (var response = await
httpClient.GetAsync(Constants.ApiBaseUrl + "/CheckHomeWork?n=" +
homeWorkNumber + "&sol=" + providedSolution))
{
if (response.StatusCode ==
System.Net.HttpStatusCode.OK)
{
string apiResponse = await
response.Content.ReadAsStringAsync();
return
JsonConvert.DeserializeObject<List<HomeWorkModel>>(apiResponse);
}
else
{
return null;
}
}
}
}
public class HomeworkModel
{
Public bool Result {get; set;}
}
whereas :
"Constants.ApiBaseUrl" is http address for base Url of another API
But in case of the same API you will use old solution :
you can pass "CHeckHomeWorkService" in your controller constructor ("Dependency Injection")
and call service methods as you like

Put request is not working using postman to web api 2 c#

I have a method in Api as follows
[HttpPut]
[Route("UpdateTeacher")]
public IHttpActionResult UpdateTeacher(BusinessLayerTeacher Obj)
{
try
{
BusinessLayerTeacher obj = new BusinessLayerTeacher ();
string status = BusinessLayerObject.UpdateTeacher(TeacherObj);
return Ok(status);
}
catch
{
return NotFound();
}
}
Now in post man i am sending the put request to update the teacher object.
It is not triggering this updateTeacher() method.
You are instantiating a new BusinessLayerTeacher object inside the method, which looks suspect when you are already passing in BusinessLayerTeacher as a parameter.
Maybe the route mapping isn't working because you're not passing in the right data in the request body.
Maybe you should be using TeacherObj as the parameter type?
Have a review and give that a try, good luck :-)

API works fine but parameters are not accepted c#

I have my route prefix here:
[RoutePrefix("api/Adresses")]
public class AdressesController : ApiController
{
My function here:
[Route("{codeEtudiant}")]
// GET: api/Adresses/1
public IEnumerable<Object> getAdresseEtu(Int32 code)
{
Where I call my api:
using (var client2 = new HttpClient())
{
string getasync = "http://localhost:11144/api/Adresses/" + etu.Code;
var response2 = await client.GetAsync(getasync);
var json2 = await response.Content.ReadAsStringAsync();
int cpt2 = -1;
foreach (object tmp2 in JsonConvert.DeserializeObject<List<Object>>(json2))
{
My string getasync returns: http://localhost:11144/api/Adresses/1
With these methods I can call any function in my api that does not have parameters but as soon I have one it doesn't respond and give me a response:
404 reason(not found)
The parameter names have to match. Currently you have the route parameter named codeEtudiant but the parameter of the method named code. Give them both the same name.
[Route("{codeEtudiant}")]
public IEnumerable<Object> getAdresseEtu(Int32 codeEtudiant)
See also Attribute Routing in ASP.NET Web API 2.
The error is because the Route Attribute must have the same name of the parameter, use
[Route("{code}")]

Braintree test Request.Params always empty

I am implementing webhook test code and I am running into a problem.
After I POST a sample notification to my webhook listener the Params are not in the request:
Request.Params["bt_signature"]
Request.Params["bt_payload"]
So the listener fails.
Below is both my Post Webhook code and Listener code; I'm not sure if I'm using gateway.WebhookTesting.SampleNotification correctly.
POST Test Webhook
private async Task PostTestNotification()
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:50709/");
var gateway = config.GetGateway();
// Create sample notification
Dictionary<String, String> sampleNotification = gateway.WebhookTesting.SampleNotification(
WebhookKind.SUBSCRIPTION_CHARGED_SUCCESSFULLY, "sub_id_1234"
);
// Convert sample notification to JSON
string payloadJson = JsonConvert.SerializeObject(sampleNotification);
// Create StringContent of json sample notificaiton
var data = new StringContent(payloadJson);
// data looks like this when debugging { "bt_payload":"PG5vdGlmaWNhdGlvbj48dGltZXN0YW1wIHR5cGU9ImRhdGV0aW1lIj4yMDE2LTA1LTI3IDEzOjM2OjEwWjwvdGltZXN0YW1wPjxraW5kPnN1YnNjcmlwdGlvbl9jaGFyZ2VkX3N1Y2Nlc3NmdWxseTwva2luZD48c3ViamVjdD48c3Vic2NyaXB0aW9uPjxpZD5zdWJfaWRfMTIzNDwvaWQ+PHRyYW5zYWN0aW9ucz48dHJhbnNhY3Rpb24+PGlkPnN1Yl9pZF8xMjM0PC9pZD48YW1vdW50PjQ5Ljk5PC9hbW91bnQ+PHN0YXR1cz5zdWJtaXR0ZWRfZm9yX3NldHRsZW1lbnQ8L3N0YXR1cz48ZGlzYnVyc2VtZW50LWRldGFpbHM+PGRpc2J1cnNlbWVudC1kYXRlIHR5cGU9ImRhdGUiPjIwMTMtMDctMDk8L2Rpc2J1cnNlbWVudC1kYXRlPjwvZGlzYnVyc2VtZW50LWRldGFpbHM+PGJpbGxpbmc+PC9iaWxsaW5nPjxjcmVkaXQtY2FyZD48L2NyZWRpdC1jYXJkPjxjdXN0b21lcj48L2N1c3RvbWVyPjxkZXNjcmlwdG9yPjwvZGVzY3JpcHRvcj48c2hpcHBpbmc+PC9zaGlwcGluZz48c3Vic2NyaXB0aW9uPjwvc3Vic2NyaXB0aW9uPjwvdHJhbnNhY3Rpb24+PC90cmFuc2FjdGlvbnM+PGFkZF9vbnMgdHlwZT0iYXJyYXkiPjwvYWRkX29ucz48ZGlzY291bnRzIHR5cGU9ImFycmF5Ij48L2Rpc2NvdW50cz48L3N1YnNjcmlwdGlvbj48L3N1YmplY3Q+PC9ub3RpZmljYXRpb24+\n","bt_signature":"69r68j6hnzjpnq4j|508a7b4b3bbbe15c241c742331acfc5bacf37c54"}
// POST
HttpResponseMessage response = await client.PostAsync("webhooks/accept", data);
// RESPONSE
if (response.IsSuccessStatusCode == true)
{
// SUCCESS CONTENT
string resultJSON = await response.Content.ReadAsStringAsync();
}
else
{
// FAIL CONTENT
dynamic problem = await response.Content.ReadAsStringAsync();
}
}
}
catch (Exception ex)
{
//
Console.WriteLine("Exception: " + ex.Message);
}
}
Webhook LISTENER
// webhooks/accept endpoint
public async Task<ActionResult> accept()
{
try
{
var gateway = config.GetGateway();
if (Request.HttpMethod == "POST")
{
var bt_signature = Request.Params["bt_signature"]; <<<<<<< ALWAYS EMPTY >>>>>>>>>
var bt_payload = Request.Params["bt_payload"]; <<<<<<< ALWAYS EMPTY >>>>>>>>>
WebhookNotification webhookNotification = gateway.WebhookNotification.Parse(
Request.Params["bt_signature"],
Request.Params["bt_payload"]
); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< EXCEPTION WHEN HIT - Value cannot be null, Parameter name: Input >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// ACTION Webhook
if (webhookNotification.Kind == WebhookKind.SUBSCRIPTION_CANCELED)
{
IsActive = false;
await Logger.LogInsight("", "WEBHOOK: SUBSCRIPTION_CANCELED " + webhookNotification.Subscription.Id );
}
else if (webhookNotification.Kind == WebhookKind.SUBSCRIPTION_CHARGED_SUCCESSFULLY)
{
IsActive = true;
await Logger.LogInsight("", "WEBHOOK: SUBSCRIPTION_CHARGED_SUCCESSFULLY " + webhookNotification.Subscription.Id);
}
// code ommitted for brevity, similar to above checking all 'kind' values
}
}
}
Why are the Braintree Request Params empty?
The problem was in the Webhook endpoint, the Braintree sample code is incorrect, it implies using MVC but developers need to use the Web Api for this, and the sample code will not work.
To get this working I left the Sample Notification POST above unchanged and created a new Webhook listener :
First create a class to receive the two braintree strings from the POST:
public class bt
{
public string bt_payload { get; set; }
public string bt_signature { get; set; }
}
And now create an empty Web Api 2 Controller:
[HttpPost]
[Route("api/webhooks/accept")]
public async Task<IHttpActionResult> accept(bt bt_lot)
{
var gateway = config.GetGateway();
WebhookNotification webhookNotification = gateway.WebhookNotification.Parse(
bt_lot.bt_signature,
bt_lot.bt_payload
);
if (webhookNotification.Kind == WebhookKind.SUBSCRIPTION_CANCELED)
{
// take your action here...
}
Im posting all my experiences with Braintree here on SO as there isn't a great deal of help here and I hope it helps others.
I have to say the Braintree Help staff are excellent and always answer questions with very detailed answers that 95% of the time resolved any issues I had, but this issue had me scratching my head as their example didn't work and the help staff assumed like me that the code should work.

Categories