확실히입니다. 내 app 내 db에 파일 (PDF/이미지)를 업로드합니다. 내 모델 개체는 실제로 파일을 바이트 배열로 저장하지만 스트림 형식으로 유지하기 쉽도록 스트림간에 변환해야하는 다른 함수에 대해서도 마찬가지입니다.
public class File : CustomValidation, IModelBusinessObject
{
public int ID { get; set; }
public string MimeType { get; set; }
public byte[] Data { get; set; }
public int Length { get; set; }
public string MD5Hash { get; set; }
public string UploadFileName { get; set; }
}
용맹 한 PdfDoc
종류 : 여기
내가 주위에 파일 (PDF 파일/이미지)를 이동하는 데 사용할 내 APP-
File
개체에서 일부 코드 예제 (N 붙여 복사)입니다
public class PdfDoc : File
{
public int ID { get; set; }
public int FileID
{
get { return base.ID; }
set { base.ID = value; }
}
[StringLength(200, ErrorMessage = "The Link Text must not be longer than 200 characters")]
public string LinkText { get; set; }
public PdfDoc() { }
public PdfDoc(File file)
{
MimeType = file.MimeType;
Data = file.Data;
Length = file.Length;
MD5Hash = file.MD5Hash;
UploadFileName = file.UploadFileName;
}
public PdfDoc(File file, string linkText)
{
MimeType = file.MimeType;
Data = file.Data;
Length = file.Length;
MD5Hash = file.MD5Hash;
UploadFileName = file.UploadFileName;
LinkText = linkText;
}
}
.. 파일 업로드에 대한 여러 부분 POST를 수신 동작의 예 :
특히 PDF 파일
//
// POST: /Announcements/UploadPdfToAnnouncement/ID
[KsisAuthorize(Roles = "Admin, Announcements")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UploadPdfToAnnouncement(int ID)
{
FileManagerController.FileUploadResultDTO files =
FileManagerController.GetFilesFromRequest((HttpContextWrapper)HttpContext);
if (String.IsNullOrEmpty(files.ErrorMessage) && files.TotalBytes > 0)
{
// add SINGLE file to the announcement
try
{
this._svc.AddAnnouncementPdfDoc(
this._svc.GetAnnouncementByID(ID),
new PdfDoc(files.Files[0]),
new User() { UserName = User.Identity.Name });
}
catch (ServiceExceptions.KsisServiceException ex)
{
// only handle our exceptions
base.AddErrorMessageLine(ex.Message);
}
}
// redirect back to detail page
return RedirectToAction("Detail", "Announcements", new { id = ID });
}
이제 서비스 개체를 내 서비스에 전달할 수 있지만 세션에 추가하고 ID를 '미리보기'보기로 다시 전달하도록 선택할 수 있습니다.
//
// GET: /FileManager/GetFile/ID
[OutputCache(Order = 2, Duration = 600, VaryByParam = "ID")]
public ActionResult GetFile(int ID)
{
FileService svc = ObjectFactory.GetInstance<FileService>();
KsisOnline.Data.File result = svc.GetFileByID(ID);
return File(result.Data, result.MimeType, result.UploadFileName);
}
편집 :
내가 마지막으로
, 여기에 (당신이 파일 세션에서/스트림을 렌더링 비슷한 가질 수) 내가 클라이언트에 파일을 렌더링하는 데 사용하는 일반적인 작업입니다
public class FileUploadResultDTO
{
public List<File> Files { get; set; }
public Int32 TotalBytes { get; set; }
public string ErrorMessage { get; set; }
}
: 나는
FileUploadResultDTO
클래스 위의 업로드 작업에 대한 전술
을 설명하기 위해 더 많은 샘플을 필요 눈치
그리고 GetFilesFromRequest
기능 :
public static FileUploadResultDTO GetFilesFromRequest(HttpContextWrapper contextWrapper)
{
FileUploadResultDTO result = new FileUploadResultDTO();
result.Files = new List<File>();
foreach (string file in contextWrapper.Request.Files)
{
HttpPostedFileBase hpf = contextWrapper.Request.Files[file] as HttpPostedFileBase;
if (hpf.ContentLength > 0)
{
File tempFile = new File()
{
UploadFileName = Regex.Match(hpf.FileName, @"(/|\\)?(?<fileName>[^(/|\\)]+)$").Groups["fileName"].ToString(), // to trim off whole path from browsers like IE
MimeType = hpf.ContentType,
Data = FileService.ReadFully(hpf.InputStream, 0),
Length = (int)hpf.InputStream.Length
};
result.Files.Add(tempFile);
result.TotalBytes += tempFile.Length;
}
}
return result;
}
그리고 마지막으로이 ReadFully
기능 (나는 당신이 지금 필요로하는 모든 것을 갖추고 바랍니다). 내 디자인이 아니야. 나는 인터넷에서 그것을 얻었다 - 독서는 까다로울 수있다.나는이 기능을 완전히 스트림을 읽을 수있는 가장 성공적인 방법입니다 찾을 :
/// <summary>
/// Reads data from a stream until the end is reached. The
/// data is returned as a byte array. An IOException is
/// thrown if any of the underlying IO calls fail.
/// </summary>
/// <param name="stream">The stream to read data from</param>
/// <param name="initialLength">The initial buffer length</param>
public static byte[] ReadFully(System.IO.Stream stream, long initialLength)
{
// reset pointer just in case
stream.Seek(0, System.IO.SeekOrigin.Begin);
// If we've been passed an unhelpful initial length, just
// use 32K.
if (initialLength < 1)
{
initialLength = 32768;
}
byte[] buffer = new byte[initialLength];
int read = 0;
int chunk;
while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0)
{
read += chunk;
// If we've reached the end of our buffer, check to see if there's
// any more information
if (read == buffer.Length)
{
int nextByte = stream.ReadByte();
// End of stream? If so, we're done
if (nextByte == -1)
{
return buffer;
}
// Nope. Resize the buffer, put in the byte we've just
// read, and continue
byte[] newBuffer = new byte[buffer.Length * 2];
Array.Copy(buffer, newBuffer, buffer.Length);
newBuffer[read] = (byte)nextByte;
buffer = newBuffer;
read++;
}
}
// Buffer is now too big. Shrink it.
byte[] ret = new byte[read];
Array.Copy(buffer, ret, read);
return ret;
}
그 아래에있는 내 예를 참조가 바이트를 기록 배열을 FileResult로 설정합니다. aspnet mvc를 사용하고 있기 때문에 Response.BinaryWrite보다 안전합니다. 또한 더 나은 스트림 리더 (아래 편집 참조)를 사용하고 코드를 단계별로 실행하여 업로드 된 파일이 실제로 세션에 버려지는지 확인하십시오. ;) –
코드의 주요 문제점은 입력 스트림에서 전혀 읽지 않는다는 것입니다. 올바른 크기의 버퍼를 만들고 있지만 빈 메모리 스트림에서 입력 스트림 대신 버퍼로 읽습니다. 당신이 얻는 것은 분명히 0으로 가득 찬 배열 일뿐입니다. 분명히 PDF 파일로 작동하지 않습니다. – Guffa