HttpPost [FromForm] also accepts query params - asp.net-core

To my despair, the below URL binds successfully and returns 200 OK.
https://myfakedomain.com/api/Submit?Email=test%40test.com&Name=fakeName
I just learned that my ASP.NET Core API accepts parameters to be submitted using query-strings. I do not want to allow users to submit sensitive data as part of the URL. Instead, I want to enforce my users to submit their info using FormData.
My endpoint looks like this:
[HttpPost]
public async Task<IActionResult> Register([FromForm] RegisterDTO registerDTO)
{}
public class RegisterDTO
{
public string Email { get; set; }
public string Name { get; set; }
}
I might add that submitting FormData also binds successfully.

Related

Map route parameters to model in asp.net core

I have an action with the following annotation,
[HttpGet("update/{hash}")]
public async Task<IActionResult> Update([FromQuery]Model model)
{
// I need to use from model.Hash
return Ok();
}
In addition, I have a simple model like below:
public class Model
{
public string Hash { get; set; }
}
The model binder is not working, because that's clear the hash is not a queryString like ?hash=[value], it's an id.
I can not use another parameter to bind it like:
public async Task<IActionResult> Update(string hash)
because I have a validator for my model.
Is there any way in which I can bind hash to Hash my property?
You can able to bind the route parameter to the model property by using [FromRoute(Name = "hash")] as shown in below.
public class Model
{
[FromRoute(Name = "hash")]
public string Hash { get; set; }
}
Refer this Microsoft doc

String array in query parameters swagger

I'm working on a project where there is an endpoint that receives a list of strings in the parameter, as shown in the code below:
public class PaymentFilter
{
public List<string> Status {get; set; }
}
[HttpGet]
public IActionResult Get([FromQuery] PaymentFilter filter)
{
...
}
However, in the swagger interface the status list is not reflected, as shown in the image:
How do I enable entries for the status list?
Click Try it out button and click Add string item then you can add
parameter

Asp.net core sending form-data and json body at the same to

I am trying to upload a file and also JSON body at the same time to a POST method as below
public async Task<ResponseModel<PersonWriteResponse>> AddPerson([FromForm]IFormFile file, [FromForm]PersonPostRequest request)
{
var person = await _service.AddPerson(file,request);
return ResponseModelHelper.BuildResponse(person, $"/production/person", "person");
}
Both parameters are always null. In postman, I am specifying the content-type as "Multipart/form-data"
Is this the correct way of passing file and json data?
Alan-
I try to use model witch include IFormFile, and it's works
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> update([FromForm]MyFile model)
{
return Ok("Success!");
}
public class MyFile
{
public string Id { get; set; }
public IFormFile File { get; set; }
// Other properties
}
PostMan request here
You may set breakPoint at the return Ok("Success!"); line and saw what you get

Cannot post JSON to an ASP.NET Core RazorPage handler

I'm working with an ASP.NET Core RazorPage as an alternative to an MVC controller, and I want to be able to submit the client side form via XMLHttpRequest. I've already figured out the XSRF token bits so that passes the muster, but the RazorPages framework doesn't seem to process the inbound JSON payload and bind it to the property as expected.
Some code:
The page's model (.cshtml.cs):
public class IndexModel : PageModel
{
private Database database;
private ILogger logger;
[BindProperty]
public AddRequestModel MyRequest { get; set; }
public IndexModel(Database database, ILogger<IndexModel> logger)
{
this.database = database;
this.logger = logger;
}
public void OnGet() {}
public IActionResult OnPostValidate()
{
if (ModelState.IsValid)
{
// ...
}
return new BadRequestObjectResult(ModelState);
}
public async Task<IActionResult> OnPutConfirmAsync()
{
// ...
}
}
And the client side post:
const url = "?handler=validate";
const data = { MyRequest: this.fields };
await axios.post(url, data);
I have verified the data is being submitted correctly:
That X-XSRF-TOKEN header is being added by axios before the request is submitted. The fact that the server responds with a list of errors indicates that it's not the XSRF token causing the problem:
Note the MyRequest object does not contain the values from the request payload - it was not bound as expected (FirstName would not return a required error otherwise). How can I tell RazorPages to accept the JSON request and bind it to my property?
I was able to get the Binding works by adding FromBody similar to how it worked for ASP.NET Web API 2.
[BindProperty, FromBody]
public BroadcastMessageEditingViewModel BindingInfo { get; set; }
Use urlsearchparams with formdata.
In this post you can find more information How do I post form data with fetch api?
You would be better off posting your data to an API endpoint instead of a page controller. Create a class from ControllerBase and it will handle your JSON post correctly.

ASP.NET MVC Web Api Get Not Mapping QueryString To Strongly Typed Parameter

The parameter request is always null using Web API. Am I missing something with using a strongly typed object as a parameter instead of simple types as the parameters.
Url
http://localhost:2222/api/v1/divisions?EventId=30
Controller Action
public virtual ApiDivisionsResponse Get(ApiDivisionsRequest request)
{
return _apiDivisionsService.GetDivisions(request);
}
Object
public class ApiDivisionsRequest : ApiAuthorizedRequest
{
public ApiDivisionsRequest()
{
Page = 1;
PageSize = 10;
}
public int EventId { get; set; }
public int PageSize { get; set; }
public int Page { get; set; }
public string[] Includes { get; set; }
}
I very strongly invite you to read the following article to better understand how parameter binding works in the Web API. After reading it you will understand that by default the Web API binds query string parameters to primitive types and request body content to complex types.
So if you need to bind query string parameters to complex types you will need to override this default behavior by decorating your parameter with the [FromUri] parameter:
public virtual ApiDivisionsResponse Get([FromUri] ApiDivisionsRequest request)
{
...
}
And yeah, I agree with you - that's a hell of a mess - model binding was so easy in plain ASP.NET MVC and they created a nightmare in the Web API. But once you know how it works you will avoid the gotchas.