Home > Net >  ASP.NET Core MVC : retrieve DateTime from database into view
ASP.NET Core MVC : retrieve DateTime from database into view

Time:10-15

I'm quite new to ASP.NET Core MVC and I'm having trouble retrieving a DateTime value from the database into the 'Edit' razor view.

I can use the scaffolded views to create a new Activity Item and this displays correctly in the 'Index' list, and in the 'Details' view, but when I attempt to 'Edit' the entry the DateTime value doesn't pull through from the database.

I've done plenty of reading but the main thing I seem to get in search results is information about JQuery Datepickers.

Any advice on where to look, how to resolve would be very much appreciated.

Here is my model:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MISDataRepo.Models
{
    [Table("Activity",Schema = "coir")]
    public partial class ActivityItem
    {
        public ActivityItem()
        {
            ActivityIdentifier = new HashSet<ActivityIdentifier>();
        }

        [Key]
        public int ActivityItemId { get; set; }

        [Required(ErrorMessage = "A valid Activity Name is required.")]
        [Display(Name = "Activity Name")]
        [StringLength(100)]
        public string ActivityName { get; set; }

        [Required]
        [Display(Name = "Activity Type")]
        public int ActivityTypeId { get; set; }

        [Required]
        [Display(Name = "Date Activity Created")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime DateCreated { get; set; }

        [Display(Name = "Date Activity Modified")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime? DatetModified { get; set; }

        [Required]
        [Display(Name = "Created By (Employee ID)")]
        [RegularExpression("^[1-9][0-9]{6}$", ErrorMessage = "A valid Employee ID is required!")]
        public int? CreatedBy { get; set; }

        [Display(Name = "Project Co-Ordinator (Employee ID)")]
        [RegularExpression("^[1-9][0-9]{6}$", ErrorMessage = "A valid Employee ID is required!")]
        public int? PC { get; set; }

        [DefaultValue(true)]
        public bool Live { get; set; }

        public virtual ActivityType ActivityType { get; set; }

        public virtual ICollection<ActivityIdentifier> ActivityIdentifier { get; set; }
    }
}

Here is the view:

@model MISDataRepo.Models.ActivityItem

@{
    ViewData["Title"] = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Edit</h1>

<h4>ActivityItem</h4>
<hr />
<div >
    <div >
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" ></div>
            <input type="hidden" asp-for="ActivityItemId" />
            <div >
                <label asp-for="ActivityName" ></label>
                <input asp-for="ActivityName"  />
                <span asp-validation-for="ActivityName" ></span>
            </div>
            <div >
                <label asp-for="ActivityTypeId" ></label>
                <select asp-for="ActivityTypeId"  asp-items="ViewBag.ActivityTypeId"></select>
                <span asp-validation-for="ActivityTypeId" ></span>
            </div>
            <div >
                <label asp-for="DateCreated" ></label>
                <input asp-for="@Html.DisplayFor(a => a.DateCreated)"  />
                <span asp-validation-for="DateCreated" ></span>
                @*<input type="hidden" asp-for="DateCreated"   type="date" placeholder="Enter Date Created" value="@Model.DateCreated" />*@
            </div>
            <div >
                <label asp-for="DatetModified" ></label>
                <input asp-for="@Html.DisplayFor(a => a.DatetModified)"  />
                <span asp-validation-for="DatetModified" ></span>
            </div>
            <div >
                <label asp-for="CreatedBy" ></label>
                <input asp-for="CreatedBy"  />
                <span asp-validation-for="CreatedBy" ></span>
            </div>
            <div >
                <label asp-for="PC" ></label>
                <input asp-for="PC"  />
                <span asp-validation-for="PC" ></span>
            </div>
            <div >
                <label >
                    <input  asp-for="Live" /> @Html.DisplayNameFor(model => model.Live)
                </label>
            </div>
            <div >
                <input type="submit" value="Save"  />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Here are the 'Edit' methods of the controller

// GET: ActivityItems/Edit/5
public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var activityItem = await _context.ActivityItem.FindAsync(id);

    if (activityItem == null)
    {
        return NotFound();
    }

    ViewData["ActivityTypeId"] = new SelectList(_context.ActivityType, "ActivityTypeId", "ActivityTypeName", activityItem.ActivityTypeId);
    return View(activityItem);
}

// POST: ActivityItems/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to, for 
// more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
//public async Task<IActionResult> Edit(int id, [Bind("ActivityItemId,ActivityName,ActivityTypeId,DateCreated,DatetModified,CreatedBy,PC,Live")] ActivityItem activityItem)
public async Task<IActionResult> Edit(int id, [Bind("ActivityItemId,ActivityName,ActivityTypeId,DatetModified,CreatedBy,PC,Live")] ActivityItem activityItem)
{
    if (id != activityItem.ActivityItemId)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(activityItem);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!ActivityItemExists(activityItem.ActivityItemId))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return RedirectToAction(nameof(Index));
    }

    ViewData["ActivityTypeId"] = new SelectList(_context.ActivityType, "ActivityTypeId", "ActivityTypeName", activityItem.ActivityTypeId);

    return View(activityItem);
}

CodePudding user response:

But when I attempt to 'Edit' the entry the DateTime value doesn't pull through from the database.

Yes, the issue you are having with the your View is pretty obvious due to your HTML Helper atrribute that is @Html.DisplayFor and the Property you have defined within your Model ActivityItem. You are probably getting following issue.

Problem:

enter image description here

How To Resolve:

Either you could use ViewModel or you can redefine your property public DateTime DateCreated { get; set; } by get rid of your annotations. However, I would prefer to use ViewModel. On the other hands, use the property like asp-for="DateCreated" within your edit view and get rid of your additional HTML helper class @Html.DisplayFor. Follow the below steps.

View Model:

public class ActivityItemViewModel
{

    public int ActivityItemId { get; set; }
    public string ActivityName { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime? DatetModified { get; set; }
}

Note: While loading your Edit view you certainly doesn't require annotations so you can ommit that.

View :

In view you are using additional HTML helper class @Html.DisplayFor which is not required in this scenario. You could try as following:

@model DotNet6MVCWebApp.Models.ActivityItemViewModel

@{
    ViewData["Title"] = "Edit";
   
}

<h1>Edit</h1>

<h4>ActivityItem</h4>
<hr />
<div >
    <div >
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" ></div>
            <input type="hidden" asp-for="ActivityItemId" />
            <div >
                <label asp-for="ActivityName" ></label>
                <input asp-for="ActivityName"  />
                <span asp-validation-for="ActivityName" ></span>
            </div>

            <div >
                <label asp-for="DateCreated" ></label>
                <input asp-for="DateCreated"  />
                <span asp-validation-for="DateCreated" ></span>
            </div>
            <div >
                <label asp-for="DatetModified" ></label>
                <input asp-for="DateCreated"  />
                <span asp-validation-for="DatetModified" ></span>
            </div>
            <div >
                <input type="submit" value="Save"  />
            </div>
        </form>
    </div>
</div>
<div>
    <a asp-action="ActivityList">Back to List</a>
</div>

Output:

enter image description here

  • Related