GZip头中的魔数不正确。确保传递了一个GZip流。

6
我正在尝试使用WebAPI从EntityFramework检索产品名称及其ID作为NameID对象。以下是相应的代码。

我正在尝试使用WebAPI从EntityFramework检索产品名称及其ID作为NameID对象。以下是相应的代码。

public class ProductController : ApiController
{
    protected MainDataContext db = new MainDataContext();
    // GET /api/values
    public IQueryable<NameID> Get()
    {
        return db.Products.Select(x=>new NameID{ ID=x.ID,Name=x.Name }).AsQueryable();
    }

    // GET /api/values/5
    public NameID Get(long id)
    {
        var result = db.Products.Select(x=>new NameID{ ID=x.ID,Name=x.Name }).SingleOrDefault(x => x.ID == id);
        if (id == 0 || result == null)
            throw new HttpResponseException(HttpStatusCode.NotFound); 
        return result;
    }

}
public class NameID {
    public long ID {get;set;}
    public string Name {get;set;}
}

它报错如下:

The magic number in GZip header is not correct.
Make sure you are passing in a GZip stream.

at System.IO.Compression.GZipDecoder.ReadHeader(InputBuffer input) 
at System.IO.Compression.Inflater.Decode() 
at System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length) 
at System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count) 
at System.IO.Compression.GZipStream.Read(Byte[] array, Int32 offset, Int32 count) 
at System.Xml.XmlTextReaderImpl.InitStreamInput(Uri baseUri, String baseUriStr, Stream stream, Byte[] bytes, Int32 byteCount, Encoding encoding) 
at System.Xml.XmlTextReaderImpl..ctor(Stream stream, Byte[] bytes, Int32 byteCount, XmlReaderSettings settings, Uri baseUri, String baseUriStr, XmlParserContext context, Boolean closeInput) 
at System.Xml.XmlReaderSettings.CreateReader(Stream input, Uri baseUri, String baseUriString, XmlParserContext inputContext) 
at System.Xml.XmlReader.Create(Stream input, XmlReaderSettings settings, String baseUri) 
at System.Xml.Linq.XDocument.Load(Stream stream, LoadOptions options) 
at System.Data.Entity.Migrations.Edm.ModelCompressor.Decompress(Byte[] bytes) 
at System.Data.Entity.Migrations.History.HistoryRepository.GetLastModel(String& migrationId) 
at System.Data.Entity.Migrations.History.HistoryRepository.GetLastModel() 
at System.Data.Entity.Internal.InternalContext.QueryForModel() 
at System.Data.Entity.Internal.ModelCompatibilityChecker.CompatibleWithModel(InternalContext internalContext, ModelHashCalculator modelHashCalculator, Boolean throwIfNoMetadata) 
at System.Data.Entity.Internal.InternalContext.CompatibleWithModel(Boolean throwIfNoMetadata) 
at System.Data.Entity.CreateDatabaseIfNotExists`1.InitializeDatabase(TContext context) 
at System.Data.Entity.Internal.InternalContext.<>c__DisplayClass8.<PerformDatabaseInitialization>b__6() 
at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) 
at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization() 
at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c) 
at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input) 
at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action) 
at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase() 
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) 
at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() 
at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() 
at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider() 
at System.Linq.Queryable.Select[TSource,TResult](IQueryable`1 source, Expression`1 selector) 
at ProductAPI.Controllers.ProductController.Get() in D:\Demo\ProductAPI\Controllers\ProductController.cs:line 24 
at lambda_method(Closure , Object , Object[] ) 
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) 
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.Execute(HttpControllerContext controllerContext, IDictionary`2 arguments) 
at System.Web.Http.Controllers.ApiControllerActionInvoker.<>c__DisplayClass2.<InvokeActionAsync>b__0() 
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)

2
你是在尝试使用gzip解压缩.zip文件吗? - Zaki
我并没有尝试任何东西,只是返回NameID对象。这是一个纯的Vannila项目,使用EntityFramework POCO。也没有设置http压缩。 - Anuj Pandey
如果有帮助的话,它不会在返回IQueryable时出错。我正在修改代码以进一步解释。 - Anuj Pandey
1
我不确定,但似乎EF正在尝试从数据库中检索模型元数据,而此元数据已损坏(不符合预期的GZip格式)。您是否尝试重新创建数据库? - Martin Liversage
我只看到了元数据损坏了。感谢@MartinLiversage的帮助。 - Anuj Pandey
如果您的问题已经解决,请删除该问题或发布一个答案。 - Aliostad
4个回答

8

堆栈跟踪似乎表明从数据库读取Entity Framework模型元数据存在问题。

HistoryRepository.GetLastModel调用ModelCompressor.Decompress,它使用XDocument.LoadGZipStream中读取一些XML。这会失败,数据库中的模型元数据很可能已损坏。

您可以尝试重新创建数据库以解决此问题。


6

有一个已经被接受的答案,可能已经有点晚了,但是如果您已经有一个可用的数据库并且不想刷新数据库,则可以在Global.asax的application_start函数中调用Database.SetInitializer并将其设置为null。这样就不会查找包含损坏数据的__migrationhistory表。


4

我无法重新创建数据库,而且我已经使用了Database.SetInitializernull

幸运的是,我在另一个数据库中有最新的__MigrationHistory表,并且我使用了此Sql查询来设置目标数据库中的正确值:

INSERT INTO TargetDbName.dbo.__MigrationHistory (MigrationId, Model, ProductVersion)
SELECT MigrationId, Model, ProductVersion
FROM SourceDbName.dbo.__MigrationHistory
WHERE MigrationId = 'YYYYMMDDHHMMSSFFF_LastMigration' 

非常感谢。这个解决方案对我很有用。我已经苦恼了两天,错误信息也太误导人了,但最终谷歌带我找到了这个解决方案。我的Code First DB无法从Visual Studio访问,也无法进行任何迁移。我复制了所有DB内容,但仍然不起作用。然而,在Global.asax.cs中设置上述属性的空值对我有用。 - Balaji Birajdar
我有一个类似的问题,我有3个迁移需要添加,但它们在另一个数据库中不存在。有什么建议吗? - jmckie

0
在我的情况下,我通过运行数据库迁移命令UPDATE-DATABASE解决了这个错误。它运行了所有的迁移文件,创建了迁移历史表以及模型的哈希值。
为了让你了解之前发生了什么:我之前在开发环境中运行了迁移脚本,并从生产环境拷贝了迁移历史数据。每当我运行我的Web API时,EF会读取数据库并发现数据库上下文与迁移历史表中的规范不同步。
在我运行了UPDATE-DATABASE后,一切都顺利进行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接