dantey89
dantey89

Reputation: 2287

Entity Framework model to Json Result

I confused with error that Action returns me. I have a code in my manager:

public class AddressesManager
    {

     private SiteDBEntities entityContext;

     public Addresses GetAddress(short id)
            {
                entityContext = new SiteDBEntities();
                var addressList = entityContext.Addresses.Where(a => a.Id == id).FirstOrDefault();
                entityContext.Dispose();
                return addressList;
            }
}

And action that call this function:

 [HttpPost]
        public ActionResult LoadAddress(short id)
        {
            AddressesManager mngr = new AddressesManager();
            Addresses address = mngr.GetAddress(id);
            return new JsonResult() { Data = address };
        }

And jquery code wich call thit action:

$.post("/Cart/LoadAddress", { id: id })
         .success(function (data) {

             console.log(data);
         })
    .fail(function (e) { console.log(e) });

Action is running, but i always getting 500 error whit this code:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

As i understood the problem is with entityContext , but why this happens? I already executed data from DB and I don't need connection anymore...

EDIT:

Thit is my Address model. It autogenerated by EF:

public partial class Addresses
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string State { get; set; }
        public string Country { get; set; }
        public string Warehouse { get; set; }
        public string FirstName { get; set; }
        public string SecondName { get; set; }
        public string Phone { get; set; }
        public short DeliveryType { get; set; }
        public System.Guid UserId { get; set; }

        public virtual DeliveryType DeliveryType1 { get; set; }
        public virtual Users Users { get; set; }
    }

Upvotes: 2

Views: 2884

Answers (6)

ocuenca
ocuenca

Reputation: 39326

If you want to use your entity data model then I suggest you to take a look to my answer in this post.

Now, what I would do is create a DTO to get only the data you need to pass to your View, like was proposed by @AnhTriet. To avoid map by yourself each property every time you need to project your query to your DTO, I suggest to use Automapper. Let me show you how would be your solution if you decide to use it:

public class AddressesManager
{
    public Addresses GetAddress(short id)
    {

        using(var entityContext = new SiteDBEntities())
        {
            var address = entityContext.Addresses
                                       .Where(a => a.Id == id)
                                       .ProjectTo<AddressDTO>()
                                       .FirstOrDefault();
            return address;
        }
    }
}

About ProjectTo extension method.

Upvotes: 1

Triet Doan
Triet Doan

Reputation: 12085

The error happens because your Address class has 2 virtual properties: DeliveryType1 and Users.

When you convert your address to JSON, it will try to access those virtual properties. However, at that time, your context are disposed already.

To avoid this problem, you shouldn't return the EF auto-generated class directly. Instead, create a DTO object (Data Transfer Object) containing only some fields you need, map it with the EF object, and return it. For example:

public class AddressesDTO
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string State { get; set; }
    public string Country { get; set; }
    public string Warehouse { get; set; }
    public string FirstName { get; set; }
    public string SecondName { get; set; }
    public string Phone { get; set; }
    public short DeliveryType { get; set; }
    public System.Guid UserId { get; set; }
}

Then, map it:

public Addresses GetAddress(short id)
{
    entityContext = new SiteDBEntities();
    var addressList = entityContext.Addresses.Where(a => a.Id == id).FirstOrDefault();

    // Create DTO object
    AddressesDTO address = new AddressesDTO();

    // Map it
    address.Id = addressList.Id;
    address.Title = addressList.Title
    // Go on, it's quite long...

    entityContext.Dispose();
    return address;
}

However, as you can see, the mapping process is very boring. A better way is using Automapper.

Upvotes: 1

Mark Omoniyi Adesina
Mark Omoniyi Adesina

Reputation: 92

When you are returning a json record in MVC you need to add AllowGet like so in your controller:

return Json(new { data= address }, JsonRequestBehavior.AllowGet);

With this in place you should be fine.

Upvotes: 0

kkakkurt
kkakkurt

Reputation: 2800

Addresses should be lazy-loaded in your case. So you are trying to access disposed data and Entity Framework tries to use disposed context and that gives an exception.

Maybe you need to attach your addressList to current context in order to enable lazy-loading

var addressList = entityContext.Addresses.Where(a => a.Id == id).FirstOrDefault();
entityContext.Addresses.Attach(addressList);

Upvotes: 0

Kahbazi
Kahbazi

Reputation: 14995

I think you should add attribute [JsonIgnore] to virtual properties of Addresses Class.

class Addresses
{
    public int ID { get; set; }

    [JsonIgnore]
    public virtual Something Something { get; set; }
}

Upvotes: 0

Barry Gallagher
Barry Gallagher

Reputation: 6246

Do you have a navigation (child) property in your Address class? I get the feeling that you're trying to access this child property after the DbContext has been disposed of, as child properties are lazy-loaded by default.

Can you post the code of your Address model?

Upvotes: 0

Related Questions