如何为 ZipFile 设置网络 api 控制器

How to setup web api controller for ZipFile

我正在尝试创建并 return 包含所选文档的 zip 文件。控制台显示选定的 DocumentId 正在从 Angular 控制器发送到 api,但我收到一个空错误。

Api控制器

 public HttpResponseMessage Get(string[] id)
    {
        List<Document> documents = new List<Document>();
        using (var context = new ApplicationDbContext())
        {
            Document document = context.Documents.Find(id);

            if (document == null)
            {
                if (document == null)
                {
                    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
                }
            }

            using (var zipFile = new ZipFile())
            {
                // Make zip file
                foreach (var d in documents)
                {
                    var dt = d.DocumentDate.ToString("y").Replace('/', '-').Replace(':', '-');
                    string fileName = String.Format("{0}-{1}-{2}.pdf", dt, d.PipeName, d.LocationAb);
                    zipFile.AddEntry(fileName, d.DocumentUrl);
                }

                return ZipContentResult(zipFile);
            }
        }
    }

    protected HttpResponseMessage ZipContentResult(ZipFile zipFile)
    {

        var pushStreamContent = new PushStreamContent((stream, content, context) =>
        {
            zipFile.Save(stream);
            stream.Close(); // After save we close the stream to signal that we are done writing.
        }, "application/zip");

        return new HttpResponseMessage(HttpStatusCode.OK) { Content = pushStreamContent };
    }

更新

public HttpResponseMessage Get([FromUri] string[] id)
    {
        var documents = new List<Document>();
        using (var context = new ApplicationDbContext())
        {
            foreach (string doc in id)
            {
                Document document = context.Documents.Find(new object[] { doc });
                if (document == null)
                {
                    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
                }

                documents.Add(document);
            }

            using (var zipFile = new ZipFile())
            {
                // Make zip file
                foreach (var d in documents)
                {
                    var dt = d.DocumentDate.ToString("y").Replace('/', '-').Replace(':', '-');
                    string fileName = String.Format("{0}-{1}-{2}.pdf", dt, d.PipeName, d.LocationAb);
                    zipFile.AddEntry(fileName, d.DocumentUrl);
                }

                return ZipContentResult(zipFile);
            }
        }
    }

错误

{"The argument types 'Edm.Int32' and 'Edm.String' are incompatible for this operation. Near WHERE predicate, line 1, column 82."}

堆栈跟踪

 at System.Data.Entity.Internal.Linq.InternalSet`1.FindInStore(WrappedEntityKey key, String keyValuesParamName)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Find(Object[] keyValues)
   at System.Data.Entity.DbSet`1.Find(Object[] keyValues)
   at  TransparentEnergy.ControllersAPI.apiZipPipeLineController.Get(String[] id)  in e:\Development\TransparentEnergy\TransparentEnergy\ControllersAPI  \BatchZipApi\apiZipPipeLineController.cs:line 25
   at lambda_method(Closure , Object , Object[] )
   at  System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor. <>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[]  methodParameters)
   at  System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Exec       ute(Object instance, Object[] arguments)
   at  System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpCo       ntrollerContext controllerContext, IDictionary`2 arguments,  CancellationToken cancellationToken)

将string[] id更改为List id后watch的新截图

除非您忘记将所有代码复制到问题中,否则您永远不会向文档列表对象添加任何内容。

一开始你创建了一个名为 documents 的新列表对象:

List<Document> documents = new List<Document>();

然后您搜索项目并将它们放在新的文档对象中:

Document document = context.Documents.Find(id);

然后在尝试制作 zip 文件时,您正在访问第一个创建的 List 对象,该对象中没有任何内容。

foreach (var d in documents)

我相信这会导致您保存 zip 文件时抛出异常

zipFile.Save(stream);

In the find line above

Document document = context.Documents.Find(id);

did you intend

documents = context.Documents.Find(id);

更新 2

我用你的信息建立了一个数据库,创建了一个 MVC 网站 api,它使用 POST 的 JSON 来传递数据。这会使用按 ID 从数据库中提取的项目填充列表。

[HttpPost]
[ActionName("ZipFileAction")]
public HttpResponseMessage ZipFiles([FromBody]int[] id)
{
    if (id == null)
    {//Required IDs were not provided
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest));
    }

    List<Document> documents = new List<Document>();
    using (var context = new ApplicationDbContext())
    {
        foreach (int NextDocument in id)
        {
            Document document = context.Documents.Find(NextDocument);

            if (document == null)
            {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
            }

            documents.Add(document);
        }

        using (var zipFile = new ZipFile())
        {
            // Make zip file
            foreach (var d in documents)
            {
                var dt = d.DocumentDate.ToString("y").Replace('/', '-').Replace(':', '-');
                string fileName = String.Format("{0}-{1}-{2}.pdf", dt, d.PipeName, d.LocationAb);
                zipFile.AddEntry(fileName, d.DocumentUrl);
            }

            return ZipContentResult(zipFile);
        }
    }
}

{"The argument types 'Edm.Int32' and 'Edm.String' are incompatible ..."}

听起来你的键列是一个 int 类型,你正在使用字符串搜索它。尝试将参数的类型从字符串更改为整数。我将其重命名为 ids,因为它似乎是一个文档标识符列表。

优化版本将在单个查询中获取所有需要的文档:

public HttpResponseMessage Get([FromUri] int[] ids)
{
    using (var context = new ApplicationDbContext())
    {
        var documents = context.Documents.Where(doc => ids.Contains(doc.Id)).ToList();
        if (documents.Count != ids.Length)
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
        }

        using (var zipFile = new ZipFile())
        {
            // Make zip file
            foreach (var d in documents)
            {
                var dt = d.DocumentDate.ToString("y").Replace('/', '-').Replace(':', '-');
                string fileName = String.Format("{0}-{1}-{2}.pdf", dt, d.PipeName, d.LocationAb);
                zipFile.AddEntry(fileName, d.DocumentUrl);
            }

            return ZipContentResult(zipFile);
        }
    }
}