I have a WebAPI
which calls functions from a Class Library
which calls data from a Entity Framework Model First Class Library
.
I am suffering from the dreaded "self referencing loop detected"
So, in my DataStore
class library I have the autogenerated
Context:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace SADatastore
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class SADatastoreEntities : DbContext
{
public SADatastoreEntities()
: base("name=SADatastoreEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<DB> DBS { get; set; }
....
}
}
I then have a Connections.cs
file which I user to pass the connection string
into the context
with...
public partial class SADatastoreEntities
{
public SADatastoreEntities(string connStr)
: base(string.Format(@"metadata=res://*/SAModel.csdl|res://*/SAModel.ssdl|res://*/SAModel.msl;provider=System.Data.SqlClient;provider connection string='{0}'", connStr))
{
// http://stackoverflow.com/questions/12868996/permanently-disable-configuration-proxycreationenabled-in-ef
Configuration.ProxyCreationEnabled = false;
}
}
As you can see in the above code I am attempting to set ProxyCreationEnabled = false
which is what I have read should solve my problem. But it has no effect.
In my API I have the following controller
public class SA_GetAllItemDetailsController : ApiController
{
[Route("SA_GetAllItemDetails")]
[HttpGet]
public List<SA_Items> Get(DateTime? lastUpdated = null, int limit = 100, int offset = 0)
{
try
{
if (Helpers.Authorise(Request, "WriteVisitors").Authorised)
{
List<SA_Items> result = new List<SA_Items>();
result = SADatastoreEngine.Functions.Item.SA_GetAllItemDetails(
Settings.Default.ConnectionString,
lastUpdated,
limit,
offset
);
// conver the result to a string to have a look at it
string json = JsonConvert.SerializeObject(result, Formatting.Indented);
return result;
}
else
{
throw new HttpResponseException(Helpers.RespondNotAuthorised());
}
}
catch (Exception e)
{
throw new HttpResponseException(Helpers.RespondWithAnError(e));
}
}
}
public class SA_GetItemByItemIdController : ApiController
{
[Route("SA_GetItemByItemId/{id}")]
[HttpGet]
public SA_Items Get(string id)
{
try
{
if (Helpers.Authorise(Request, "WriteVisitors").Authorised)
return SADatastoreEngine.Functions.Item.GetItemByItemId(Settings.Default.ConnectionString, id);
else
{
throw new HttpResponseException(Helpers.RespondNotAuthorised());
}
}
catch (Exception e)
{
throw new HttpResponseException(Helpers.RespondWithAnError(e));
}
}
}
public class SA_CreateItemController : ApiController
{
[Route("SA_CreateItem")]
[HttpPost]
[ValidateViewModel]
public Dictionary<string, string> Post(SA_Items item)
{
try
{
// get the auth details
AuthorisationModel auth = Helpers.Authorise(Request, "WriteVisitors");
if (Helpers.Authorise(Request, "WriteVisitors").Authorised)
{
return SADatastoreEngine.Functions.Item.CreateItem(Settings.Default.ConnectionString, auth.DBSId, item);
}
else
{
throw new HttpResponseException(Helpers.RespondNotAuthorised());
}
}
catch (Exception e)
{
throw new HttpResponseException(Helpers.RespondWithAnError(e));
}
}
}
public class SA_UpdateItemController : ApiController
{
[Route("SA_UpdateItem")]
[HttpPut]
public Dictionary<string, string> Post(SA_Items item)
{
try
{
// get the auth details
AuthorisationModel auth = Helpers.Authorise(Request, "WriteVisitors");
if (auth.Authorised)
{
return SADatastoreEngine.Functions.Item.UpdateItem(Settings.Default.ConnectionString, auth.DBSId, item);
}
else
{
throw new HttpResponseException(Helpers.RespondNotAuthorised());
}
}
catch (Exception e)
{
throw new HttpResponseException(Helpers.RespondWithAnError(e));
}
}
}
Here is the SA_GetAllItemDetails
function:
public static List<SA_Items> SA_GetAllItemDetails(string connStr, DateTime? lastUpdated, int limit, int offset) {
using (SADatastoreEntities db = new SADatastoreEntities(connStr)) {
if (lastUpdated == null)
lastUpdated = new DateTime(1900, 1, 1);
return db.SA_Items
.Include("SA_Model")
.Include("SA_Model.SA_Manufacturers")
.Where(x => x.LastUpdated > lastUpdated)
.OrderBy(x => x.ItemID)
.Skip(offset)
.Take(limit)
.ToList();
}
}
I have added a line where I am attempting to convert the object to a json string so I can see it. But this is where it throws the error.
I have the feeling the setting
Configuration.ProxyCreationEnabled = false;
is being ignored because it's in the wrong location. But I cannot work out where it should be.
Can anyone see what I am doing wrong please?
EDIT
I have now changed my code to attempt to serialize it:
JsonSerializerSettings _jsonSettings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
// convert the result to a string to have a look at it
string json = JsonConvert.SerializeObject(result, Formatting.Indented, _jsonSettings);
which leads to a Exception of type 'System.OutOfMemoryException' was thrown error