2

完整的错误是:

{
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)"
}
}

这似乎与我的计算机隔离,因为我们的服务器和其他同事可以正常运行相同的代码。

我唯一的线索是我刚刚将 Visual Studio 2012 Express 与我正在运行的 VS 2010 并排安装。尽管它们都出现了相同的错误。

更令人困惑的是,json.net库是在本地引用的,并没有改变。

只有一个 web api 控制器抛出错误(联系人是一个 IQueryable,在此之前已经以多种方式过滤,但在调试器中工作直到渲染):

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
    });
4

3 回答 3

1

通过正常的消除过程,我将问题缩小到使用匿名对象的连接语句:

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,
});

删除该test = c.Score行将修复错误。更多测试显示匿名对象抛出了“构造函数的参数数量不正确”错误,因此解决方法是使连接强类型化:

.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()
    }
)   

为了可维护性,我仍然想找到问题的根源。

于 2013-02-14T20:50:31.317 回答
1

升级到 .NET 4.5 后,我发现由于匿名对象中属性的顺序,这样的投影失败了。

(t1, t2) => new { Thing1 = t1, Thing2 = t2, Thing1Prop1 = t1.Prop1, Thing2Prop1 = t2.Prop1 };

切换顺序为

(t1, t2) => new { Thing1Prop1 = t1.Prop1, Thing2Prop1 = t2.Prop1, Thing1 = t1, Thing2 = t2 };

为我解决了这个问题,但我还没有尝试过其他场景。这似乎是一个突破性的、令人讨厌的变化。

于 2013-07-09T21:09:50.900 回答
0

我发现了以下内容:

我必须添加this.Configuration.ProxyCreationEnabled = false到基于 DbContext 的类。

实际上,这会禁用对 EF 6.x 的巨大优化。

否则,此代码将不会运行并返回与您相同的错误。

(基于 ApiController 的类)

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);
}
于 2014-08-24T12:30:20.240 回答