0

I am developing my first web application using MVC5+WebAPI2 with the EntityFramework 5.0.

In my application I have to display a list of transactions extracted from a database, so I have a WebApi Controller which does the following:

    [RoutePrefix("api/transaction")]
public class TransactionApiController : ApiController
{
    [Route("{userid}/{status}")]
    [HttpGet]
    [Authorize]
    public TPASS_Transaction[] getTransactions(string userid, int status) {
        using (var ec = new TelepassEntities()) {
            TPASS_Transaction[] transactions = ec.TPASS_Transaction
            .Where(t => t.TransactionOwner.EndsWith(userid) && t.Status == status)
            .ToArray();
            return transactions;
        }
    }
}

However, on the client I get an error: The 'ObjectContent`1' type failed to serialize the response body. It seems like this is due to the property HBTI_Employee in the TPASS_Transaction class:

"InnerException":{"Message":"An error has occurred.",
"ExceptionMessage":"Error getting 
value from 'HBTI_Employee1' on 
'System.Data.Entity.DynamicProxies.HBTI_Employee_...

My workaround to this problem was to create a class TransactionViewModel, and create objects of this type on the server from the original TPASS_Transaction, avoiding the HBTI_Employee property:

    [Route("{userid}/{status}")]
    [HttpGet]
    [Authorize]
    public TransactionVM[] getTransactions(string userid, int status) {
        using (var ec = new TelepassEntities()) {
            TransactionVM[] transactions = ec.TPASS_Transaction
            .Where(t => t.TransactionOwner.EndsWith(userid) && t.Status == status)
                .Select(t => new TransactionVM()
                            { 
                                //all properties of TPASS_Transaction
                                //but HBTI_Employee
                            }).ToArray();
            return transactions;
        }
    }

Anyway, it would be tedious to do it for every model class in my application, so I would rather work with the original objects. I googled the issue, but no one seems to give a good answer/solution to this problem. Can anyone explain what is wrong/what I am missing here?

link
  • 1,676
  • 1
  • 13
  • 21
  • Take a look at this, maybe : http://stackoverflow.com/questions/7276507/serializable-classes-and-dynamic-proxies-in-ef-how – Raphaël Althaus Mar 31 '14 at 09:37
  • Actually your "workaround" with VM is a best practice and you should do so. You can use AutoMapper to simplify entities converting. – Oleksandr Kobylianskyi Mar 31 '14 at 09:42
  • @RaphaëlAlthaus thanks Raphaël, that was useful. It means that I will probably need to disable lazy loading and implement some kind of paging. – link Mar 31 '14 at 09:46
  • @alex.koby could you elaborate a little more on this "AutoMapper"? Unfortunately I'm really a beginner with this kind of technologies, so I am a little lost. Thank you! – link Mar 31 '14 at 09:47
  • AutoMapper is a convenient library for mapping classes (in your case Entity Framework entites to view model), You can read more here - http://automapper.org/. – Oleksandr Kobylianskyi Mar 31 '14 at 09:52
  • It seems to me like you might be getting a lazy-loaded relation on a disposed DbContext. The serialization will hit your property and try to load the value, but your context is probably disposed since you are wrapping it in a using block. – Simon Belanger Mar 31 '14 at 12:12
  • @SimonBelanger yes, the issue is with lazy-loaded relations. Would keeping the EntityContainer alive be a good solution? I thought that it was meant to be used with the OPEN -> PERFORM OPERATION -> CLOSE workflow... – link Mar 31 '14 at 14:50
  • @simoned You can either eager load the required properties, or dispose of your context when your controller is disposed. That means moving your `Context.Disposed` call in your controller's own dispose method and let the framework dispose of the objects when they are no longer required. – Simon Belanger Mar 31 '14 at 15:21

0 Answers0