ASP.NET Core Error: The JSON value could not be converted to System.String [duplicate]

I am trying to perform a search functionality in ASP.NET Core. This is my controller:

[HttpPost("searchbyname")] public async Task<ActionResult<List<SelectedChildDto>>> SearchByName([FromBody]string firstName) { if (string.IsNullOrWhiteSpace(firstName)) { return new List<SelectedChildDto>(); } return await _context.Children .Where(x => x.FirstName.Contains(firstName)) .OrderBy(x => x.FirstName) .Select(x => new SelectedChildDto { Cld = x.Cld, ChildCode = x.ChildCode, FirstName = x.FirstName, PhotoPath = x.PhotoPath }) .Take(5) .ToListAsync(); }

I have this DTO class from the model

namespace API.Dtos
{ public class SelectedChildDto { public int Cld { get; set; } public string ChildCode { get; set; } public string FirstName { get; set; } public string PhotoPath { get; set; } }
}

This is my error output:

"errors": { "$": [ "The JSON value could not be converted to System.String. Path: $ | LineNumber: 0 | BytePositionInLine: 1." ] }

How can I fix this?

0

2 Answers

The problem is related to System.Text.Json deserialization of body text for the single [FromBody] string firstName argument of your controller. For example, you need just to send "John" in body instead of full-featured JSON {"firstName": "John"}.

Check also this answer to the similar question.

I don't know how you pass firstName in your view, but your data format is not correct.

If you just passed a string firstName without [FromBody],You can refer to the following code.

Controller:

 [HttpGet] public async Task<IActionResult> SearchByName() { var children = from m in _context.Children select m; return View(await children.ToListAsync()); }
[HttpPost]
public async Task<ActionResult<List<SelectedChildDto>>> SearchByName(string firstName)
{ if(string.IsNullOrWhiteSpace(firstName)) { return new List<SelectedChildDto>(); } return await _context.Children .Where(x => x.FirstName.Contains(firstName)) .OrderBy(x => x.FirstName) .Select(x => new SelectedChildDto { Id = x.Id, ChildCode = x.ChildCode, FirstName = x.FirstName, PhotoPath = x.PhotoPath }) .Take(5) .ToListAsync();
}

View:

@model IEnumerable<API.Models.SelectedChildDto>
<form asp-controller="Home" asp-action="SearchByName" method="post"> <p> Title:<input type="text" name="firstName"/> <input type="submit" value="check"/> </p>
</form>
<table> <thead> <tr> <th> @Html.DisplayNameFor(model => model.ChildCode) </th> <th> @Html.DisplayNameFor(model => model.FirstName) </th> <th> @Html.DisplayNameFor(model => model.PhotoPath) </th> </tr> </thead> <tbody>
@foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.ChildCode) </td> <td> @Html.DisplayFor(modelItem => item.FirstName) </td> <td> @Html.DisplayFor(modelItem => item.PhotoPath) </td> </tr>
} </tbody>
</table>

Test Result:enter image description hereenter image description hereenter image description here

And if you wish to use [FromBody], you can refer to the following code. Controller:

 [HttpGet] public async Task<IActionResult> SearchByName() { var children = from m in _context.Children select m; return View(await children.ToListAsync()); }
[HttpPost]
public async Task<ActionResult<List<SelectedChildDto>>> SearchByName([FromBody] string firstName)
{ if(string.IsNullOrWhiteSpace(firstName)) { return new List<SelectedChildDto>(); } return await _context.Children .Where(x => x.FirstName.Contains(firstName)) .OrderBy(x => x.FirstName) .Select(x => new SelectedChildDto { Id = x.Id, ChildCode = x.ChildCode, FirstName = x.FirstName, PhotoPath = x.PhotoPath }) .Take(5) .ToListAsync();
}

View:

@model IEnumerable<API.Models.SelectedChildDto>
<p> Title:<input type="text" name="firstName"/> <button onclick="Inquire()">check</button>
</p>
<table> <thead> <tr> <th> @Html.DisplayNameFor(model => model.ChildCode) </th> <th> @Html.DisplayNameFor(model => model.FirstName) </th> <th> @Html.DisplayNameFor(model => model.PhotoPath) </th> </tr> </thead> <tbody>
@foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.ChildCode) </td> <td> @Html.DisplayFor(modelItem => item.FirstName) </td> <td> @Html.DisplayFor(modelItem => item.PhotoPath) </td> </tr>
} </tbody>
</table>
<script src=""></script>
<script type="text/javascript"> function Inquire() { $.ajax({ contentType: 'application/json; charset=utf-8', dataType: 'JSON', url: '/Home/SearchByName', type: "post", data: JSON.stringify($("#firstName").val()), success: function (result) { alert(JSON.stringify(result)); }, failure: function (response) { console.log(response); } }); }
</script>

Test Result:enter image description hereenter image description here

1

You Might Also Like