C# webservice how to send multiple parameters to POST action - c#

I use C# with VS 2015, .NET 4.5.2 and Web API 2
I want to build a restful webservice.
I need to use CURL or Fiddler for testing the webservice (not AJAX or Jquery).
I would prefer CURL if possible.
I succeeded in sending GET requests using CURL to the webservice.
But I also need to send data to the webservice using POST
Unfortunately I have problems using POST.
I need to send not only 1 parameter, but multiple paramters.
(Basically I need to send a whole record that will add to a database)
It seems that it is not possible to send multiple parameters to the POST action?
But instead of sending multiple parameters I should be able to send the record data using an array or List object ?
How should I code the POST action in the webservice controller?
How should I send the data using CURL (or fiddler) so that the POST action can process it?
I saw some examples that have used the URI to POST data... but using URI seems to need content-length to be set?
If possible I would avoid to set content-length.
Model:
The model represents the data that should be sent using POST :
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
Client:
The client (CURL/fiddler) must be able to send model data, for example:
id=5
Name="test"
Category="Hardware"
Price=10
How can I send this data using CURL (or fiddler) ?
Controller Action:
How should I code this action ?
Whould this be OK ? :
[HttpPost]
public void AddProduct([FromBody] List<Product> data )
{
Do something
}
webervice URL
Just for completeness:
My webservice URL looks like this
http://myServer/api/product

For adding such kind of thing .Make a wrapper class and then send it to POST .
[HttpPost]
public void AddProduct(List<Product> data )
{
Do something
}
Instead of this what you can do is- Make a Class
class Wrapper{
List<Product> data
}
and then use
[HttpPost]
public void AddProduct(Wrapper data )
{
Do something
}
This will work . If does't work let me know .I will try to provide you the solution . For me this worked when I was having an issue .

Related

How do I send form data to HttpPost Action with Postman in ASP .Net Core MVC

Out of simple curiosity I would like to Post data from my MVC app to my local database with Postman. Unfortunately, I encountered a certain obstacle and cannot figure out how to solve it.
The general idea is that I have a controller X with an Edit method accepting YViewModel as the only parameter.
XController : Controller
{
//Post
IActionResult Edit(YViewModel vm)
{
//Code
}
//Get
IActionResult Edit(int id)
{
//Code
}
}
YViewModel
{
public int Id { get; set; }
//Other fields below
}
In the Edit method with an HTTP GET Verb I am returning the respective view with the YViewModel containing all the required fields. All the fields (except Id) are assigned to form inputs.
The Id is only bound to the VM model. Binding works perfectly on the page, but I cannot compose the right Postman Request.
I know that I can try localhost..../X/Edit with form-data and then assign all the form fields. But where do I fit Id in that request?
Under the Body tab select x-www-form-urlencoded. For Key use Id. For Value use whatever you want to test with.
I assume you would want to post other YViewModel fields for testing.
Ensure you are creating a POST request.
If Id as the Key doesn't work you can load the page in your browser and look for the name attribute of the Id hidden field. Then use that in Postman.

Problem sending model to HttpPost method in a .net core 3.1 web api application

I'm trying to hit my HttpPost method in a .net core 3.1 application.
When i try to hit it, the model object is created but none of the properties are set.
The behaviour is same when i try to invoke using Swagger as well as postman.
I tried to add a model as simple as :
public class Student{
public string Name{get; set;}
}
[HttpPost]
[Route("TestMethod")]
public void TestMethod(Student stu) {}
public void TestMethod(string name) {}
The strange behaviour is, if i pass it as query string, it works, but somehow it doesn't work with json (using postman). Also, if i create a demo app, it works perfectly fine, but not with my existing application
i used FromBody attribute as well.
Can someone help me with this?
you have to use this action
[HttpPost]
[Route("TestMethod")]
public IActionResult TestMethod([FromBody]Student stu) { return Ok(stu.Name)}
For a Post acton using Postman you have to select Body, raw, JSON in Postman menus. Your json should be
{ "Name":"Doe" }

Sending Base64 data to Controller of Type GET

I am working on MVC WebAPI project. I created controller that needs to accept the Base64 data.
[HttpGet]
public string getData(string fileData)
{ .. Further Operations .. }
Currently, I am using Postman/Telerik Fiddler to check my APIs.
Few things,
Is it possible to send Base64 data to controller of type GET(without using FormData class)?
because in POST and PUT we can use FormData class and send data to controller
if it is can anyone please tell me how can I check my scenario in Postman/Fiddler?
If you can suggest me any another tool that will also be great
Thank You

