ASP.NET (C#) Example
Caution
For server security, please refer to the link below when handling this work.
[Software Security Weakness Diagnosis Guide]
1. Image / Video / File Upload
Caution
The file-upload portion of the sample code below is intentionally minimal and lacks proper security handling.
For the file-upload portion, use what is already in place inside your project, and refer to the code below for the integration portion only.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
// Absolute path to WEB ROOT
private const string WEB_ROOT_ABS_PATH = @"C:\workspace\SynapEditor_C#\SynapEditor\wwwroot";
// Where uploaded files go
private readonly string UPLOAD_DIR_ABS_PATH = Path.Combine(WEB_ROOT_ABS_PATH, "uploads");
[HttpPost("api/uploadFile")]
public IActionResult UploadFile(IFormFile file)
{
string uploadFileAbsPath = SaveFileToDisk(file).Result;
string uploadFileRelPath = Path.GetRelativePath(UPLOAD_DIR_ABS_PATH, uploadFileAbsPath);
return Ok(new { uploadPath = uploadFileRelPath });
}
private async Task<string> SaveFileToDisk(IFormFile file)
{
string extension = Path.GetExtension(file.FileName);
string uploadFileName = $"{Guid.NewGuid()}{extension}";
string uploadFileAbsPath = Path.Combine(UPLOAD_DIR_ABS_PATH, uploadFileName);
using (var fileStream = new FileStream(uploadFileAbsPath, FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
return uploadFileAbsPath;
}
2. HWP / Word / Excel Document Import
Caution
The file-upload portion of the sample code below is intentionally minimal and lacks proper security handling.
For the file-upload portion, use what is already in place inside your project, and refer to the code below for the integration portion only.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
private const string WEB_ROOT_ABS_PATH = @"C:\workspace\SynapEditor_C#\SynapEditor\wwwroot";
// Temporary workspace for decompressing converted documents
private readonly string WORK_DIR_ABS_PATH = Path.Combine(WEB_ROOT_ABS_PATH, "works");
private readonly string UPLOAD_DIR_ABS_PATH = Path.Combine(WEB_ROOT_ABS_PATH, "uploads");
[HttpPost("api/importDoc")]
public async Task<IActionResult> ImportDoc(IFormFile file)
{
// 1. Save the document to disk
string uploadFileAbsPath = SaveFileToDisk(file).Result;
// 2. Convert it to model data
string importAbsPath = ExecuteConverter(uploadFileAbsPath).Result;
string importRelPath = Path.GetRelativePath(WEB_ROOT_ABS_PATH, importAbsPath);
// 3. Read the model data
// From v2.3.0 the filename is "document.pb" (was "document.word.pb")
string pbFileAbsPath = Path.Combine(importAbsPath, "document.pb");
int[] serializedData = ReadPbData(pbFileAbsPath);
// 4. Return
return Ok(new { serializedData, importPath = importRelPath });
}
private async Task<string> SaveFileToDisk(IFormFile file)
{
string extension = Path.GetExtension(file.FileName);
string uploadFileName = $"{Guid.NewGuid()}{extension}";
string uploadFileAbsPath = Path.Combine(UPLOAD_DIR_ABS_PATH, uploadFileName);
using (var fileStream = new FileStream(uploadFileAbsPath, FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
return uploadFileAbsPath;
}
private async Task<string> ExecuteConverter(string docFileAbsPath)
{
const string CONVERTER_ABS_PATH = @"C:\workspace\SynapEditor_C#\sedocConverter.exe";
const string FONTS_DIR_ABS_PATH = @"C:\workspace\SynapEditor_C#\fonts";
const string TEMP_DIR_ABS_PATH = @"C:\workspace\SynapEditor_C#\tmp";
string outputAbsPath = Path.Combine(WORK_DIR_ABS_PATH, Path.GetFileName(docFileAbsPath));
var startInfo = new ProcessStartInfo
{
FileName = CONVERTER_ABS_PATH,
Arguments = $"-f {FONTS_DIR_ABS_PATH} {docFileAbsPath} {outputAbsPath} {TEMP_DIR_ABS_PATH}",
CreateNoWindow = false,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
};
using (Process exeProcess = Process.Start(startInfo))
{
// Treat conversions taking more than 30 seconds as a failure
if (exeProcess.WaitForExit(30000)) return outputAbsPath;
exeProcess.Kill();
return "";
}
}
/*
* Serialize document model data so the Synap Editor front-end module can consume it.
* (Important: import will fail if the body of this function is modified.)
*/
private static int[] ReadPbData(string pbFilePath)
{
var pbData = new List<int>();
using (var fileStream = new FileStream(pbFilePath, FileMode.Open, FileAccess.Read))
{
fileStream.Seek(16, SeekOrigin.Begin);
using (var inflater = new InflaterInputStream(fileStream))
{
byte[] buffer = new byte[1024];
int count;
while ((count = inflater.Read(buffer, 0, buffer.Length)) > 0)
{
for (int i = 0; i < count; i++) pbData.Add(buffer[i] & 0xFF);
}
}
}
return pbData.ToArray();
}