I am sending request. And i want map parameters to C# class in Asp.Net Core Web.API controller. When i write to my method property name as parameter, it is working. But, i write class then it gave me error like "The input was not valid."
I am sending my request by Postman as "Get"request. My request is
http://localhost:5002/api/user/GetUsers?PageFirstIndex=0&IsSortAscending=true&PageSize=10&SortBy=Id
When i wrote like this, it is working and all parameters came with value.
public async Task<ServiceResult> GetUsers(string SortBy, bool IsSortAscending, int Page, byte PageSize)
{...}
But when i wrote like this as class, gave me error "The input was not valid.".
[HttpGet("GetUsers")]
public async Task<ServiceResult> GetUsers(QueryObject queryFilter)
{...}
public class QueryObject
{
public string SortBy { get; set; }
public bool IsSortAscending { get; set; }
public int PageFirstIndex { get; set; }
public byte PageSize { get; set; }
}
You need to use the FromQuery attribute.
public async Task<ServiceResult> GetUsers([FromQuery]QueryObject queryFilter) {}
See the model binding documentation.
Related
I am looking to receive 1 CNCTask class object from the body, but I also need to transfer a file in the same POST request. I have written out my POST route definition as:
[HttpPost("TaskUpload")]
[Consumes("application/json")]
public async Task<ActionResult<CNCTask>> Post([FromBody] CNCTask task, IFormFile file)
With my route defined as such, I just don't get how I will even transfer the file (e.g. when testing from Postman). A file would usually be sent in the body (I think ?), but if I already have my CNCTask object being selected by the [FromBody], how do I negotiate this file transfer as well ?
I'm quite confused as to how to send both the class object and the file. Any tips would be appreciated.
EDIT
text body request that only includes a CNCTask object
{
"description":"truc",
"completion":24,
"machine":{
"hostname":"some host",
"port": 1234
}
}
form-data body request that includes the full Payload (CNCTask + IFormFile)
This was tested using a Postman and Visual studio.
You have to create a model class
public class CNCTask
{
public string Description { get; set; }
public int Completion { get; set; }
public Machine Machine { get; set; }
public IFormFile File { get; set; }
}
public class Machine
{
public string Hostname { get; set; }
public int Port { get; set; }
}
action
[HttpPost("TaskUpload")]
public async Task<ActionResult<CNCTask>> Post(CNCTask model)
and you can test it using postman
You can retrive form data as follows
var formdata = Request.Form["formdata"];
var model = JsonConvert.DeserializeObject<ModelEntity>(formdata);
And write your controller this way
public async Task<ActionResult<CNCTask>> Post(IFormFile file)
{
var formdata = Request.Form["formdata"];
var model = JsonConvert.DeserializeObject<InitialDemandEntity>(formdata);
...
}
I am trying to POST image file and a set of parameters using ASP.NET Core. Is there any option/solution to send both Model Data and Image at the same time in POST API. Here is the image of POST API in POSTMAN:
Here is body with Model Information:
If I do it like following code then my companyInfo data is null and image is there.
[HttpPost("PostInformation")]
public async Task<ActionResult<Company>> PostEmployeeJobCategories(IFormFile image, [FromForm]Company companyInfo)
{
}
If I do it like following code then I am getting Unsupported Media Type.
[HttpPost("PostInformation")]
public async Task<ActionResult<Company>> PostEmployeeJobCategories([FromForm]IFormFile image, [FromBody]Company companyInfo)
{
}
Any Advise, how to achieve the goal ?
Thank You
Adding [FromForm] attribute and sending everything through form-data tab in Postman works for me:
public class OtherData
{
public string FirstString { get; set; }
public string SecondString { get; set; }
}
public async Task<IActionResult> Post(IFormFile file, [FromForm]OtherData otherData)
{
return Ok();
}
As vahid tajari pointed out, you can also add your IFormFile to the class definition.
In asp.net core, you can send file and data together, so change your model to:
public class Company
{
public IFormFile Image { get; set; }
public string NameEn { get; set; }
public string Address { get; set; }
//......
}
And your action method to:
[HttpPost("PostInformation")]
public async Task<ActionResult<Company>>PostEmployeeJobCategories([FromForm] Company companyInfo)
{
}
I've an ASP.Net MVC 4 application that I'm porting to ASP.Net Core 3.0 MVC.
I'm trying to port this method
[HttpPost]
public ActionResult DoSave(
[Bind(Prefix = "new")]IEnumerable<C_Data> newItems,
[Bind(Prefix = "updated")]IEnumerable<C_Data> updatedItems,
[Bind(Prefix = "deleted")]IEnumerable<C_Data> deletedItems))
{
}
In the post AJAX (in JavaScript from the web browser) I'm sending the values as JSON like this
{
"new[0].Id":3,
"new[0].SID":"00000000-0000-0000-0000-000000000000",
"new[0].Name":"asd"
}
Here's the C_Data class
public class C_Data
{
[Key]
public int Id { get; set; }
public Guid SID { get; set; }
[Required]
[MaxLength(40)]
public string Name { get; set; }
}
But the three parameters are empty when this action is executed.
Here's the error I get in the ModelState
"The JSON value could not be converted to C_Data"
Anyone please can tell me how to port this method?
Thank you.
PD: This action is in an MVC controller not an API controller.
Here's a link that should help.
It looks like you should be able to use C_Data object, put it in an array, and stringify it in the AJAX call, receive an IEnumerable.
For Asp.Net Core, there are two ways to bind the model, ModelBinding and JsonInputFormatter. For sending request with json, it will use JsonInputFormatter and Bind will not work.
In general, I would suggest you try option below:
Controller Action
[HttpPost]
public ActionResult DoSave([FromBody]ItemModel itemModel)
{
return Ok("Worked");
}
Model
public class ItemModel
{
public IEnumerable<C_Data> NewItems { get; set; }
public IEnumerable<C_Data> UpdatedItems { get; set; }
public IEnumerable<C_Data> DeletedItems { get; set; }
}
Request Json
{
"newItems":[{
"Id":3,
"SID":"00000000-0000-0000-0000-000000000000",
"Name":"asd"
}]
}
I'm implementing feature of getting Incoming Emails from Mailgun. I created action:
[Route("incoming-email/notify")]
[HttpPost]
public async Task<IActionResult> NotifyIncomingEmail([FromForm] CreateIncomingEmailCmd cmd)
{ ... }
and want to debug it locally (send to localhost) to check if params are mapped correctly.
So, for example if I send via Postman as x-www-form-urlencoded param body-html then it isn't mapped to my property BodyHtml of CreateIncomingEmailCmd class and [JsonProperty("body-html")] didn't help.
How can I do that?
You could try to use ModelBinder attribute to specify the name of the property like below:
public class CreateIncomingEmailCmd
{
[ModelBinder(Name = "body-plain")]
public string BodyPlain { get; set; }
[ModelBinder(Name = "body-html")]
public string BodyHtml { get; set; }
}
I'm trying to pass a complex object though the query string but for some reason its not working. I have a complex object that looks like this:
public class QueryOptions
{
public QueryParameter[] Parameters = new QueryParameter[0];
}
And I've tried to sent it a few ways but nothing is working:
My webapi method looks like this:
[HttpGet]
[AllowAnonymous]
public async Task<TDTO[]> GetList([FromQuery] QueryOptions queryOptions)
{
return await this._service.GetList(queryOptions);
}
I've tried with and with out the FromQuery Attribute neither are working.
The url queries looks like this :
/api/users?Parameters[0].PropertyName=FirstName&Parameters[0].Value=GTitzy&Parameters[0].FilterCondition=0
I've also tried with the name of the object appened to the beginning. The request gets sent but the queryOptions always have no parameters.
How can I pass this complex object through the query string?
Assuming
public class QueryParameter {
public string PropertyName { get; set; }
public string Value { get; set; }
public string FilterCondition { get; set; }
}
You need to update your model to expose public properties for [FromQuery] to know what to bind to.
public class QueryOptions {
public QueryParameter[] Parameters { get; set; }
}
You should also consider reading Model Binding: Customize model binding behavior with attributes