Restful Web Service using C#

I have been assigned to come up with a web service that receives and posts data. However, I am very new to this, and even after looking up multiple examples and trying to follow them, I have a bit of a difficult time understanding.
Referenced examples:
Link 1
Link 2
The code that I have been given as a reference for the model and controller are the following:
Model
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Webservice.Models.ApiModels {
public class SecondlyReading {
[Key]
public int Id { get; set; }
[Required]
public int Name { get; set; }
[Required]
public string TimeStamp { get; set; }
[Required]
public string Date { get; set; }
[Required]
}
}
Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
using SmartDBWeb.Data;
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using SmartDBWeb.Models.ApiModels;
using Microsoft.EntityFrameworkCore;
namespace Webservice.Controllers.Api {
[Route("api/[controller]")]
[Authorize]
public class WebserviceController : Controller {
private ApplicationDbContext _context;
public WebserviceController(ApplicationDbContext context) {
_context = context;
}
// GET: api/Webservice
[HttpGet]
public IEnumerable<Webservice> GetSecondlyReadings() {
return _context.Webservice.ToList();
}
// GET api/Webservice/id
[HttpGet("{id}")]
public async Task<IActionResult> GetWebservice(int id) {
var reading = await _context.Webservice.SingleOrDefaultAsync(c => c.Id == id);
if (reading == null) {
return NotFound();
}
return Ok(reading);
}
[HttpPost]
public IActionResult PostWebservice([FromBody]List<Webservice> Readings) {
if (!ModelState.IsValid) {
return BadRequest();
}
foreach (Webservice reading in Readings) {
_context.Webservice.Add(reading);
}
_context.SaveChanges();
return CreatedAtAction("GetWebservice", new { id = Readings[0].Id }, Readings[0]);
}
}
}
My main question is how the use of the above code works in general. What I have found out(might not be correct), is that the the model is the data itself and the controller links the model and view together.
Model: It is basically a table structure for the database. So, whenever you will create an object and set the values and insert the object in the database.
Controller: It is used to deal with the HTTP calls and to link your business logic with the View.
[HttpGet]
This maps to a GET request to the URL api/Webservice without any query parameter. The actions return type is a List, which means that multiple objects should be returned. In your case, when the client accesses api/Webservice, all objects within your _context.Webservice are returned.
[HttpGet("{id}")]
This maps to a GET request as well, but this time it requires a so called Query Parameter. This is an additional piece of information that your client provides to make its request more specific. E.g., they could be requesting api/Webservice?id=1 which would ask you to return the object with an id of 1.
[HttpPost]
This maps to a POST request and asks you to insert or update an object. [FromBody] tells the request processor to convert the so-called Request Body into an object of a given type. The request body is where your client will put entire objects - converted e.g. in JSON format - they want to submit to the server.
So, for the model
public class SecondlyReading {
[Key]
public int Id { get; set; }
[Required]
public int Name { get; set; }
[Required]
public string TimeStamp { get; set; }
[Required]
public string Date { get; set; }
}
This will create a datatable with Id as the primary key because you are using [Key] attribute.
private ApplicationDbContext _context;
This is used to create a database context. You might have also created the following in ApplicationDbContext class
public DbSet<SecondlyReading> WebService{get; set;}
It will create a DbSet with name WebService.
In WEB APIs, POST is used to insert new data. So, here the API
api/webservice
in POST, will be used to insert the data. You can insert the data using any CLIENT like POSTMAN or ARC. You have to set the data in body of request of the HTTP call.
The response of the API can be JSON or XML depending on your output.
I think it's better to read the basics?So that you will understand how normally Web API works
For self reading
https://www.asp.net/web-api
Start with asking yourself how Web Communication generally works. When accessing any website via your browser by typing in an address, what actually happens behind the scenes?
What I found to be very helpful was to open up a new tab in my browser and use Developer Tools (e.g. by right clicking anywhere and then clicking on "Inspect") to observe traffic by switching to the network tab. Access a website of your choice, say: wikipedia.org.
Now a bunch of stuff is going on, but you are interested in the first new entry to your network communication list that should say "www.wikipedia.org". Click on that.
You should now be looking at the "Headers" tab, specifically the request headers. There are two important fields:
Request URL : This tells the server what you want from it. It is a Resource locator, meaning that you want to access a resource from the server, say, a piece of HTML, an image or raw JSON data that you use in your application.
Request Method : This tells the server what you want to do with the resource you are trying to access. Do you want to GET it? Or do you want to PUT some resource on the server? Maybe you want to DELETE it or POST changes to this resource.
Let's go back to your source code.
What you provided above are a Model class and a Controller class.
Your model is a data structure that represents a resource within your web application. Id, Name, Timestamp, Date are attributes of this resource. Depending on your actual use case, you want to create, use, update or delete objects of this model type and decide on their attribute's values.
To allow your clients to do so, you have a controller class. It is the entry point for all web requests that "map" to :
[Route("api/[controller]")]
Map means, when the request URL of your client (remember our example "www.wikipedia.org") matches to the string you defined in your Route, this controller class is used (notice: [controller] will be replaced with the actual name of your controller class, in this case "Webservice".
Within your controller you define Actions. Depending on the Request URL and the Request Method (see above) of your client's request, your web framework decides, which action is called.
[HttpGet]
This maps to a GET request to the URL api/Webservice. The action's return type is a List, which means that multiple objects should be returned. In your case, when the client accesses api/Webservice, all objects within your _context.Webservice are returned.
[HttpGet("{id}")]
This maps to a GET request as well, but this time it requires a so called Query Parameter. This is an additional piece of information that your client provides to make its request more specific. E.g., they could be requesting api/Webservice?id=1 which would ask you to return the object with an id of 1.
[HttpPost]
This maps to a POST request and asks you to insert or update an object. [FromBody] tells the request processor to convert the so-called Request Body into an object of a given type. The request body is where your client will put entire objects - converted e.g. in JSON format - they want to submit to the server.
Now, I hope this makes your code examples a bit clearer to you. You also mentioned the View, so I will quickly explain what that is: Typically, after a request to your server, you respond with some sort of answer. In the most simple case, it is the Response Status that tells the client if everything went smooth. For a GET request, you typically return an object in the Response Body. What you return is called the view. In your example:
return Ok(reading);
converts the object that was retrieved from the database into a machine-readable format (e.g. JSON) and adds the response status "200 OK" to it. This is sent to your client.
So this should give you a good overview on how web frameworks work. I hope I could help you with this rather long read. Let me know if I can clarify anything.

How does WebAPI work? Are signatures of HTTP methods in backend strict?

Working on some little task I have some troubles with the Web API controller.
There are 2 methods in my API:
[HttpGet]
public IHttpActionResult FetchAll()
[HttpPost]
public IHttpActionResult CreateNew(int? taskType, string taskName = null)
Which, I'm using for managing tasks in db.
The 1st one (FetchAll) works fine as from special utilities like Postman and bringing some results to the browser console.
But! If to use the 2nd one (CreateNew) there are some problems.
As I have tested in Postman, it works fine:
But if to use my frontend part of application (JS):
var App = function () {
this.init();
};
App.prototype.init = function () {
var self = this;
$.post(
'/api/task/createNew',
{ taskName: "smth new", taskType: 0 }
);
$.get(
'/api/task/fetchAll',
function ( sender ) {
console.log(sender);
}
);
};
window.onload = function () {
var app = new App();
};
There is a problem with the POST method. Firstly I think I'm using jQuery not correctly, but reading the following links I understand that all is correct with jQuery use:
http://api.jquery.com/jquery.post/
http://api.jquery.com/jquery.get/
Also I've checked in browser the failed request details:
As you're able to see, the POST data have been transferred correctly with my jQuery use,
but I have also admit one detail: it's form data.
So... Form data is a type of data, which is send with application/x-www-form-urlencoded and isn't presented as URL part.
If to use in JS-part the next code:
$.post( '/api/task/createNew?taskName=smth new&taskType=0' );
All begins to work.
And Web API seems to be not supporting operations with the Forms data and that's why the Postman test works well (if to look again at old screenshot), because it uses URL parameters, nor forms one.
But I think to send POST data with using URL parameters is rather ugly as for REST architecture and as for using it in JavaScript code (you will generate a string and not normally using Object representation for data, which can be reviews as bad OO-structure).
I have read about forms handling in WebAPI here:
Is there a way to handle form post data in a Web Api controller?
So do exist some ways to solve my problem with more pretty code-style etc (it's meant not to generate URL strings and etc)?
PS
Projects files which were described here are available:
C#/WebAPI controller: http://pastebin.com/AeE2Lb2a
JS part: http://pastebin.com/XcBPs6SD
As explained in the question you linked to your web api post action should take a object containing the fields you want:
public IHttpActionResult CreateNew(NewTask task)
{
// do something with task.TaskType and task.TaskName here
}
public class NewTask
{
public int? TaskType { get;set; }
public string TaskName { get; set; }
}

Categories