c# - WebApi 中自动生成的 EF 代码无法在 Azure 上运行,但在测试时可以在本地运行

标签 c# entity-framework azure asp.net-web-api

我将我的项目连接到了 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;”的响应正文; charset=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;
        }

我已经没有想法了。

有人能解决吗?

谢谢。

最佳答案

这很可能是由序列化尝试延迟加载您的问题的引用引起的。

如果您将响应更改为拥有自己的响应类型或 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;}
}

此外,直接返回数据库模型是不好的,您可能会将他们不应该看到的数据暴露给客户端。通过使用响应对象,您可以准确控制客户端看到的内容,无论数据库模型是否发生变化。

关于c# - WebApi 中自动生成的 EF 代码无法在 Azure 上运行,但在测试时可以在本地运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25225426/

相关文章:

c# - 异步方法混淆

entity-framework - 仅当 EntityCollection 或 EntityReference 不包含对象时才能调用 Load

c# - 在 Entity Framework Core 中使用 Update-Database 添加新列

entity-framework - 为什么 VS 2015 需要引用 System.Data.Entity 而 VS 2013 不需要?

c# - 防止子元素失去焦点时触发LostFocus

c# - Roslyn 编译器用零优化函数调用乘法

azure - 缩小 Azure 上 FileLoadException 错误的范围

azure - 如何在 ARM 模板中动态生成流量管理器端点?

iis - gif 文件在 Windows azure 中给出 404 错误

c# - 如何在单元测试中验证 Flurl Http 中的请求正文内容?