[MVC 3] MvcImage Project……Its Alive!…..


Over the last few months i have done the following blog posts to explain how to handle images using MVC and various technologies like JQuery and Entity Framework. Now the majority of hits i receive are concerning these blogs posts, so obviously Image Handling is a common Achilles heel. The posts are also being referenced in forums to answer Image related questions. So i have decided to create a Open Source project which combines all of these blog posts into one solution for people to use. This project can be found here for anyone who wants to use it:

Codeplex: http://mvcimage.codeplex.com/

Github: http://garfbradaz.github.com/MvcImage/

At the moment it includes everything i have blogged about and shows you how to extend the RegisterModel to include adding Images when registering a new user. I will be adding the following to the project moving forward as i want this to an organic project that grows:

  1. Adding Thumbnails to the database and displaying these
  2. A details page of users so you can view their details and the images – A User Dashboard for the Admin
  3. A Image FileResult.
  4. A PDF document explaining what the Project does and where.

MY ORIGINAL BLOG POSTS – Image Handlers – JQuery/ASP.NET/SQL DB & Entity Framework (MVC3)

Tutorial 1 – Image Preview – JQuery

Tutorial 2 – Image Preview – HTML Helpers

Tutorial3 – Upload Image – SQL Server & Entity Framework

Tutorial 4 – Images – Downloading Images

Tutorial 5 – Thumbnail Support

Enhanced by Zemanta

[MVC 3] Entity Framework and Serializing JSON–Circular References


ADO.NET Entity Framework stack

Image via Wikipedia

I’m at the moment trying to write a light-weight AJAX control for my home page, which displays New Properties which have been added, aptly named WhatsNew.

The issue i had was the following error which i inspected in Fiddler when i didn’t have any JSON returned to my view:

A circular reference was detected while serializing an object type of “System.Data.Metadata.Edm.Properties”

A bit of googling, and it seems the JavaScriptSerializer has gets it knickers in a twist trying to traverse your Entity Framework objects which have relationships.

There are many options, but the one i took was to make the JSON as lightweight as possible and pass a ViewModel with only and not Entity Framework at objects at all. I build the view model based on data from the Entity Framework.

Here is my viewModel – the List was my old implementation which was causing the problems.

This will be returned as a JSON ActionResult to my view.  Bingo – I’ve fixed the issue! Smile

public class WhatsNewViewModel {
    //public List<PropertyViewModel> Properties { get; set; } 
 public string UniqiueKey { get; set; }
    public string Area { get; set; }
    public string PropertyType { get; set; }
}

Enhanced by Zemanta

[MVC 3] ObjectSet Extension Method–CountAll


I find myself when using Entity Framework, before accessing any of Objects i have various try/catch methods, due to the amount of exceptions that “bubble” up.

 

Now before i try and access my ObjectSet’s within my ObjectContext i usually make sure there are objects there to begin with. I usually do something like:

 

 

if ((db.RoomTypes.Count(i => i.Type_Code == room.Type)) > 0)
{
    roomType = db.RoomTypes.SingleOrDefault(i => i.Type_Code == room.Type);
    r.RoomType = roomType.Type_Name;

}

 

 

Now this is fine for when I’m trying to select against say, an id. This doesn’t work when i want to return all records from my ObjectSet. So i have come up with an extension method to the said ObjectSet:

        #region CountAll
        public static int CountAll<TEntity>(this ObjectSet<TEntity> objectSet) 
where TEntity : class { int _count = 0; foreach (var ObjectSet in objectSet) { if (objectSet != null) { _count++; } } return _count; } #endregion

 

 

Take note of the TEntity class constraint. Some little background. When you create your EF classes based on your database, there are various classes that are created.

Here is another example, db.Rooms being my ObjectContext:

 

Room room = db.Rooms.SingleOrDefault(r => r.Unique_Key == id);

 

If you look at the definition of Rooms (ObjectSet – a table), this is the collection of Room:

 

public ObjectSet<Room> Rooms
 {
     get
     {
         if ((_Rooms == null))
         {
             _Rooms = base.CreateObjectSet<Room>("Rooms");
         }
         return _Rooms;
     }
 }

 

If you look at the definition of Room generic parameter, represents a row in the table Room:

public partial class Room : EntityObject

 

So we know in essence the ObjectSet is the table and EntityObject is a row. So now we know this you can interrogate the definition of ObjectSet:

public class ObjectSet<TEntity> : ObjectQuery<TEntity>, IObjectSet<TEntity>,
IQueryable<TEntity>,IEnumerable<TEntity>, IQueryable, IEnumerable
where TEntity : class { }


So there’s your TEntity you need for your extension method constraint. Now you know why we have done what we have done for the Extension Method, here is how to use it:

try
{
  if ((db.Properties.CountAll()) > 0)
  {
     //--code here
      
  }
}

So we can CountAll the ObjectsSets (Rows) within Properties, if there are more than 0, the do something (Like query the data).

Anyway, i hope this helps.

 

 

 

Enhanced by Zemanta

[MVC 3] Entity Framework 4–Disposing ObjectContext–TIP


ADO.NET Entity Framework stack

