ZIP ファイル内のエントリの順序を制御する必要がある場合は、DotNetZip と ZipOutputStream を使用できます。
あなたは DotNetZip を試したと言っていましたが、それ (epub バリデーター) は MIME タイプについて不平を言うエラーを出しました。これはおそらく、DotNetZip 内で ZipFile タイプを使用したためです。ZipOutputStream を使用すると、zip エントリの順序を制御できます。これは明らかに epub にとって重要です (フォーマットはわかりませんが、推測です)。
編集
確認したところ、ウィキペディアの epub ページに.epub ファイルのフォーマット方法が記載されています。mimetype ファイルには特定のテキストが含まれている必要があり、圧縮も暗号化もされていない必要があり、ZIP アーカイブの最初のファイルとして表示される必要があります。
ZipOutputStream を使用して、その特定の ZipEntry で CompressionLevel = None を設定することでこれを行います。この値はデフォルトではありません。
サンプルコードは次のとおりです。
private void Zipup()
{
string _outputFileName = "Fargle.epub";
using (FileStream fs = File.Open(_outputFileName, FileMode.Create, FileAccess.ReadWrite ))
{
using (var output= new ZipOutputStream(fs))
{
var e = output.PutNextEntry("mimetype");
e.CompressionLevel = CompressionLevel.None;
byte[] buffer= System.Text.Encoding.ASCII.GetBytes("application/epub+zip");
output.Write(buffer,0,buffer.Length);
output.PutNextEntry("META-INF/container.xml");
WriteExistingFile(output, "META-INF/container.xml");
output.PutNextEntry("OPS/"); // another directory
output.PutNextEntry("OPS/whatever.xhtml");
WriteExistingFile(output, "OPS/whatever.xhtml");
// ...
}
}
}
private void WriteExistingFile(Stream output, string filename)
{
using (FileStream fs = File.Open(fileName, FileMode.Read))
{
int n = -1;
byte[] buffer = new byte[2048];
while ((n = fs.Read(buffer,0,buffer.Length)) > 0)
{
output.Write(buffer,0,n);
}
}
}
ZipOutputStream のドキュメントはこちらを参照してください。