views:

277

answers:

3

I've got a field which its type is byte[]. This field will hold my entity's RecordVersion property (timestamp in the database). How do I keep this field so that when I save my entity it is available?

I've tried two different things and haven't succeeded so far: This renders "System.Byte[]":

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

This throws a ModelStateError where the type couldn't be converted:

ViewData["RecordVersion"] = entity.RecordVersion

Apparently the default MVC's mechanism that does the bind/unbind doesn't like much byte[] fields .....

A: 

I wouldn't put the timestamp on the form. If you want to keep the object around I'd cache it server side and retrieve it from the cache using the id. Otherwise, you can re-retrieve the object from the database and apply the changes from your form data. The latter is what I do, using TryUpdateModel.

public ActionResult Update( int id )
{
     using (var context = new DataContext())
     {
         var model = context.Models.Where( m => m.ID == id ).Single();
         if (TryUpdateModel( model ))
         {
            ...
            context.SubmitChanges(); // wrapped in try/catch
            ...
         }
         else
         {
            ...
         }
     }
     return RedirectToAction( "Show", new { id = id } );
}
tvanfosson
@ tvanfosson - This is a nice way and I know that apparently is the most common way of replay your changes. I'm just trying to keep my object's Id and RecordVersion in my form so that I can use my own framework to reply the changes (i.e. I didn't need to re-query the entity ... )
afgallo
A: 

Have you tried.

<%= Html.Hidden("RecordVersion", System.Text.Encoding.Unicode.GetString(Model.RecordVersion)) %>
KaraT
it seemed that it renders a string in the form but on the way back it still doesn't convert back to a byte[] ....
afgallo
You can modelbinder where you can use Encoding.Unicode.GetBytes to convert it back to a byte array.
KaraT
+2  A: 

You need to make a modelbinder and register it.

This article shows how to use a timestamp from a linq database in a hidden field much like what you are doing.

 ModelBinders.Binders.Add(typeof(Binary), new LinqBinaryModelBinder());

In global.asax to register it.

That LinqBinaryModelBinder is in the futures assembly. If you want to user byte[] you'll have to write one yourself.

AndreasN
The safest thing would probably be to represent the byte[] as a base64-string.
Thomas Eyde
Works just fine with ModelBinders.Binders.Add(typeof(Binary), new LinqBinaryModelBinder());Thanks.
afgallo