0

I'm trying to save my Photo class that has a byte[] File field. When trying to save it using context is throws the error

Object reference not set to an instance of an object.

But when debugging I can see that it is not null. I can see all of the properties of the the class including the values in the byte array.

 public class PhotoRepository 
    {
        private static BlogContext _ctx;

        public PhotoRepository()
        {
            _ctx = new BlogContext();
        }

        public static void Save(Photo p)
        {
            _ctx.Photos.Add(p);
            _ctx.SaveChanges();
        }
    }

controller

 public class PhotoController : Controller
    {
        public ActionResult Index()
        {
            using (var ctx = new BlogContext())
            {
                return View(ctx.Photos.AsEnumerable());
            }
        }

        public ActionResult Upload()
        {
            return View(new Photo());
        }

        [HttpPost]
        public ActionResult Upload(PhotoViewModel model)
        {
            var photo =  new Photo();//Mapper.Map<PhotoViewModel, Photo>(model);
            if (ModelState.IsValid)
            {

                photo.AlternateText = model.AlternateText;
                photo.Description = model.Description;
                photo.File = MapStreamToFile(model.File);
                photo.Name = model.Name;
                PhotoRepository.Save(photo);
                return RedirectToAction("Index");
            }
            return View(photo);
        }

        public byte[] MapStreamToFile(HttpPostedFileBase file)
        {
            using (var stream = file.InputStream)
            {
                var memoryStream = stream as MemoryStream;
                if (memoryStream == null)
                {
                    memoryStream = new MemoryStream();
                    stream.CopyTo(memoryStream);
                }
                return memoryStream.ToArray();
            }
        }
    }

Photo

 public class Photo
    {
        public int Id { get; set; }

        public Byte[] File { get; set; }

        public string Name { get; set; }

        public string Description { get; set; }

        public string AlternateText { get; set; }
    }

PhotoViewModel

 public class PhotoViewModel
    {
        public int Id { get; set; }

        public HttpPostedFileBase File { get; set; }

        public string Name { get; set; }

        public string Description { get; set; }

        public string AlternateText { get; set; }
    }

enter image description here

5
  • Exactly what returns a null or raises a NullReferenceException? Less code and more stack, please. Commented Jun 17, 2012 at 17:55
  • 1
    You realize that every time you create a new instance of PhotoRepository you will re-initialize that static field, right? That seems like and error prone and confusing design to me Commented Jun 17, 2012 at 17:55
  • its not byte array You are trying to use a reference variable who’s value is null. Commented Jun 17, 2012 at 17:55
  • @EdS. Ah, I just noticed. Or, more importantly here, perhaps, _ctx will not be set before an instance is created. Commented Jun 17, 2012 at 17:56
  • @pst: Yep, that too. OP, either _ctx is null because you never create an instance of PhotoRepository, _ctx.Photos is null, or you are getting the exception in _ctx.SaveChanges();. Initialize that static member statically (i.e., when you declare it). You are going to run into weird problems relying on a constructor to initialize static data. Commented Jun 17, 2012 at 17:57

1 Answer 1

1

I think the problem is that _ctx is null. Notice that you declare it and Save static, but _ctx is only instantiates in public PhotoRepository(), which is the constructor. As long as it should really be static, instantiate it statically instead of in the constructor:

 public static class PhotoRepository 
    {
        private static BlogContext _ctx = new BlogContext();

        public static void Save(Photo p)
        {
            _ctx.Photos.Add(p);
            _ctx.SaveChanges();
        }
    }

I also changed the class to static, since I only see it contains static members. This may not be correct if you intend more for this class.

Edit: (thanks @pst) I see from looking at your code more, I think this might really be a better design:

 public class PhotoRepository : IDisposable
    {
        private BlogContext _ctx = new BlogContext();

        public void Save(Photo p)
        {
            _ctx.Photos.Add(p);
            _ctx.SaveChanges();
        }

        void IDisposable.Dispose() { _ctx.Dispose(); }
    }

And then always be sure to dispose PhotoRepository when you're done with it. The reason for my suggested change here is that BlogContext is disposable, and is used with using in another place.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks that worked, I just removed the static property and created a new PhotoRepository before calling.
Ok, good. Be sure to dispose things that are disposable as soon as you're done with them (see my second code snippet in the answer for an example of a disposable PhotoRepository).
Thanks I was wondering how to Implement IDisposable in this situation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.