skip to Main Content

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; }
    }
}

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

2

Answers


  1. 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 class="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 here
    enter image description here
    enter 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" id="firstName" name="firstName"/>
            <button class="btn btn-primary" onclick="Inquire()">check</button>
    </p>
    
    <table class="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="https://code.jquery.com/jquery-3.3.1.min.js"></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 here
    enter image description here

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search