0

I have a Date field in my DB and I'm trying to update it to the current Date when I press the submit button on my webpage but it does not update. I believe I'm doing the correct steps but here is my code.

Controller:

public ActionResult TakeInventory(int? AssetNum, string owners, string locationId, string clientId)
        {
            ViewBag.LocationId = new SelectList(db.Locations, "LocationKey", "LocationName");
            ViewBag.ClientId = new SelectList(db.ClientSites, "ClientSiteKey", "ClientSiteName");
            var records = from s in db.Assets select s;
            if (AssetNum != 0)
            {
                records = records.Where(c => c.AssetKey == AssetNum);
            }

            if (!String.IsNullOrEmpty(owners))
            {
                records = records.Where(x => x.InventoryOwner.Equals(owners));
            }

            if (!String.IsNullOrEmpty(locationId))
            {
                int locnum = Convert.ToInt32(locationId);
                records = records.Where(x => x.LocationKey == locnum);
            }

            if (!String.IsNullOrEmpty(clientId))
            {
                int clinum = Convert.ToInt32(clientId);
                records = records.Where(x => x.ClientSiteKey == clinum);
            }


            else
            {
                return View(records);
            }
            return View(records);

        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult TakeInventory([Bind(Include = "InventoryDate")] Asset asset)
        {
            if (ModelState.IsValid)
            {
                db.Entry(asset).State = EntityState.Modified;
                asset.InventoryDate = DateTime.Now;
                db.Assets.Add(asset);
                db.SaveChanges();
                return RedirectToAction("Index");

            }
            return View(asset);
        }

View:

@foreach (var items in Model)
    {
        <p>Last Inventory Date: @Html.DisplayFor(modelItem => items.InventoryDate) </p>
        <input type="submit" value="Submit" />

Model:

public partial class Asset
    {    
public System.DateTime InventoryDate { get; set; }
    public Asset()
      {
      InventoryDate = DateTime.Now;
      }
    }
Win
  • 61,100
  • 13
  • 102
  • 181
CRich
  • 57
  • 1
  • 8
  • Use view models, not data models in your view. Submit the view model, get the data model based on its ID, update data the data model based on the view model properties and save the data model. - [What is ViewModel in MVC?](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) –  Nov 28 '16 at 20:06
  • And you cannot bind to a collection using a `foreach` loop (and you view does not even have any form controls) so this code will never work (but its not clear what you expect to do when you submit –  Nov 28 '16 at 20:09
  • All I expect, when I press the submit button is to update my date field in my database. I've taken out the foreach loop and added the form-control class to it. But the db still does not update – CRich Nov 28 '16 at 20:17
  • You need to show more of the view (you passing a collection of `Asset` to the view which means that the parameter in the POST method must also be `IEnumerable` - currently your `Asset asset` parameter will not bind to anything –  Nov 28 '16 at 20:19
  • Ok, I changed my parameter type of my Asset asset to IEnumerable asset, and that still did not change anything. I also tried `Asset entity = new Asset()` after parameter failed and still no luck – CRich Nov 28 '16 at 20:27
  • Show the view!! –  Nov 28 '16 at 20:27
  • I know to `return View(asset)` but then all my code setting my field's time is invalid. – CRich Nov 28 '16 at 20:33
  • Show the view!! –  Nov 28 '16 at 20:35
  • Isn't that what I'm doing if I have `return View(asset);`? Also I took out the parameters and just added `Asset asset = new Asset();` – CRich Nov 28 '16 at 20:41
  • The code in your view - the `.cshtml` file! What you have shown does not even have a form. It has no form controls so nothing is ever submitted. And you cannot use a `foreach` loop to bind to a collection. –  Nov 28 '16 at 20:44
  • Ok, working on it. Got to change a ton of stuff around – CRich Nov 28 '16 at 21:01

3 Answers3

2

You want to retrieve the Asset entity again before updating again.

For example,

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult TakeInventory([Bind(Include = "InventoryDate")] Asset asset)
{
   if (ModelState.IsValid)
   {
      var entity = (from s in db.Assets where AssetNum == asset.AssetNum Select s).FirstOrDefalt();
      entity.InventoryDate = DateTime.Now;
      db.SaveChanges();
      return RedirectToAction("Index");
   }
   return View(asset);
}
Win
  • 61,100
  • 13
  • 102
  • 181
  • Tried that but still no change in my DB. Is there something I should do in my view? or to my Submit button? – CRich Nov 28 '16 at 20:08
  • Could you set a break point at `if (ModelState.IsValid)`, and debug the application? – Win Nov 28 '16 at 20:22
0

Is a bad practice: asset.InventoryDate = DateTime.Now;

At least, you need: 1. SaveChanges() your DbContext 2. Your DateTime field in backend must be Nullable or NotNull in Db (there is no inmpicit conversion)

But the real trouble is timezones. Its all works fine, if you have only one instance in only one datacenter and all your clients is from only one small and beauty country (one timezone wide)

DateTime.Now returns you local mashine timezone time.

If you use your 'entity.InventoryDate' in any kind of requests query it can return confused rezults, and can be surprized with funny result: for ex., value with tomorrow datetime relatively to you :)

For Web-services always cast to UTC that kind of fields, or use triggers or default expression for this kind of fields inside your DB engine

P.S. Russia is 11 timezones wide, i know what i'm talking about

  • If you use Code-First always mnake DateTime field nullable "DateTime?" or [Required] attributes. In most situations trouble is there, no implicit converion for nullables between Sql DateTime and CLR DateTime – Ivan Mokrov Nov 28 '16 at 20:19
0

Why you are passing the Current date , there is no need for that you can you Sql build in function "GETDATE()" to Get the current Date

Ghanshyam Singh
  • 1,361
  • 2
  • 15
  • 27