2012-06-10 25 views
31

Tôi đang tải lên tệp bằng ASP.NET Web API. Tôi đã làm điều này trước RC nhưng vì lý do nào đó tệp được lưu dưới dạng "BodyPart_3ded2bfb-40be-4183-b789-9301f93e90af" thay vì tên tệp. Biến tên tệp dưới đây trả về chuỗi bodypart này thay vì tên tệp. Tôi dường như không thể tìm ra nơi tôi đang đi sai. Bất kỳ trợ giúp được đánh giá cao.Tệp Web API ASP.NET được lưu dưới dạng "BodyPart_3ded2bfb-40be-4183-b789-9301f93e90af"

Khách hàng mã:

function upload() { 
    $("#divResult").html("Uploading..."); 
    var formData = new FormData($('form')[0]); 
    $.ajax({ 
     url: 'api/files/uploadfile?folder=' + $('#ddlFolders').val(), 
     type: 'POST', 
     success: function (data) { 
      $("#divResult").html(data); 
     }, 
     data: formData, 
     cache: false, 
     contentType: false, 
     processData: false 
    }); 
}; 

Bộ điều khiển:

public Task<HttpResponseMessage> UploadFile([FromUri]string folder) 
    { 
     if (!Request.Content.IsMimeMultipartContent()) 
     { 
      throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType)); 
     } 

     // Save file 
     MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/Files")); 
     Task<IEnumerable<HttpContent>> task = Request.Content.ReadAsMultipartAsync(provider); 

     return task.ContinueWith<HttpResponseMessage>(contents => 
     { 
      string filename = provider.BodyPartFileNames.First().Value; 
      return new HttpResponseMessage() 
      { 
       Content = new StringContent(string.Format("File saved in {0}.", folder)) 
      }; 

     }, TaskScheduler.FromCurrentSynchronizationContext()); 

Các tập tin đang tìm kiếm như:

enter image description here

+0

tôi đã viết lên ví dụ hoàn chỉnh của tôi ở đây: http://rivdiv.wordpress.com/2012/06/13/uploading-a-file-using-asp-net-web-api/ – Rivka

Trả lời

44

Đó là một sự thay đổi ý thức, chúng tôi thực hiện - nó được coi một nguy cơ bảo mật để lấy tên tập tin được cung cấp trong Content-Dispositi trên trường tiêu đề và vì vậy thay vào đó, chúng tôi hiện tính toán tên tệp mà bạn đang thấy.

Nếu bạn muốn tự kiểm soát tên tệp máy chủ cục bộ, bạn có thể lấy được từ MultipartFormDataStreamProvider và ghi đè GetLocalFileName để cung cấp bất kỳ tên nào bạn muốn. Lưu ý rằng mặc dù có thể có những cân nhắc về bảo mật làm như vậy.

Hope this helps,

Henrik

+3

Cảm ơn bạn đã trả lời. Làm cách nào để lưu tệp thực sự một cách chính xác? Hiện tại, nó thuộc loại dữ liệu "Tệp" không có phần mở rộng nào và không thể mở được. – Rivka

+4

Tôi đã tìm được một công việc xung quanh - để sử dụng File.Move và thêm phần mở rộng chính xác bằng cách sử dụng * provider.BodyPartFileNames.FirstOrDefault(). Key.TrimStart ('"'). TrimEnd ('"') * để lấy tên tệp gốc. Điều này cảm thấy một chút ngược lại mặc dù. Tôi đánh giá cao bất kỳ sự giác ngộ nào. – Rivka

+1

public class FormDataStreamer: MultipartFormDataStreamProvider { FormDataStreamer công cộng (string rootPath): cơ sở (rootPath) {} FormDataStreamer công cộng (string rootPath, int BUFFERSIZE): cơ sở (rootPath, BUFFERSIZE) {} công chuỗi override GetLocalFileName (HttpContentHeaders header) {var srcFileName = headers.ContentDisposition.FileName.Replace ("\"", ""); trở Guid.NewGuid() + Path.GetExtension (srcFileName); }} –

16

tôi cập nhật mã cho hướng dẫn để làm cho nó làm việc với RC ASP.NET Web API. Thật vậy, như Henrik đề cập đến Content-Disposition không còn được sử dụng một tên tập tin. Xem các tệp nguồn ở cuối bài đăng - http://www.strathweb.com/2012/04/html5-drag-and-drop-asynchronous-multi-file-upload-with-asp-net-webapi/

Xin lưu ý rằng có nhiều thay đổi đối với MultipartFormDataStreamProvider không thực hiện việc cắt thành RC, vì vậy giờ đây sẽ linh hoạt hơn. Henrik viết blog về những người ở đây - http://blogs.msdn.com/b/henrikn/archive/2012/04/27/asp-net-web-api-updates-april-27.aspx.

EDIT: Tôi đã viết blog về cách thức mới và cải tiến của tải lên tập tin trong RTM Web API, do đó nên hy vọng giúp đỡ được thứ có tổ chức - http://www.strathweb.com/2012/08/a-guide-to-asynchronous-file-uploads-in-asp-net-web-api-rtm/

+0

Thanx, ví dụ của bạn dễ đọc và dễ theo dõi. Tôi đã tự viết bằng mã beta d đã kéo tóc của tôi ra cố gắng tìm ra cách để làm điều đó trong RC. – Keith

+0

Cảm ơn bạn Filip. Vì vậy, tôi giả sử đúng cách * là * để lấy tệp gốc từ khóa và sau đó di chuyển/đổi tên tệp. Đã không đi qua bất kỳ bài viết Web API đã thay đổi cụ thể RC này, vui mừng tôi đặt câu hỏi này ra khỏi đó. Cảm ơn. – Rivka

+0

Điều này thật đẹp. Làm việc như một say mê! – Detilium

7

Ở đây, tác phẩm này với tôi

Trong Bộ điều khiển API

// We implement MultipartFormDataStreamProvider to override the filename of File which 
// will be stored on server, or else the default name will be of the format like Body- 
// Part_{GUID}. In the following implementation we simply get the FileName from 
// ContentDisposition Header of the Request Body. 
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider 
{ 
    public CustomMultipartFormDataStreamProvider(string path) : base(path) { } 

    public override string GetLocalFileName(HttpContentHeaders headers) 
    { 
     return headers.ContentDisposition.FileName.Replace("\"", string.Empty); 
    } 
} 

Sau đó

string root = HttpContext.Current.Server.MapPath("~/App_Data");  
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(root); 

Cảm ơn,

Các vấn đề liên quan