简体   繁体   中英

Send List<T> as an optional parameter in the post body in ASP.NET Core Web Api

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM