what is the difference between those 2 Post methods - c#

am a bit confused about the difference between this 2 lines:
req.OpenReadStream();
and
Request.Form.Files.GetFile("FileContent").OpenReadStream()
here is what i know so far and correct me if am wrong, i know that they are both meant to read a file, and the first method accept file only, however the second accept file and a json value,,
but what i still dont understand is the difference in term of syntax
Here is a snippet from the post methods:
public IActionResult Post(IFormFile req)
{
req.OpenReadStream();
return Ok();
}
[HttpPost]
public IActionResult Post([FromForm] RequestModel req)
{
Request.Form.Files.GetFile("FileContent").OpenReadStream()
return Ok();
}
//....
public class RequestModel
{
public string FileContent { get; set; }
public string SomeRandomString { get; set; }
}

None. They both belong to IFormFile.
The only difference is how you're accessing the interface.
In your first example you're accessing it directly as it's passed into the constructor of your method.
In your second example you're accessing it from the Files collection of the HttpRequest by getting the file using GetFile method that returns the said interface.
As Panagiotis Kanavos said, the later can not be tested at all.

Related

the values field is required

Detail: I am trying to set up a simple get/post method inside asp.net controller and using postman to set if its set up correctly. I have looked for similar question on stackoverflow and they did not fixed my issue
Error: My Get method works fine but my post method giving an following error. Please see below postman:
debug: if I add a break line inside post method. it is never reaching to that break line
Code in asp.net
[ApiController]
[Route("[controller]")]
public class CoursesTakenController : Controller
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] {"value", "value" }
}
[HttpPost]
public Task<ActionResult<string>> Post([FromBody] string values)
{
return Ok(values);
}
}
I also tried this: but doesnt work
[HttpPost]
public async Task<IActionResult> Post([FromBody] string values)
{
return Ok();
}
You are posting a json object while the method expects a string. System.Text.Json (default json serializer used by ASP.NET Core) is pretty restrictive in JsonTokenType handling, so either post a string i.e. just "RandomText" (or encoded into string json object - {\"values\":\"asdasdasd\"}) or change action to accept an object:
public class Tmp
{
public required string Values { get; set; }
}
[HttpPost]
public async Task<ActionResult<string>> Post([FromBody] Tmp values)
{
...
}

What's the correct structure for a HTTP Post method? ASP.NET Core Web API

I'm working on a simple notes api, I'm trying to create a Put method to update a note in my notes list, but when I try to update any note through the SwaggerUI I get a the 404 status code. I think that I'm missing something in the structure.
This is my [HttpPut] request:
[HttpPut("{id}")]
public IActionResult Put([FromBody] Note requestParam)
{
if (!ModelState.IsValid)
{
return BadRequest("Not a valid model");
}
using (_datacontext)
{
var ExistingNote = _datacontext.Note.Where(n => n.Id == requestParam.Id)
.FirstOrDefault<Note>();
if (ExistingNote != null)
{
ExistingNote.Title = requestParam.Title;
ExistingNote.Description = requestParam.Description;
ExistingNote.Completed = requestParam.Completed;
_datacontext.SaveChanges();
} else
{
return NotFound();
}
}
return Ok();
}
My DataContext:
public class DataContext : DbContext
{
public DataContext(DbContextOptions<DataContext> option) : base(option)
{
}
public DbSet<Note> Note { get; set; }
}
And lastly my Note Model:
public class Note
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public bool Completed { get; set; }
}
After looking for different examples I haven't found a standard approach so I'm not sure what to do about it
I've researched about Http bodies since it seemed like it needed to be part of the request but still get the error code. What could be wrong with it? (Both post and get methods work!).
Also, the error code:
When using the [HttpPut("{id}")] attribute on your controller, you need to add a parameter to the controller method's signature:
IActionResult Put([FromRoute] int Id, [FromBody] Note requestParam)
You can then call the API like this when Id=123
PUT http://{base-url}/123
Then you need to query the data context using the id from the route (which means you can remove it from the body)
On the other hand, if you don't want the Id as part of the request URL and keep it in the body, you need to remove the Id from the route template:
[HttpPut] without {id}.
Needless to say, make sure the Id actually exists in the data context. Otherwise your code will return, yes, a 404.

Why are POST params always null in .NET Core API

I've created a simple .NET core controller and am trying to query it from Angular.
The problem is that whenever I send a post request to my login action, I always receive null parameters! The weird thing though is that upon investigating, the request body/payload clearly shows my parameters are set.
See my screenshot for an example of what I mean.
I have tried my best and have been reading through similar problems for the past few hours, but haven't had any success 😭
So my question is: What is causing my null parameters? .NET core must be doing something that I'm not aware of.
If you think seeing more code or the entire project would help, don't hesitate to ask!
You can't get two separate parameters from body, cause it is going to bind email and password as properties of the parameter, not exact parameters. You need to create an object, which defines properties with those names, and use that object in the parameter
class Login
{
public string Email { get; set; }
public string Password { get; set; }
}
In the action method parameter
([FromBody]Login model)
I suggest to create class with properties email and password.And using [FromBody] attribute.
public class LoginModel
{
public string Email {get;set;}
public string Password {get;set}
}
[HttpPost]
[Route("login")
public async Task<IActionResult> Login([FromBody] LoginModel model)
{
// your code
}

ASP.NET MVC required parameters in controller method

I was wondering if it's possible to have something like:
[HttpGet]
public JsonResult AddTextFile(string path)
{
if(string.IsNullOrEmpty(path))
{
// return error
}
}
But in the case where I might have a lot of parameters in my controller method I don't want to use string.IsNullOrEmpty() for each one. I know that I could use view-models with a [Required] field indicator and that will allow me to use ModelState, but because these are all API endpoints, I'm requiring information through get parameters.
Is there an elegant way of requiring controller method parameters, so that if any of them are not set it would return a generic response message?
Use a complex object as the parameter:
[HttpGet]
public JsonResult AddTextFile(MyObject obj) {
if(!ModelState.IsValid) {
// return error
}
}
public class MyObject {
[Required]
public string Path { get; set; }
}
The properties of MyObject will be taken from the query parameters, like: /addtextfile?path=blah
And the model validation will apply.

How to validate GET url parameters through ModelState with data annotation

I have a Web API project... I would like to respect the REST principles, so I should have just a GET method and just a POST method...
I have to do a search, so i think this matches the GET method, because after the search I obtain the result and I show it in the page... If I do not find anything I must create the object... this action is a POST...
Now I have a problem... I must validate the filters of the search, because filters are a tax code and a alpha-numeric code (6 chars)... I have already done a client side validation. Now I should do a Server Side validation.
Untill now, we have used data annotation to validate the request, but this is a GET... so my method has this signature:
[HttpGet]
public IHttpActionResult GetActivationStatus(string taxCode, string requestCode)
{
if (ModelState.IsValid)
{
...
}
}
But how can I validate my ModelState with Data Annotation?
Thank you
Create your own model...
public class YourModel
{
[//DataAnnotation ...]
public string taxCode { get; set; }
[//DataAnnotation ...]
public string requestCode { get; set; }
}
And change your signature of your server side controller:
[HttpGet]
public IHttpActionResult GetActivationStatus([FromUri] YourModel yourmodel)
{
if (ModelState.IsValid)
{
...
}
}
If your client side code already worked you don't have to change it... Please, note that the properties of your Model are the same of the parameter you are passing now (string taxCode, string requestCode)... and they are case sensitive...
EDIT:
I mean that you can call your controller in this way:
http://localhost/api/values/?taxCode=xxxx&requestCode=yyyy

Categories