I had this model which was taking optional params for a post request body:
public class ReportFilterModel
{
public int? ReportStatusId { get; set; }
public Guid? AreaID { get; set; }
}
This would do a search in DB according to the filters given by user:
var report = _context.tbl_Reports.AsQueryable();
if (model.ReportStatusId.IsNotNull())
report = report.Where(x => x.IsDeleted == false && x.ReportStatusId == (StatusEnum)model.ReportStatusId.Value);
if (model.Area.IsNotNull())
report = report.Where(x => x.IsDeleted == false && x.Area.Id == model.AreaId);
And then it'd finally return this:
finalReports = await report
.Where(x => x.IsDeleted == false)
.Select(x => new ReportsWithFiltersModel
{
Id = x.Id,
Area = Id,
UserId = x.UserId,
ReportStatus = x.ReportStatusId.GetEnumDescription(),
}).ToListAsync();
All this working absolutely fine, but now I want to give a list of optional params like this:
public class ReportFilterModel
{
public List<int>? ReportStatusId { get; set; }
public List<Guid>? AreaID { get; set; }
}
This is giving an exception
'List<int>' does not contain a definition for 'Value' and no accessible extension method 'Value' accepting a first argument of type 'List<int>' could be found (are you missing a using directive or an assembly reference?)
How do I fix this?
? Does not stand for optional. It means Nullable where T is value type (It applies to value types and makes them nullable).
Reference types, such as Lists are already nullable.
List<int> x = null; //valid version of what you are trying to achieve with List<int>?
int? or Nullable<int> //valid
List<int?> x or List<Nullable<int>> ; //valid
You are mixing two concepts nullable value types and nullable reference types (added in C# 8.0). Nullabale value types marked with ?
are basically shortcut for Nullable<T>
and they have Value
property. List<T>
(in your case List<int>
and List<Guid>
) is reference type and it does not have Value
property and marking it with ?
makes compiler aware that this property can contain null
reference and make it able to enforce rules to ensure that you've correctly checked this property for a null reference. So in the nutshell your List<int>? ReportStatusId
List<int>? ReportStatusId
and List<Guid>? AreaID
List<Guid>? AreaID
already "optional" and ?
makes compiler aware of that.
Hot to fix that?
Change
if (model.ReportStatusId.IsNotNull())
report = report.Where(x => x.IsDeleted == false && x.ReportStatusId == (StatusEnum)model.ReportStatusId.Value);
to
if (model.ReportStatusId.IsNotNull() && model.ReportStatusId.Any())
var statuses = model.ReportStatusId.Cast<StatusEnum>().ToList();
report = report.Where(x => x.IsDeleted == false && statuses.Contains(x.ReportStatusId));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.