2016-11-13 37 views
0

在Visual Studio中創建代碼時,它將從臨時目錄運行。但是在託管服務提供商(專門託管ASP.NET網站的服務提供商)中,它將位於不同的目錄中(通常是具有IIS的應用程序服務器虛擬文件夾)。我需要將文件上傳到IIS Web服務器可以找到的目錄中,因此下面的用例將起作用。在Visual Studio中上傳和下載與生產

問:我如何在MVC控制器/視圖中定義我的鏈接,以便它們在開發和生產中均可用(上傳&下載)?

使用案例:我的應用程序需要允許一個文件被上傳(仍然不知道在哪裏上開發框上傳到),然後通過另一個網頁下載同一個文件的鏈接。

+1

使用'服務器。在MapPath()'創建,讓你的文件夾/文件的相對或虛擬路徑 –

+0

邊注:請確保您有足夠的預算來支付託管,允許運行代碼完全信任... –

回答

0

如果你需要更詳細的答案,我會給你一些提示,希望這會讓你走上正軌。

  1. 定義一個合同,所以你可以在命令,如果以後需要改變底層的文件存儲的影響降到最低,並修改您的代碼抽象的任何具體文件提供者實現。例如,如果您在將來的版本中轉到Azure,則可以實現AzureFileProvider並使用Blob存儲文件。

    public interface IFileProvider 
    { 
        UploadResult UploadFile(byte[] fileContent, string fileName); 
        DownloadResult DownloadFile(int fileId); 
    } 
    

實現你的基於文件系統的文件提供的接口:

public class FileSystemFileProvider : IFileProvider 
{ 
    public FileSystemFileProvider(string absouteBasePath) 
    { 
     //Check if absoluteBasPath exists and create the directory if it doesn't. 
     if (!Directory.Exists(absouteBasePath)) 
      Directory.CreateDirectory(absouteBasePath); 
    } 

    public UploadResult UploadFile(byte[] fileContent, string fileName) 
    { 
     //TODO: Your upload file implementation here 
    } 

    public DownloadResult DownloadFile(int fileId) 
    { 
     //TODO Your download file implementation here 
    } 
} 

您可以根據自己的需要調整您的合同。這裏的示例UploadResult和DownloadResult是簡單的類來檢索操作的結果。例如,這可以是用於DownloadResult一個定義:

public class DownloadResult 
{ 
    public bool Success { get; set; } 
    public byte[] FileContent { get; set; } 
    public string DownloadName { get; set; } 
    public string SizeInBytes { get; set; } 
    //... any other useful properties 
} 
  • 在你StartupAuth.cs或Global.asax中(其中的引導程序代碼運行的地方,初始化文件提供您的具體實現。這種做法在地方IoC容器更好地工作,你可以使用AutoFacNinject或者其他任何你喜歡,但請做你自己一個忙,並使用一個。

    //read the base path from web.config so you may adjust it on production hosting provider without need to make and compile the app 
    var fileBasePath = ConfigurationManager.AppSettings["fileBasePath"]; 
    
    //get the path as an absolute file system path 
    var absoluteBasePath = Server.MapPath(fileBasePath); 
    
    //Initialize the file provider with the absolute path 
    var fileProvider = new FileSystemFileProvider(absoluteBasePath); 
    
    //TODO: Configure your IoC to return the fileProvider instance when an IFileProvider is requested. 
    
  • 正如你在看步驟2我從中讀取應用程序設置值web.config文件。這應該出現在配置文件的appSettings部分。

    <appSettings> 
        <add key="fileBasePath" value="~/FileStorage"/> 
    </appSettings> 
    
  • 帶着所有這些地方,你可以注入你的fileProvider到你的控制器是這樣的:

    public class UploadController : Controller 
    { 
        private readonly IFileProvider fileProvider; 
    
        public UploadController(IFileProvider fileProvider) 
        { 
         this.fileProvider = fileProvider; 
        } 
    
  • 然後當需要它,你可以用你的供應商的相關行動。

    [HttpPost] 
    public ActionResult Upload(FileUploadModel model) 
    { 
        //Validate 
        if (ModelState.IsValid) 
        { 
         //Use your fileProvider here to upload the file 
         var content = new byte[model.PostedFile.ContentLength]; 
         model.PostedFile.InputStream.Write(content, 0, content.Length); 
         var result = fileProvider.UploadFile(content, model.PostedFile.FileName); 
         if (result.Success) 
         { 
          //TODO: Notify the user about operation success 
    
          return RedirectToAction("Index", "Upload"); 
         } 
        } 
    
        // 
        return View(model); 
    } 
    

    希望這有助於! PS:我不知道爲什麼代碼格式有點瘋狂。

    +0

    額外的4個空格縮進如果編號列表:) –

    +0

    非常感謝@Stephen。 –

    +0

    @KarelTamayo這是一個非常有趣的答案!這需要我消化時間。我只是在尋找保存上傳文件的位置,以便在生產環境中可以找到它們,但我可以看到很多iun你的答案,我喜歡,我想調查!謝謝!!! –