Share via

Pagination - String Property in Controller Warning (Green Underline)

Dean Everhart 1,541 Reputation points
2022-11-30T16:14:04.81+00:00

.
.

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Threading.Tasks;  
using Microsoft.AspNetCore.Mvc;  
using Microsoft.AspNetCore.Mvc.Rendering;  
using Microsoft.EntityFrameworkCore;  
using Project.Data;  
using Project.Models;  
  
namespace Project.Controllers  
{  
    public class ModelController : Controller  
    {  
        private readonly ProjectContext _context;  
  
        public ModelController(ProjectContext context)  
        {  
            _context = context;  
        }  
  
        //GET: Model  
  
        public async Task<IActionResult> Index(string sortOrder, string currentFilter, string searchString, int? pageNumber)  
  
        // ********************* Previous **************************  
  
        //public async Task<IActionResult> Index(string sortOrder, string searchString)  
  
        {  
            ViewData["Text"] = String.IsNullOrEmpty(sortOrder) ? "text_desc" : "";  
            ViewData["Number"] = sortOrder == "Number" ? "number_desc" : "Number";  
            ViewData["CurrentFilter"] = searchString;  
            ViewData["CurrentSort"] = sortOrder;  
  
            if (searchString != null)  
            {  
                pageNumber = 1;  
            }  
            else  
            {  
                searchString = currentFilter;  
            }  
  
            var models = from s in _context.Models  
                           select s;  
  
            if (!String.IsNullOrEmpty(searchString))  
            {  
                models = models.Where(s => s.Text.Contains(searchString));  
  
                                     // || s.Number.Contains(searchString)  
            }  
  
            switch (sortOrder)  
            {  
                case "text_desc":  
                    models = models.OrderByDescending(s => s.Text);  
                    break;  
                case "Number":  
                    models = models.OrderBy(s => s.Number);  
                    break;  
                case "number_desc":  
                    models = models.OrderByDescending(s => s.Number);  
                    break;  
                default:  
                    models = models.OrderBy(s => s.Text);  
                    break;  
            }  
  
            int pageSize = 3;  
            return View(await PaginatedList<Model>.CreateAsync(models.AsNoTracking(), pageNumber ?? 1, pageSize));  
  
        }  


@model PaginatedList<Project.Models.Model>  
  
@********************** Previous **********************  
  
@model IEnumerable<Project.Models.Model>*@  
  
@{  
    ViewData["Title"] = "Index";  
}  
  
<h1>Index</h1>  
  
<p>  
    <a asp-action="Create">Create New</a>  
</p>  
  
<form asp-action="Index" method="get">  
    <div class="form-actions no-color">  
        <p>  
            Find by name: <input type="text" name="SearchString" value="@ViewData["CurrentFilter"]" />  
            <input type="submit" value="Search" class="btn btn-default" /> |  
            <a asp-action="Index">Back to Full List</a>  
        </p>  
    </div>  
</form>  
  
@********************** Previous **********************  
  
<form asp-controller="Model" asp-action="Index"></form>*@  
  
<table class="table">  
    <thead>  
        <tr>  
            <th>  
               <a asp-action="Index" asp-route-sortOrder="@ViewData["Text"]" asp-route-currentFilter="@ViewData["CurrentFilter"]">Text</a>  
  
               @*<a asp-action="Index" asp-route-sortOrder="@ViewData["Text"]">@Html.DisplayNameFor(model => model.Text)</a>*@  
  
               @* @Html.DisplayNameFor(model => model.Text)*@  
            </th>  
  
            <th>  
                <a asp-action="Index" asp-route-sortOrder="@ViewData["Number"]" asp-route-currentFilter="@ViewData["CurrentFilter"]">Number</a>  
  
                @*<a asp-action="Index" asp-route-sortOrder="@ViewData["Number"]">@Html.DisplayNameFor(model => model.Number)</a>*@  
  
                @*@Html.DisplayNameFor(model => model.Number)*@  
            </th>  
            <th>  
                Bool  
                @*@Html.DisplayNameFor(model => model.Bool)*@  
            </th>  
            <th>  
                Date  
                @*@Html.DisplayNameFor(model => model.Date)*@  
            </th>  
            <th></th>  
        </tr>  
    </thead>  
    <tbody>  
@foreach (var item in Model) {  
        <tr>  
            <td>  
                @Html.DisplayFor(modelItem => item.Text)  
            </td>  
            <td>  
                @Html.DisplayFor(modelItem => item.Number)  
            </td>  
            <td>  
                @Html.DisplayFor(modelItem => item.Bool)  
            </td>  
            <td>  
                @Html.DisplayFor(modelItem => item.Date)  
            </td>  
            <td>  
                <a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |  
                <a asp-action="Details" asp-route-id="@item.ID">Details</a> |  
                <a asp-action="Delete" asp-route-id="@item.ID">Delete</a>  
            </td>  
        </tr>  
}  
    </tbody>  
</table>  
  
@{  
    var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";  
    var nextDisabled = !Model.HasNextPage ? "disabled" : "";  
}  
  
<a asp-action="Index"  
   asp-route-sortOrder="@ViewData["CurrentSort"]"  
   asp-route-pageNumber="@(Model.PageIndex - 1)"  
   asp-route-currentFilter="@ViewData["CurrentFilter"]"  
   class="btn btn-default @prevDisabled">  
    Previous  
</a>  
<a asp-action="Index"  
   asp-route-sortOrder="@ViewData["CurrentSort"]"  
   asp-route-pageNumber="@(Model.PageIndex + 1)"  
   asp-route-currentFilter="@ViewData["CurrentFilter"]"  
   class="btn btn-default @nextDisabled">  
    Next  
</a>  

.
.
using System.ComponentModel.DataAnnotations;

namespace Project.Models
{
public class Model
{
public int ID { get; set; }

    public string? Text { get; set; }  

    public int? Number { get; set; }  

    public bool? Bool { get; set; }  

    [DataType(DataType.Date)]  
    public DateTime? Date { get; set; }  
}  

}

Code on Github

Developer technologies | ASP.NET Core | Other

Answer accepted by question author

Anonymous
2022-12-01T09:30:56.19+00:00

Hi @Dean Everhart ,

50 models = models.Where(s => s.Text.Contains(searchString)); <- "s.Text" is underlined in green after adding pagination.

If you move the mouse over the "s.Text", you can see it will show the CS8602 nullable warnings, it means this property might be null. Because the Text property is nullable: public string? Text { get; set; }

266013-image.png

To disable this warning, you can change the Text property to not-null or add a missing null check. You can try to use the following code:

models = models.Where(s => s.Text != null && s.Text.Contains(searchString));  

52 // || s.Number.Contains(searchString) <- had to comment out this line for code to work. It was stating that it couldn't search on a number?

The Contains method is a String class's method, so, you can't directly use it with the Int number. If you want to check whether the number contains special number, you can convert it to a String, then use the Contains method. Code like this:

models.Where(s => s.Number.GetValueOrDefault().ToString().Contains(searchString));  

To combine them, the query statement as below:

models.Where(s => (s.Text != null && s.Text.Contains(searchString)) || s.Number.GetValueOrDefault().ToString().Contains(searchString));  

If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Best regards,
Dillion

Was this answer helpful?


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.