Chắc chắn là. Tôi tải tệp (PDF/hình ảnh) lên db của tôi trong app. Đối tượng mô hình của tôi thực sự lưu trữ các tập tin như là một mảng byte, nhưng đối với các chức năng khác tôi phải chuyển đổi sang và từ các dòng để im chắc chắn nó chỉ là dễ dàng để giữ nó trong định dạng dòng.
Dưới đây là một số ví dụ mã (copy n paste) từ cấp ứng dụng
Đối tượng File
của tôi mà tôi sử dụng để di chuyển các file (PDF/images) xung quanh:
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; }
}
..the PdfDoc
loại đặc biệt cho các tập tin PDF:
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;
}
}
.. ví dụ về một hành động tiếp nhận đa phần POST cho tập tin tải lên:
//
// 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 });
}
Bây giờ bạn có thể thấy tôi vượt qua các đối tượng tập tin để dịch vụ của tôi ở đây nhưng bạn có thể chọn để thêm nó vào phiên và vượt qua một id trở lại quan điểm 'xem trước' chẳng hạn.
Cuối cùng, đây là một hành động chung tôi sử dụng để render file ra cho khách hàng (bạn có thể có một cái gì đó tương tự như làm cho các tập tin/suối từ Session):
//
// 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);
}
EDIT:
tôi nhận thấy tôi cần thêm mẫu để giải thích sự above-
Đối với hành động tải lên trên, lớp FileUploadResultDTO
:
public class FileUploadResultDTO
{
public List<File> Files { get; set; }
public Int32 TotalBytes { get; set; }
public string ErrorMessage { get; set; }
}
Và GetFilesFromRequest
chức năng:
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;
}
Và cuối cùng (tôi hy vọng tôi có mọi thứ bạn cần bây giờ) ReadFully
chức năng này. Nó không phải là thiết kế của tôi. Tôi nhận được nó từ đọc net - dòng có thể được khôn lanh.Tôi thấy chức năng này là cách thành công nhất để đọc toàn bộ luồng:
/// <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;
}
Tham khảo ví dụ của tôi dưới đây mà viết byte mảng như một FileResult. Nó an toàn hơn Response.BinaryWrite vì bạn đang sử dụng mvc aspnet. Ngoài ra, hãy sử dụng trình đọc luồng tốt hơn (xem bản chỉnh sửa của tôi bên dưới) và duyệt qua mã của bạn để xác minh rằng tệp đã tải lên thực sự bị bán phá giá trong phiên. ;) –
Vấn đề chính với mã của bạn là bạn chưa bao giờ đọc từ luồng đầu vào. Bạn đang tạo một bộ đệm với kích thước phù hợp, nhưng bạn đọc từ luồng bộ nhớ trống vào bộ đệm thay vì từ luồng đầu vào. Những gì bạn nhận được chỉ là một mảng đầy đủ các số không, mà rõ ràng là không hoạt động như một tập tin PDF. – Guffa