While calling an apiController method from Postman I encountered a problem.
the method with params mentioned in Postman client call below method
[AllowAnonymous]
[HttpPost]
public IActionResult Register([FromBody]UserDto userDto)
{
// map dto to entity
//var user = _mapper.Map<User>(userDto);
return Ok(new
{
userDto
});
//try
//{
// // save
// _userService.Create(user, userDto.Password);
// return Ok();
//}
//catch (AppException ex)
//{
// // return error message if there was an exception
// return BadRequest(new { message = ex.Message });
//}
}
which maps the UserDto..
public class UserDto
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
but instead I get the error below :
Use raw option and select json from dropdown
and add your dto value in the body.
Raw
{
"FirstName" : "yourname",
"LastName": "lastname"
}
Related
I need to create a Create Custom Return Validate in Asp Core 2.2 in WebApi.
First Step :
I Created on OnResultExecuting :
public override void OnResultExecuting(ResultExecutingContext context)
{
if (context.Result is BadRequestObjectResult badRequestObjectResult)
{
var message = badRequestObjectResult.Value.ToString();
if (badRequestObjectResult.Value is SerializableError errors)
{//The Code skips the if statement. Why?
var errorMessages = errors.SelectMany(p => (string[])p.Value).Distinct();
message = string.Join(" | ", errorMessages);
}
context.Result = new JsonResult(new ReturnResult(false, ResultStatus.BadRequest, message))
{ StatusCode = badRequestObjectResult.StatusCode };
}
}
The Code skips the if statement. Why?
Second Step :
Created a IValidatableObject in UserDto :
public class UserDto : IValidatableObject
{
[Required]
public string Name { get; set; }
[Required]
public string Family { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Email { get; set; }
[Required]
public string Phone { get; set; }
[Required]
public GenderType Gender { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
foreach (var item in ValidateList.UsernameBanList)
if (Username.Equals(item, StringComparison.OrdinalIgnoreCase))
yield return new ValidationResult("Username Invalid", new[] { nameof(Username) });
foreach (var item in ValidateList.PasswordBanList)
if (Password.Equals(item, StringComparison.OrdinalIgnoreCase))
yield return new ValidationResult("Password Invalid, new[] { nameof(Password) });
foreach (var item in ValidateList.EmailBanList)
if (Email.Equals(item, StringComparison.OrdinalIgnoreCase))
yield return new ValidationResult("Email Invalid", new[] { nameof(Email) });
}
}
Third Step :
I Create a ReturnResult Class :
public class ReturnResult
{
public bool Success { get; }
public ResultStatus Status { get; }
public string Message { get; }
public ReturnResult(bool Success, ResultStatus Status, string Message = null)
{
this.Success = Success;
this.Status = Status;
this.Message = Message ?? Status.ToDisplay();
}
#region implicit operator
public static implicit operator ReturnResult(OkResult result)
{
return new ReturnResult(true, ResultStatus.Success);
}
public static implicit operator ReturnResult(BadRequestResult result)
{
return new ReturnResult(false, ResultStatus.BadRequest);
}
public static implicit operator ReturnResult(BadRequestObjectResult result)
{
var message = result.ToString();
if (result.Value is SerializableError error)
{
var errorMessage = error.SelectMany(p => (string[])p.Value).Distinct();
message = string.Join(" | ", errorMessage);
}
return new ReturnResult(false, ResultStatus.BadRequest, message);
}
public static implicit operator ReturnResult(ContentResult result)
{
return new ReturnResult(true, ResultStatus.Success, result.Content);
}
public static implicit operator ReturnResult(NotFoundResult result)
{
return new ReturnResult(false, ResultStatus.NotFound);
}
#endregion
}
Now All Return in Api by this Format :
{
"success": true,
"status": 0,
"message": "success process"
}
In UserDto i Create a Validate in for Username and Password and Email then i need to return all error of them return by this format :
{
"success": true,
"status": 0,
"message": "Email Invalid | Password Invalid | Username Invalid"
}
But it not show me by this format , it show me this format :
{
"success": false,
"status": 2,
"message": "Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
}
Now how can I solve this problem ???? I found This problem here but doesn't explain why the code doesn't work?
I am new to Blazor and I am encountering the following issue when trying to post for data with an authentication token : at the time of the API call, an exception is lifted with the message "The JSON value could not be converted to System.Int32. Path: $ | LineNumber: 0 | BytePositionInLine: 1."
Here's the code in my blazor page's code-behind :
public partial class ContactCreate : AuthenticatedPageBase
{
[Inject]
public IContactDataService ContactDataService { get; set; }
[Inject]
public ICountryDataService CountryDataService { get; set; }
public Contact.Post Model { get; set; } = new Contact.Post();
protected string CountryIdString { get; set; } = string.Empty;
protected string TokenString { get; set; } = string.Empty;
public string ErrorMessage { get; set; } = string.Empty;
protected List<Country.ListItem> Countries { get; set; } = new List<Country.ListItem>();
protected async override Task OnInitializedAsync()
{
await base.OnInitializedAsync();
Countries = (await CountryDataService.GetCountryListAsync(Token.Token)).ToList();
TokenString = Token.Token;
}
protected async Task HandleValidSubmit()
{
try
{
Model.CountryId = int.Parse(CountryIdString);
var response = await ContactDataService.PostContactAsync(TokenString, Model);
NavManager.NavigateTo("/contacts");
}
catch(Exception ex)
{
ErrorMessage = ex.Message;
}
}
protected void HandleInvalidSubmit()
{
ErrorMessage = "Le formulaire n'est pas valide. Veuillez réessayer.";
}
}
and here's the relevant code in the data service :
public async Task<int> PostContactAsync(string token, Contact.Post model)
{
var response = await PostAuthenticatedAsync<int>(token, Url, model);
return response;
}
public async Task<T> PostAuthenticatedAsync<T>(string token, string url, object model)
{
var jsonBody = model.ToJson();
var request = new HttpRequestMessage()
{
RequestUri = new Uri(HttpClient.BaseAddress.ToString() + url),
Method = HttpMethod.Post,
Content = jsonBody
};
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
var response = await HttpClient.SendAsync(request);
return await response.FromJson<T>(Options);
}
...and the extension method that serializes the object into json :
public static StringContent ToJson(this object o)
{
return new StringContent(JsonSerializer.Serialize(o), Encoding.UTF8, "application/json");
}
Here's the object model that I'm passing through :
public class Contact
{
public class Post
{
[MaxLength(50)]
public string FirstName { get; set; }
[MaxLength(50)]
public string LastName { get; set; }
[MaxLength(50)]
public string CompanyName { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
[MaxLength(20)]
public string PostCode { get; set; }
[MaxLength(60)]
public string Locality { get; set; }
public int CountryId { get; set; }
}
}
And, finally, here's the API method that I'm trying to reach :
[HttpPost]
public async Task<ActionResult> PostContact(Contact.Post model)
{
try
{
var createdId = await _contactRepository.CreateAsync(model);
return Ok(new { Id = createdId });
}
catch (Exception ex)
{
return BadRequest(new { ex.Message });
}
}
Any idea what is happening or what actual exception lies behind this cryptic error message ?
P.S. : I know that there is a question with that exact exception message but it concerns .NET Core while I'm targeting .NET Standard 2.1. I've read it and it visibly doesn't apply to this case.
You are not returning an int (the Id). You're returning an anonymous object with an int property named Id.
Try
return Ok(createdId);
i have a model
public partial class TalentVendorShots
{
public int Id { get; set; }
public string Email { get; set; }
public string One { get; set; }
public string Two { get; set; }
public string Three { get; set; }
public string Four { get; set; }
public string Five { get; set; }
public string Six { get; set; }
public string Seven { get; set; }
public string Eight { get; set; }
public string Nine { get; set; }
public string Ten { get; set; }
}
and basic controllers
[Route("api/[controller]")]
[ApiController]
public class TalentVendorShotsController : ControllerBase
{
private readonly champagneDatabase _context;
public TalentVendorShotsController(champagneDatabase context)
{
_context = context;
}
// GET: api/TalentVendorShots
[HttpGet]
public async Task<ActionResult<IEnumerable<TalentVendorShots>>> GetTalentVendorShots()
{
return await _context.TalentVendorShots.ToListAsync();
}
// GET: api/TalentVendorShots/5
[HttpGet("{id}")]
public async Task<ActionResult<TalentVendorShots>> GetTalentVendorShots(int id)
{
var talentVendorShots = await _context.TalentVendorShots.FindAsync(id);
if (talentVendorShots == null)
{
return NotFound();
}
return talentVendorShots;
}
// PUT: api/TalentVendorShots/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTalentVendorShots(int id, TalentVendorShots talentVendorShots)
{
if (id != talentVendorShots.Id)
{
return BadRequest();
}
_context.Entry(talentVendorShots).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TalentVendorShotsExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/TalentVendorShots
[HttpPost]
public async Task<ActionResult<TalentVendorShots>> PostTalentVendorShots(TalentVendorShots talentVendorShots)
{
_context.TalentVendorShots.Add(talentVendorShots);
await _context.SaveChangesAsync();
return CreatedAtAction("GetTalentVendorShots", new { id = talentVendorShots.Id }, talentVendorShots);
}
// DELETE: api/TalentVendorShots/5
[HttpDelete("{id}")]
public async Task<ActionResult<TalentVendorShots>> DeleteTalentVendorShots(int id)
{
var talentVendorShots = await _context.TalentVendorShots.FindAsync(id);
if (talentVendorShots == null)
{
return NotFound();
}
_context.TalentVendorShots.Remove(talentVendorShots);
await _context.SaveChangesAsync();
return talentVendorShots;
}
private bool TalentVendorShotsExists(int id)
{
return _context.TalentVendorShots.Any(e => e.Id == id);
}
}
}
all of this works fine. i get information from the database fine. now i want to make a post to the table via uri. no body.for example
/api/TalentVendorShots/id=1,email=testemail should create a new record with id of 1 and email of testemail. how can i accomplish this?
The basic rule is, You should use POST if the action is not idempotent. Though you can pass the query parameters and no body to POST. But It would not make sense in this scenario. Basically query parameters are used to get/filter information.
Similar way many Web API testing tools like ARC, Swagger, and PostMan (chrome extension does not allow, but standalone application allows) does not allow to send body with the GET request. Though you can send the body in GET requests.
I am writing a very basic and hacky React and c#/.NET app to try to sharpen my skills.
I am sending an axios request from the front but when it hits the route the data is always null.
call from the front end
axios
.post(URL, {
"name": "me",
"text": "Hello World",
"date": "today",
"userId": 1
})
.then(res => {return res})
My Message Class
public class Message
{
[Key]
public int MessageId { get; set; }
public string Date { get; set; }
public string Text { get; set; }
public int UserID { get; set; }
}
}
My controller method
public async Task<object> Post(Message message)
{
using (var context = new DbContext())
{
System.Diagnostics.Debug.WriteLine(message);
context.Messages.Add(message);
await context.SaveChangesAsync();
}
}
When I debug and hit the breakpoint all of my values are null.
What am I missing here?
The answer is to put the [FromBody] attribute before my argument like this
public async Task<object> Post([FromBody] Message message)
{
using (var context = new DbContext())
{
System.Diagnostics.Debug.WriteLine(message);
context.Messages.Add(message);
await context.SaveChangesAsync();
}
}
Thanks to the comment on on my original post!
Here is my Post() method
[HttpPost]
[Consumes("Application/Json")]
public IActionResult Post([FromBody]Album value)
{
if(value==null)
{
return BadRequest("Album cannot be empty");
}
if(value.AlbumName==null)
{
return BadRequest("Album Name cannot be empty");
}
else if(value.AlbumName.Equals(""))
{
return BadRequest("Album Name cannot be empty");
}
if (value.AlbumReleasedate == null||value.AlbumReleasedate.Equals("") )
{
return BadRequest("Album Release Date cannot be empty");
}
if (value.CoverImageURL.Equals("") || value.CoverImageURL == null)
{
return BadRequest("Cover Image URL cannot be empty");
}
return Ok(value);
}
and this is the Album Class
public class Album
{
public int AlbumId;
public string AlbumName { get; set; }
public string CoverImageURL { get; set; }
public DateTime AlbumReleasedate { get; set; }
public Artist artist;
public List<Song> Songs;
}
here value.AlbumName is null.
when i send this request with Body using POSTMAN
{
"Album":{
"coverImageURL": "https://en.wikipedia.org/wiki/Let_Go_",
"albumReleasedate": "2002-06-04T00:00:00",
"albumName": "Let Go."
}
}
when I send a POST Request to my controller the data does not bind to the object i have used. How do i bind this data?
ema is right. You don't need the Album key. Just remove that and it'll work
{ "coverImageURL": "https://en.wikipedia.org/wiki/Let_Go_", "albumReleasedate": "2002-06-04T00:00:00", "albumName": "Let Go." }