D.M
D.M

Reputation: 427

Display Results by Date ASP.NET MVC

Can anybody please tell me where I am going wrong with this. I have a list of errors and I want to be able to search by date. For example, if I selected the date, 20/08/2015, from a date picker, then I want the list to just show errors from that date. By default it will show all the errors in the database, but when a date is selected, I want to show only the errors from that date.

Controller

[HttpPost]
public ActionResult Index(string sortOrder, int? page, DateTime? datePicker)
{
    ViewBag.CurrentSort = sortOrder;
    ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

    DateTime userSelectedDate = DateTime.Parse(Request["datePicker"]);

    var applications = from s in db.ElmahErrors
                       where s.TimeUtc == userSelectedDate
                       select s;

    switch (sortOrder)
    {
        default:
            applications = applications.OrderByDescending(x => x.TimeUtc);
            break;
    }

    int pageSize = Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["DefaultPageSize"]);
    int pageNumber = (page ?? 1);
    return View(applications.ToPagedList(pageNumber, pageSize));
}

View

 @using (Html.BeginForm())
{
    <label for="datePicker">Find By Date:</label>

    @Html.TextBox("datePicker", null, new { @type = "date" })

    <input id="submitBtn" type="submit" value="Search" />
}

The userSelectedDate variable is taking in the value from the date picker, but it doesn't match any of the errors. Can somebody please help?

Thanks in advance.

Upvotes: 1

Views: 1882

Answers (3)

evictednoise
evictednoise

Reputation: 593

I think your s.TimeUtc is clearly never equal to userSelectedDate;

Why, because you have a datePicker which implies you can't select time on it, then you parse it to a DateTime which defaults the time to some value, then you compare it to s.TimeUtc and I believe it will be a millisecond comparision which you are not likely to hit in the nearest decade.

So I suggest you do something like

s.TimeUtc.ToLocalTime().Date == userSelectedDate.Date

Upvotes: 0

RePierre
RePierre

Reputation: 9566

As @Chris Disley pointed out you need to select errors based on a date. The usual approach for this is when you have a date, select all the lines where the date is between the date and the next day. Something like this:

[HttpPost]
public ActionResult Index(string sortOrder, int? page, DateTime? datePicker)
{
    ViewBag.CurrentSort = sortOrder;
    ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

    DateTime userSelectedDate = DateTime.Parse(Request["datePicker"]);

    var startDate = userSelectedDate.Date;
    var endDate = startDate.AddDays(1);

    var applications = from s in db.ElmahErrors
                   where s.TimeUtc >= startDate && s.TimeUtc < endDate
                   select s;

    switch (sortOrder)
    {
        default:
            applications = applications.OrderByDescending(x => x.TimeUtc);
            break;
    }

    int pageSize = Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["DefaultPageSize"]);
    int pageNumber = (page ?? 1);
    return View(applications.ToPagedList(pageNumber, pageSize));
}

Upvotes: 1

Chris Disley
Chris Disley

Reputation: 1355

You're selecting based on a DateTime, not a Date, so the records would have to occur at exactly the time (down to the millisecond) that your DateTime variable is set to. To do what you're after, you'll need to do a little more to your select query to match just the date parts. There are a few ways to do this, but this SO question sums them up pretty well:

How to compare only date components from DateTime in EF?

Essentially, the simplest way is to use the EntityFunctions.TruncateTime method on both dates within your predicate.

Upvotes: 4

Related Questions