0

Inside my class Lugar I have this:

public virtual Foto FotosLugar { get; set; }

And I have this definition:

public class Foto
{
    [Column(TypeName = "image")]
    public byte[] Binary { get; set; }
}

In my LugarController I have tried:

 public ActionResult Create(Lugar lugar, HttpPostedFileBase FotosLugar)

I tried to make some conversions but it didnt work either...

I want to store an Image inside the class Lugar....

Rudi Visser
  • 21,350
  • 5
  • 71
  • 97
Ze Carioca Silva
  • 445
  • 7
  • 16

3 Answers3

1

Try this:

public ActionResult Create(Lugar lugar, HttpPostedFileBase fotosLugar)
{
    if (fotosLugar != null && fotosLugar.ContentLength > 0)
    {
        var contentLength = fotosLugar.ContentLength;
        var content = new byte[contentLength];
        fotosLugar.InputStream.Read(content, 0, contentLength);
        var foto = new Foto { Binary = content };
        lugar.FotosLugar = foto;
    }
    //... eventually return an ActionResult
}

Files are a bit trickier to deal with than normal data because the bytes are contained in a Stream object. The code above reads the bytes out of the stream so that they can be stored in your EF entity class.

A couple of other notes: It might not be a bad idea to also store the ContentLength, ContentType, and possibly FileName on your Foto entity. You might also want to consider splitting this entity into 2, so that you can query out the file name, content type, and content length separately from the raw binary file data. We had an issue in our site where we needed to just get the file names, but that query was slow because, since we stored our byte[] column on the same table as the file name, SQL was returning all of the binary data when all we needed was the string file name. Eventually solved with a model similar to the following:

public class Foto
{
    public int Id { get; set; }
    public int ContentLength { get; set; }
    public string FileName { get; set; }
    public string ContentType { get; set; }
    public virtual FotoBinary Content { get; set; }
}

public class FotoBinary
{
    public int Id { get; set; }
    public virtual Foto Owner { get; set; }
    public byte[] Value { get; set; }
}

This way, you can query just the string & int data separately, and eager load or lazy load the binary data separately when needed. Here is the fluent mapping for the relationship between these 2 entities:

// Foto entity
HasRequired(principal => principal.Content)
    .WithRequiredPrincipal(dependent => dependent.Owner)
    .WillCascadeOnDelete(true);

// FotoBinary entity
HasRequired(dependent => dependent.Owner)
    .WithRequiredDependent(principal => principal.Content)
    .WillCascadeOnDelete(true);

When you use a mapping similar to the one above, all of your Foto and FotoBinary rows in the database will share the same primary key (Id). As long as you know the Id of one, you can use it to query the corresponding row for the other (Owner or Content).

Finally, I would at least consider not passing a Lugar entity into your MVC action. You can instead compose a ViewModel class, like LugarViewModel. That class can then have an HttpPostedFileBase property in similar fashion to Karthik's answer. Your controller action can then take the data from the viewmodel and use it to populate a Lugar entity.

Community
  • 1
  • 1
danludwig
  • 46,965
  • 25
  • 159
  • 237
  • I am sorry but your controller code is not working..... The line var foto = new Foto { Binary = content }; It says it doesnt have a definition for Binary, so I tried Content=content but didnt work either..... I tried a lot of changes but nothing worked... I tried creating a FotoBInary first too..... I am still learning asp.net MVC , I would aprreciate a lot if you could help me.... You already have helped a lot but now I am kind of lost here..... – Ze Carioca Silva Feb 20 '13 at 00:49
  • I Will take a deeper look at this one-to-one tomorrow... I will see how to solve this problem – Ze Carioca Silva Feb 20 '13 at 03:51
  • I based a lot of this code on the sample classes in your original question. If you are getting a compiler error, make sure you have a `Foto` class with a property named `Binary` as in your original question. – danludwig Feb 20 '13 at 12:34
0

I'm not sure this has anything to do with EF. Looks like you didn't get there yet.

What you are saying is that you cannot receive a file inside your Create action in the controller, right?

You have at least two options:

  • have an action with one parameter (HttpPostedFile/IEnumerable) and get the images separately from the model
  • or you can simply access Request.Files anywhere in your controller that you will get a collection of uploaded files and then later add to you Lugar class. There is no need to have the extra FotosLugar parameter
tucaz
  • 6,524
  • 6
  • 37
  • 60
0

OK, Here's my take on it:

Community
  • 1
  • 1
amhed
  • 3,649
  • 2
  • 31
  • 56