Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC.NET milliseconds get lost when using Html.hidden on a DateTime LastUpdated column for version tracking

Question in short:

How tot do this in MVC.NET?

Question in long version:

Im trying to use a DateTime column in a SQL Table for version tracking (this in itself is proposed as a solution to re-attaching a Linq2Sql data class after being passedback by a editview for the table)

But now i get 'row not found or changed'-exception. on the ctx.submit:

 ctx.appointments.Attach(appointment,true);
 ctx.SubmitChanges();

where ctx is my Linq datacontext, appointments my table, and appointment the appointment object i try to attach.. Ive setup the appointments table as sugested here

This problem was also noted by a reader of the suggested solution. He suggested this as a solution.

Problem here is im not using webforms, im using MVC.NET. So i'm guessing using

            <%= Html.Hidden("LastUpdate", Model.LastUpdate) %>                

makes the LastUpdate property change. So is there a way to make sure i get the same (or at least equal) DateTime object when this is passed back into my update action?

Im using the suggested gettime() trigger on update of my appointments table. this obviously stores an sql datetime object. which might not be precicely parsed by Linq2SQL. I guess this also adds into the problem.

I'm hoping there's a solution for this. I know just using the timestamp format would solve it also.. but that's outside the scope of this question

like image 385
ArjanW Avatar asked Feb 11 '10 21:02

ArjanW


2 Answers

I think the problem is that writing out the last update time into a hidden field like that will just do a ToString on the date which by default won't render out the milliseconds. You could try rendering out the timestamp as some absolute value such as ticks:

<%= Html.Hidden("LastUpdate", Model.LastUpdate.Ticks) %>

You can then reconstruct your datetime on the other side by converting the value back into a long & reconstructing the DateTime:

var dt = new DateTime(Int64.Parse(ticks));
like image 96
Alconja Avatar answered Oct 25 '22 23:10

Alconja


You won't belive me, but try this: Before the return on your controller, do a

ModelState.Remove("LastUpdate");
return View(model);

Reason, someone on infinite confidence decide Html.Hidden would keep "posted" values discarding modifications. Even when created on c# on the same page.

This simple way you delete it from the ModelState so it catches the new value instead of posted.

Some people says the default behaviour its right, but please, I was working with a hand-made grid with an integrated company search (company/products), and a hidden field for the key of the products(a long). Changing the company posted on the same page.

<%= Html.Hidden("detalleProductos[" + i + "].PRO_PRODUCTOEMPRESAID", item.PRO_PRODUCTOEMPRESAID)%>
<%= Html.Hidden("detalleProductos[" + i + "].DET_DETALLEENCUESTAID", item.DET_DETALLEENCUESTAID)%>

I spent so many hours trying to figure out WHY it updated the wrong company (the first I loaded). Because it remembered the first one and discarded the modification I made on c# on the same page. Hard to catch.

Finally I had to do this:

foreach (var s in ModelState.Keys.ToList())
                if (s.StartsWith("detalleProductos"))
                    ModelState.Remove(s);

I was so frustrated I decided to post my workaround...

Good luck!

like image 33
jorge Avatar answered Oct 25 '22 22:10

jorge