Image via Wikipedia

The Entity Framework can throw a lot of Exceptions depending on what you are trying to achieve. We are lucky that the default CRUD controller template includes how to use EF during a Create/Delete/Edit scenario, but sometimes (a lot of the time in my case), when you first begin using EF, the exceptions keep on coming.

 

A lot of people use either try/finally or using statements when using their ObjectContext. You will find a lot of people will have something like (db being the ObjectContext):

 

    finally {
        if (db != null)
 db.Dispose();
    }

}

 

 

Now this is fine, but you need to handle this correctly, because if you saves changes after this, you could throw an InvalidOperationException, with the following text:

 

The object cannot be attached because it is already in the object context. An object can only be reattached when it is in an unchanged state.

OR

 

 

ObjectDisposedException

 

In Entity Framework, entities are attached to the EF context and changes are “tracked” within the framework. So you need to make sure you are not trying to Attach or Detach your entities incorrectly. Remember:

 

AddObjectUsed solely to add new entities only (Does not deal with EntityState.Modified items) to the context to be added to the data source.

AttachUsed to update an object that already exists in the context.

 

Now if we Dispose the object context incorrectly, then this could cause the above exceptions to be thrown later on when trying to update the data sources after the finally statement which includes the Dispose.

 

Now the way i get around this is use partial to extend my EF ObjectContext class (in my case EduEntities), and override the Dispose method so i only Detach the Unchanged Entities.

 

public partial class EduEntities {
    protected override void Dispose(bool disposing)
    {

        foreach (var entry in ObjectStateManager.GetObjectStateEntries       (EntityState.Unchanged))
        {

            Detach(entry.Entity);
        }

        base.Dispose(disposing);

    }

}

 

This means that the tracking on my changed objects are not lost.

Enhanced by Zemanta

[MVC 3] Upload Image –SQL Server & Entity Framework


UPDATE: I have now combined all my MVC Image Handling  blog posts into a Open Source Project. Feel free to check this out once you have read the post.

http://mvcimage.codeplex.com/

Original Blog Post:

The last post i described how to create a HTML Helper for Image Previewing. This time around we will be uploading an image to a Database, which is handled little differently than normal CRUD operations.

The following block of code shows my Create action method within my UserProfile controller:

 1:         public ActionResult Create(UserProfile userprofile,
 2:          HttpPostedFileBase imageLoad2)
 3:         {
 4:             var profileimage = new Medium();
 5:  
 6:             if (imageLoad2 != null)
 7:             {
 8:                 using (Image img =
                        Image.FromStream(imageLoad2.InputStream))
 9:                 {
 10:  
 11:                     //--Initialise the size of the array
 12:                     byte[] file = new byte[imageLoad2.InputStream.Length];
 13:  
 14:                     //--Create a new BinaryReader and set the InputStream
 //-- for the Images InputStream to the
 16:                     //--beginning, as we create the img using a stream.
 17:                     BinaryReader reader =
                              new BinaryReader(imageLoad2.InputStream);
 18:                     imageLoad2.InputStream.Seek(0, SeekOrigin.Begin);
 19:  
 20:                     //--Load the image binary.
 21:                     file = reader.ReadBytes((int)imageLoad2.
                                   InputStream.Length);
 22:  
 23:                     //--Create a new image to be added to the database
 24:  
 25:                     profileimage.Created_Date = DateTime.Now;
 26:                     profileimage.Source = file;
 27:                     profileimage.File_Size = imageLoad2.ContentLength;
 28:                     profileimage.File_Name = imageLoad2.FileName;
 29:                     profileimage.Content_Type = imageLoad2.ContentType;
 30:                     profileimage.Height = img.Height;
 31:                     profileimage.Width = img.Width;
 32: #if DEBUG
 33:                     profileimage.Record_Status = "T";   //--Testing.
 34: #else
 35:                         profileimage.Record_Status = " ";/--Live.
 36: #endif
 37:  
 38:  
 39:  
 40:                 }
 41:             }
 42:  
 43:             if (ModelState.IsValid)
 44:             {
 45:  
 46:                 db.Media.AddObject(profileimage);
 47:                 db.SaveChanges();
 48:  
 49:                 return RedirectToAction("Index", "Home");
 50:  
 51:             }
 52:  
 53:             var viewModel = new UserProfileViewModel
 54:             {
 55:                 UserProfile = userprofile,
 56:                 UserTypes = userTypes
 57:             };
 58:  
 59:             return View(userprofile);
 60:         }

This method creates has two parameters, the model UserProfile, and the imageLoad2 is the file posted. Have a look at the previous post about building the HTML.

NB: the parameter name imageLoad2 needs to be the name of the input file from the view so that is is bound (using the MVC Model Binding). If you used a different name the parameter would be null.

The method creates a Entity Framework model Medium, which is my class to describe the SQL Table which holds the Images. The images are saved within SQL as (MAX). Quite easy really, create a   to convert the image stream to binary,  then using the EF to the entity set, then save it to the table.

There we have it. Join me next time for downloading the image, using another custom HTML Helper.

 

Enhanced by Zemanta