Reputation: 15664
The full error is:
{
Message: "An error has occurred.",
ExceptionMessage: "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.",
ExceptionType: "System.InvalidOperationException",
StackTrace: null,
InnerException: {
Message: "An error has occurred.",
ExceptionMessage: "Incorrect number of arguments for constructor",
ExceptionType: "System.ArgumentException",
StackTrace: " at System.Linq.Expressions.Expression.ValidateArgumentCount(MethodBase method, ExpressionType nodeKind, Int32 count, ParameterInfo[] pis) at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments) at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, IEnumerable`1 arguments) at System.Data.Objects.ELinq.InitializerMetadata.ProjectionNewMetadata.Emit(Translator translator, List`1 propertyTranslatorResults) at System.Data.Common.Internal.Materialization.Translator.HandleLinqRecord(RecordColumnMap columnMap, InitializerMetadata initializerMetadata) at System.Data.Common.Internal.Materialization.Translator.Visit(RecordColumnMap columnMap, TranslatorArg arg) at System.Data.Query.InternalTrees.RecordColumnMap.Accept[TResultType,TArgType](ColumnMapVisitorWithResults`2 visitor, TArgType arg) at System.Data.Common.Internal.Materialization.Translator.ProcessCollectionColumnMap(CollectionColumnMap columnMap, TranslatorArg arg, ColumnMap discriminatorColumnMap, Object discriminatorValue) at System.Data.Common.Internal.Materialization.Translator.Visit(SimpleCollectionColumnMap columnMap, TranslatorArg arg) at System.Data.Query.InternalTrees.SimpleCollectionColumnMap.Accept[TResultType,TArgType](ColumnMapVisitorWithResults`2 visitor, TArgType arg) at System.Data.Common.Internal.Materialization.Translator.TranslateColumnMap[TRequestedType](QueryCacheManager queryCacheManager, ColumnMap columnMap, MetadataWorkspace workspace, SpanIndex spanIndex, MergeOption mergeOption, Boolean valueLayer) at System.Data.Common.Internal.Materialization.ShaperFactory.TypedShaperFactoryCreator`1.TypedCreate(QueryCacheManager cacheManager, ColumnMap columnMap, MetadataWorkspace metadata, SpanIndex spanInfo, MergeOption mergeOption, Boolean valueLayer) at System.Data.Common.Internal.Materialization.ShaperFactory.Create(Type elementType, QueryCacheManager cacheManager, ColumnMap columnMap, MetadataWorkspace metadata, SpanIndex spanInfo, MergeOption mergeOption, Boolean valueLayer) at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Span span, ReadOnlyCollection`1 compiledQueryParameters, AliasGenerator aliasGenerator) at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption) at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at Newtonsoft.Json.Serialization.JsonArrayContract.CreateWrapper(Object list) in c:\Dev\Releases\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\JsonArrayContract.cs:line 108 at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) in c:\Dev\Releases\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalWriter.cs:line 128 at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) in c:\Dev\Releases\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalWriter.cs:line 342 at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) in c:\Dev\Releases\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalWriter.cs:line 123 at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value) in c:\Dev\Releases\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalWriter.cs:line 58 at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value) in c:\Dev\Releases\Working\Newtonsoft.Json\Src\Newtonsoft.Json\JsonSerializer.cs:line 608 at System.Net.Http.Formatting.JsonMediaTypeFormatter.<>c__DisplayClassd.<WriteToStreamAsync>b__c() at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)"
}
}
This seems to be isolated to my computer since our server and other coworkers can run the same code fine.
The only lead I've had is that I just installed Visual Studio 2012 Express side by side with VS 2010 which I'm running it in. Both of them come up with the same error though.
What is more perplexing is that the json.net library is being referenced locally and has not changed.
Only one of the web api controllers throws the error (contacts is an IQueryable that has been filter in numerous ways before this but works in the debugger until the render):
var r =
contacts
.Skip(offset).Take(count)
.Join(
crm.ContactViews,
c => c.Id,
cv => cv.Id,
(c, cv) => new {
contact = c,
view = cv,
userInfo = c.ContactUsers.Select(u => new {
name = u.User.UserName,
id = u.UserId
}).FirstOrDefault(),
lastCalled = crm.CallLogs
.Where(x => x.ContactId == c.Id)
.OrderByDescending(x => x.CallEnd)
.Select(log => new { date = log.CallStart, username = crm.Users.FirstOrDefault(x => x.UserId == log.Caller).UserName })
.FirstOrDefault()
}
)
.AsEnumerable()
.Select(c => new
{
id = c.contact.Id,
firstName = c.contact.FirstName,
lastName = c.contact.LastName,
dateCreated = formatDate(c.contact.DateCreated),
score = c.contact.Score,
companyName = c.view.Company,
phone = c.view.Phone,
email = c.view.Email,
street = c.view.Street,
street2 = c.view.Street2,
city = c.view.City,
state = c.view.State,
zip = c.view.Zip,
assignedUserName = c.userInfo != null ? c.userInfo.name : null,
assignedUserId = c.userInfo != null ? c.userInfo.id : (Guid?)null,
dateLastCalled = c.lastCalled != null ? formatDate(c.lastCalled.date) : null,
lastCalledBy = c.lastCalled != null ? c.lastCalled.username : null
});
Upvotes: 2
Views: 1805
Reputation:
I found out the following:
I had to add this.Configuration.ProxyCreationEnabled = false
to a DbContext based class.
Effectively this disables a huge optimization for EF 6.x.
Otherwise, this code would not run and returned the same error you had.
(ApiController based class)
public IHttpActionResult Surveys(int filterscount, int groupscount,
int pagenum, int pagesize, int recordstartindex, int recordendindex)
{
var data = _dbContext.Surveys.OrderByDescending(o => o.ID)
.Skip(pagenum * pagesize)
.Take(pagesize)
.ToList();
return Ok(data);
}
Upvotes: 0
Reputation: 181
After upgrading to .NET 4.5, I found that a projection like this failed due to the order of the properties in the anonymous object.
(t1, t2) => new { Thing1 = t1, Thing2 = t2, Thing1Prop1 = t1.Prop1, Thing2Prop1 = t2.Prop1 };
Switching the order to
(t1, t2) => new { Thing1Prop1 = t1.Prop1, Thing2Prop1 = t2.Prop1, Thing1 = t1, Thing2 = t2 };
fixed this for me, but I haven't yet experimented with other scenarios. This seems a BREAKING, annoying change.
Upvotes: 1
Reputation: 15664
Through the normal process of elimination I narrowed the problem down to the join statement using an anonymous object:
var r =
contacts
.Skip(offset).Take(count)
.Join(
crm.ContactViews,
c => c.Id,
cv => cv.Id,
(c, cv) => new ContactJoin(){
contact = c,
view = cv,
test = c.Score // <-- this line
}
)
.AsEnumerable()
.Select(c => new
{
id = c.contact.Id,
firstName = c.contact.FirstName,
lastName = c.contact.LastName,
score = c.test,
});
Removing the test = c.Score
line will fix the error. More testing revealed that "Incorrect number of arguments for constructor" error was being thrown from the anonymous object so the workaround is to make the join strongly typed:
.Join(
crm.ContactViews,
c => c.Id,
cv => cv.Id,
(c, cv) => new ContactJoin(){
contact = c,
view = cv,
userInfo = c.ContactUsers.Select(u => new UserInfo(){
name = u.User.UserName,
id = u.UserId
}).FirstOrDefault(),
lastCalled = crm.CallLogs
.Where(x => x.ContactId == c.Id)
.OrderByDescending(x => x.CallEnd)
.Select(log => new LastCall(){
date = log.CallStart,
username = crm.Users.FirstOrDefault(x => x.UserId == log.Caller).UserName
})
.FirstOrDefault()
}
)
I'd still like to find the root of the problem for maintainabilities sake.
Upvotes: 1