I am trying to create and return a zip file with selected documents. The console shows that the selected DocumentId's are being sent from the Angular controller to the api but I am getting a null error.
ApiController
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 };
}
UPDATE
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);
}
}
}
ERROR
{"The argument types 'Edm.Int32' and 'Edm.String' are incompatible for this operation. Near WHERE predicate, line 1, column 82."}
STACKTRACE
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)
New Screenshot of watch after changing string[] id to List id
Unless you forgot to copy all the code into the question you never add anything to the documents list object.
At the start you create a new List object named documents:
List<Document> documents = new List<Document>();
You then search for items and place them in a new document object:
Document document = context.Documents.Find(id);
Then when attempting to make the zip file you are accessing the first created List object that has nothing put into it.
foreach (var d in documents)
I believe this is then causing your save of the zip file to throw an exception
zipFile.Save(stream);
In the find line above
Document document = context.Documents.Find(id);
did you intend
documents = context.Documents.Find(id);
UPDATE 2
I set up a database with your information, created a MVC web api that takes a POST of JSON to pass the data. This populates the list with items pulled from a database by 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 ..."}
Sounds like your key column is an int type and you are searching it using a string. Try changing the type of the parameter from string to int. I renamed it ids
as it seems to be a list of document identifiers.
An optimized version would get all needed documents in a single query :
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);
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.