我将我的项目连接到Azure上的sql数据库。 在本地测试时,
此网址正常。 - > http://localhost:3287/api/Questions
但在Azure上测试时 - > http://mywebsite.azurewebsites.net/api/Questions 它失败并返回JSON格式的错误消息,如下所示。
{
"$id": "1",
"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": {
"$id": "2",
"Message": "An error has occurred.",
"ExceptionMessage": "Error getting value from 'company_answer' on 'System.Data.Entity.DynamicProxies.question_70E4093AC2C7FDC38798C82820B9E2C1CBF9627487D0F09FFAC57467331A277B'.",
"ExceptionType": "Newtonsoft.Json.JsonSerializationException",
"StackTrace": " at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()",
"InnerException": {
"$id": "3",
"Message": "An error has occurred.",
"ExceptionMessage": "An error occurred while executing the command definition. See the inner exception for details.",
"ExceptionType": "System.Data.Entity.Core.EntityCommandExecutionException",
"StackTrace": " at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)\r\n at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)\r\n at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()\r\n at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)\r\n at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()\r\n at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)\r\n at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)\r\n at System.Data.Entity.Core.Objects.ObjectQuery`1.Execute(MergeOption mergeOption)\r\n at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Load(List`1 collection, MergeOption mergeOption)\r\n at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Load(MergeOption mergeOption)\r\n at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.DeferredLoad()\r\n at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.LoadProperty[TItem](TItem propertyValue, String relationshipName, String targetRoleName, Boolean mustBeNull, Object wrapperObject)\r\n at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.<>c__DisplayClass7`2.<GetInterceptorDelegate>b__1(TProxy proxy, TItem item)\r\n at System.Data.Entity.DynamicProxies.question_70E4093AC2C7FDC38798C82820B9E2C1CBF9627487D0F09FFAC57467331A277B.get_company_answer()\r\n at Getcompany_answer(Object )\r\n at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)",
"InnerException": {
"$id": "4",
"Message": "An error has occurred.",
"ExceptionMessage": "There is already an open DataReader associated with this Command which must be closed first.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": " at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)\r\n at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)\r\n at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)\r\n at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)\r\n at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)\r\n at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)\r\n at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)\r\n at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)\r\n at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)\r\n at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)\r\n at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)\r\n at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)"
}
}
}
}
我还尝试了其他网址,例如: 的 http://mywebsite.azurewebsites.net/api/Questions/3 它在本地和Azure上都可以正常工作。 (真奇怪!)
我确实看到'ObjectContent`1'类型无法序列化内容类型'application / json的响应正文;字符集= UTF-8' 。
并添加了这个
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
((DefaultContractResolver)json.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;
config.Formatters.JsonFormatter.SerializerSettings.Formatting =
Newtonsoft.Json.Formatting.Indented;
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
进入我的WebApiConfig.cs,但它无法解决问题。
我还看到:已经有一个与此命令关联的打开DataReader,必须先关闭。
所以我检查了这个: MultipleActiveResultSets = True; 它在我的连接字符串中。
但我的问题仍然存在。
以下是VS 2013生成的代码
// GET: api/Questions
[HttpGet]
public IQueryable<question> Getquestions()
{
return db.questions;
}
我已经没有想法了。
有人能搞清楚吗?
谢谢。
答案 0 :(得分:6)
这很可能是因为序列化试图延迟加载您问题的引用。
如果您将响应更改为具有自己的响应类型或dto,则会阻止在序列化时发生任何延迟加载。
类似的东西:
// GET: api/Questions
[HttpGet]
public IList<QuestionResponse> Getquestions()
{
return db.questions.Select(x => new QuestionResponse
{
Id = x.Id,
Question = x.Question
});
}
public class QuestionResponse
{
public int Id {get;set;}
public string Question {get;set;}
}
此外,直接返回数据库模型很糟糕,您可能会将数据暴露给他们不应该看到的客户端。通过使用响应对象,您可以准确控制客户端看到的内容,无论数据库模型是否发生更改。
答案 1 :(得分:1)
在使用延迟加载here时,请仔细检查用于连接到SQL Azure数据库的连接字符串是否包含 MultipleActiveResultSets = True 。