Search code examples
c#json.netasp.net-core-mvcfilteringdynamic-tables

How do I add an search-function to a Table that displays Json-data?


My ASP.NET Core project displays data from a Json file as a table on a Razor page.

Now I want to add an search function so it only shows "objects" with the selected userId.

I added an search bar on the razor page but I do not how to use the Searchstring to filter everything that is not selected out.

This is my Razor page that displays the table (ToDoModel.cshtml)

@model List<ToDo.Models.ToDoStructure>
@{
    ViewBag.Title = "ToDoModel";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<form asp-action="ToDoModel" method="get">
    <div class="form-actions no-color">
        <p>
            Find by userId: <input type="text" name="SearchString" value="@ViewData["CurrentFilter"]" />
            <input type="submit" value="Search" class="btn btn-default" /> |
            <a asp-action="ToDoModel">Back to Full List</a>
        </p>
    </div>
</form>

<h2>ToDo-List</h2>
@{ 
    <table border="1">
        <tr>
            <th>UserId</th>
            <th>Id</th>
            <th>Name</th>
            <th>Erledigt</th>
        </tr>
    @foreach (var t in Model)
     {
        <tr>
            <th>@Html.DisplayFor(modelItem => t.userId)</th>
            <th>@t.id</th>
            <th>@t.title</th>
            <th>@t.completed</th>
        </tr>
     }
         
    </table>
}

The controller (ToDoData.cs)

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using ToDo.Models;
using System.Net;

namespace ToDo.Controllers
{
    public class ToDoData : Controller
    {
        public ActionResult ToDoModel(string searchString)
        {
            ViewData["CurrentFilter"] = searchString;
            var webClient = new WebClient();
                webClient.Headers.Add(HttpRequestHeader.Cookie, "cookievalue");
                var json = webClient.DownloadString(@"https://jsonplaceholder.typicode.com/todos");
                var _toDoData = JsonConvert.DeserializeObject<List<ToDoStructure>>(json);

            return View(_toDoData);
        }
    }
}

(ToDoStrucuture.cs)

namespace ToDo.Models
{
    public class ToDoStructure
    {
        public int userId { get; set; }
        public int id { get; set; }
        public string title { get; set; }
        public bool completed { get; set; }
    }
}

I tried to figure it out by myself and found people using _context but I do not know what it is.


Solution

  • If you play around with the provided link, the API service does provide the data filtering feature.

    For example, link: https://jsonplaceholder.typicode.com/todos?userId=1

    [
      {
        "userId": 1,
        "id": 1,
        "title": "delectus aut autem",
        "completed": false
      },
      {
        "userId": 1,
        "id": 2,
        "title": "quis ut nam facilis et officia qui",
        "completed": false
      },
      {
        "userId": 1,
        "id": 3,
        "title": "fugiat veniam minus",
        "completed": false
      },
      {
        "userId": 1,
        "id": 4,
        "title": "et porro tempora",
        "completed": true
      },
      {
        "userId": 1,
        "id": 5,
        "title": "laboriosam mollitia et enim quasi adipisci quia provident illum",
        "completed": false
      },
      {
        "userId": 1,
        "id": 6,
        "title": "qui ullam ratione quibusdam voluptatem quia omnis",
        "completed": false
      },
      {
        "userId": 1,
        "id": 7,
        "title": "illo expedita consequatur quia in",
        "completed": false
      },
      {
        "userId": 1,
        "id": 8,
        "title": "quo adipisci enim quam ut ab",
        "completed": true
      },
      {
        "userId": 1,
        "id": 9,
        "title": "molestiae perspiciatis ipsa",
        "completed": false
      },
      {
        "userId": 1,
        "id": 10,
        "title": "illo est ratione doloremque quia maiores aut",
        "completed": true
      },
      {
        "userId": 1,
        "id": 11,
        "title": "vero rerum temporibus dolor",
        "completed": true
      },
      {
        "userId": 1,
        "id": 12,
        "title": "ipsa repellendus fugit nisi",
        "completed": true
      },
      {
        "userId": 1,
        "id": 13,
        "title": "et doloremque nulla",
        "completed": false
      },
      {
        "userId": 1,
        "id": 14,
        "title": "repellendus sunt dolores architecto voluptatum",
        "completed": true
      },
      {
        "userId": 1,
        "id": 15,
        "title": "ab voluptatum amet voluptas",
        "completed": true
      },
      {
        "userId": 1,
        "id": 16,
        "title": "accusamus eos facilis sint et aut voluptatem",
        "completed": true
      },
      {
        "userId": 1,
        "id": 17,
        "title": "quo laboriosam deleniti aut qui",
        "completed": true
      },
      {
        "userId": 1,
        "id": 18,
        "title": "dolorum est consequatur ea mollitia in culpa",
        "completed": false
      },
      {
        "userId": 1,
        "id": 19,
        "title": "molestiae ipsa aut voluptatibus pariatur dolor nihil",
        "completed": true
      },
      {
        "userId": 1,
        "id": 20,
        "title": "ullam nobis libero sapiente ad optio sint",
        "completed": true
      }
    ]
    

    For filtering the selected userId, you need to provide the query parameter in the url as:

    var json = webClient.DownloadString($"https://jsonplaceholder.typicode.com/todos?userId={searchString}");
    
    
    public ActionResult ToDoModel(string searchString)
    {
        ViewData["CurrentFilter"] = searchString;
        var webClient = new WebClient();
        webClient.Headers.Add(HttpRequestHeader.Cookie, "cookievalue");
    
        string uri = @"https://jsonplaceholder.typicode.com/todos";
        if (!String.IsNullOrEmpty(searchString))
            uri = uri + $"?userId={searchString}";
        
        var json = webClient.DownloadString(uri);
        var _toDoData = JsonConvert.DeserializeObject<List<ToDoStructure>>(json);
    
        return View(_toDoData);
    }
    

    The above URL will lead to a result that the data filtering is on the server side.


    Or you can also perform the data filtering in the memory as:

    1. By retrieving all the data from the server.
    2. Use System.Linq .Where() to filter data.
    using System.Linq;
    
    public ActionResult ToDoModel(string searchString)
    {
        ViewData["CurrentFilter"] = searchString;
    
        if (!Int32.TryParse(searchString, out int userId)
        {
            // Handle when user provides searchString is not a valid integer.
            // return to view
        }
        var webClient = new WebClient();
        webClient.Headers.Add(HttpRequestHeader.Cookie, "cookievalue");
    
        string uri = @"https://jsonplaceholder.typicode.com/todos";
    
        var json = webClient.DownloadString(uri);
        var _toDoData = JsonConvert.DeserializeObject<List<ToDoStructure>>(json);
        _toDoData = _toDoData.Where(x => x.userId == userId)
            .ToList();
    
        return View(_toDoData);
    }