2015-02-18 3 views
0

Я застрял на сохранении виртуального пути загрузки файла на мой db. Без виртуального пути файл сохраняется, а URL-адрес в db - это физический путь к файлу. поэтому, когда я пытаюсь загрузить его, я получаю локальный ресурс, который не разрешен. url начинается с файла: /// C: путь ....
Когда я использую точки прерывания, я вижу, что физический путь изменяется на виртуальный путь, однако исключение исключается.Почему виртуальный путь map.server не сохраняется в базе данных

apiController

//POST 
    public async Task<HttpResponseMessage> Post() 
    { 

     try 
     { 
      //saving the posted file to the harddisk 
      string root = HttpContext.Current.Server.MapPath("~/Files/"); 
      var provider = new MultipartFormDataStreamProvider(root); 
      await Request.Content.ReadAsMultipartAsync(provider); 

      //Get Logged in User Name 
      var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())); 
      var user = manager.FindById(User.Identity.GetUserId()); 

      //getting the user details and storing in the object 
      Document model = new Document(); 
      model.TypeId = Convert.ToInt32(provider.FormData["TypeId"]); 
      model.TypeName = provider.FormData["TypeName"]; 
      model.PipeName = provider.FormData["PipeName"]; 
      model.DocumentUrl = provider.FormData["DocumentUrl"]; 
      model.DocumentUrl = model.DocumentUrl == "" ? null : model.DocumentUrl; 

      //if there is a file then save that file to the desired location 
      if (provider.FileData.Count > 0) 
      { 
       MultipartFileData fileData = provider.FileData[0]; 
       FileInfo fi = new FileInfo(fileData.LocalFileName); 
       if (!Directory.Exists(fi.DirectoryName)) 
       { 
        Directory.CreateDirectory(fi.DirectoryName); 
       } 
       else 
       { 
        //getting the file saving path 
        string clientFileName = fileData.Headers.ContentDisposition.FileName.Replace(@"""", ""); 
        if (clientFileName != "") 
        { 
         string clientExtension = clientFileName.Substring(clientFileName.LastIndexOf('.')); 
         string space = ("-"); 
         var dt = model.DocumentDate.ToString("y").Replace('/', '-').Replace(':', '-'); 
         var CompanyName = model.CompanyName.Replace('_', ' '); 

         string vPath = root.Replace(@"C:\Development\TransparentEnergy\TransparentEnergy", "~").Replace("\\", "/"); 
         string serverFileName = vPath + CompanyName + space + model.TypeName + space + model.CounterPartyName + space + dt + clientExtension; 
         model.DocumentUrl = serverFileName; 



         FileInfo fiOld = new FileInfo(vPath); 
         if (fiOld.Exists) 
          fiOld.Delete(); 
         //if (File.Exists()) 
         fi.MoveTo(serverFileName); 
        } 
        else 
        { 
         if (fi.Exists) 
          fi.Delete(); 
        } 
       } 
      } 
      //calling DB to save the user details 
      using (var context = new ApplicationDbContext()) 
      { 
       //save to db 
       context.Documents.Add(model); 
       context.SaveChanges(); 
      } 
     } 
     catch (Exception fex) 
     { 
      return Request.CreateErrorResponse(HttpStatusCode.NotFound, fex); 
     } 
     //sending the confirmation or error back to the user 
     return Request.CreateResponse(HttpStatusCode.OK); 
    } 

Точка останова по адресу:

model.DocumentUrl = serverFileName; 

показывает "2006.pdf ~/Files/Black Elk-Инвойсы-None-Май"

T он Исключение здесь происходит

FileInfo fiOld = new FileInfo(vPath); 
    if (fiOld.Exists) 
    fiOld.Delete(); 
//if (File.Exists()) 
    fi.MoveTo(serverFileName); 

FiloInfo (VPATH) показывает

~/Files/

Исключение происходит в:

fi.MoveTo(serverFileName); 

Exception сообщение:

на System.IO .__ Error.WinIOError (Int32 ERRORCODE, String maybeFullPath) в System.IO .__ Error.WinIOError() в System.IO.FileInfo.MoveTo (String DestFileName) в TransparentEnergy.ControllersAPI.apiInvoiceController. d__0.MoveNext() в C: \ Development \ TransparentEnergy \ TransparentEnergy \ ControllersAPI \ SubmitApi \ apiInvoiceController.cs: линия 87

Обновлено

//POST 
    public async Task<HttpResponseMessage> Post() 
    { 

     try 
     { 
      //saving the posted file to the harddisk 
      string root = HttpContext.Current.Server.MapPath("~/Files/"); 
      var provider = new MultipartFormDataStreamProvider(root); 
      await Request.Content.ReadAsMultipartAsync(provider); 

      //Get Logged in User Name 
      var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())); 
      var user = manager.FindById(User.Identity.GetUserId()); 

      //getting the user details and storing in the object 
      Document model = new Document(); 
      model.TypeId = Convert.ToInt32(provider.FormData["TypeId"]); 
      model.TypeName = provider.FormData["TypeName"]; 
      model.LocationId = Convert.ToInt32(provider.FormData["LocationId"]); 
      model.LocationName = provider.FormData["LocationName"]; 
      model.PipeId = Convert.ToInt32(provider.FormData["PipeId"]); 
      model.PipeName = provider.FormData["PipeName"]; 
      model.CompanyId = Convert.ToInt32(provider.FormData["CompanyId"]); 
      model.CompanyName = provider.FormData["CompanyName"]; 
      model.PlantId = Convert.ToInt32(provider.FormData["PlantId"]); 
      model.PlantName = provider.FormData["PlantName"]; 
      model.CounterPartyId = Convert.ToInt32(provider.FormData["CounterPartyId"]); 
      model.CounterPartyName = provider.FormData["CounterPartyName"]; 
      string docDate = provider.FormData["DocumentDate"]; 
      model.DocumentDate = DateTime.Parse(docDate.Trim('"')); 
      model.UploadedBy = user.Name; 
      model.UploadDate = DateTime.Now; 
      model.DocumentUrl = provider.FormData["DocumentUrl"]; 

      //if there is a file then save that file to the desired location 
      if (provider.FileData.Count > 0) 
      { 
       MultipartFileData fileData = provider.FileData[0]; 
       FileInfo fi = new FileInfo(fileData.LocalFileName); 

       //getting the file saving path 
       string clientFileName = fileData.Headers.ContentDisposition.FileName.Replace(@"""", ""); 
       if (clientFileName != "") 
       { 
        string clientExtension = clientFileName.Substring(clientFileName.LastIndexOf('.')); 
        string dash = ("-"); 
        var dt = model.DocumentDate.ToString("y").Replace('/', '-').Replace(':', '-'); 
        var CompanyName = model.CompanyName.Replace('_', ' '); 

        string vPath = root.Replace(@"C:\Development\TransparentEnergy\TransparentEnergy", "~").Replace("\\", "/"); 
        string path = String.Format(CompanyName + dash + model.TypeName + dash + model.CounterPartyName + dash + dt + clientExtension); 

        string combination = Path.Combine(vPath, path); 
        model.DocumentUrl = combination; 
        FileInfo fiOld = new FileInfo(path); 
        if (fiOld.Exists) 
         fiOld.Delete(); 
        //if (File.Exists()) 
        fi.MoveTo(vPath); 
       } 
       else 
       { 
        if (fi.Exists) 
         fi.Delete(); 
       } 

      } 
      //calling DB to save the user details 
      using (var context = new ApplicationDbContext()) 
      { 
       //save to db 
       context.Documents.Add(model); 
       context.SaveChanges(); 
      } 
     } 
     catch (Exception fex) 
     { 
      return Request.CreateErrorResponse(HttpStatusCode.NotFound, fex); 
     } 
     //sending the confirmation or error back to the user 
     return Request.CreateResponse(HttpStatusCode.OK); 
    } 

Это работает!

public async Task<HttpResponseMessage> Post() 
    { 

     try 
     { 
      //saving the posted file to the harddisk 
      //string root = HttpContext.Current.Server.MapPath("~/Files/"); 
      string root = HostingEnvironment.MapPath(ConfigurationManager.AppSettings["~/Files/"]); 
      var provider = new MultipartFormDataStreamProvider(root); 
      await Request.Content.ReadAsMultipartAsync(provider); 

      //Get Logged in User Name 
      var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())); 
      var user = manager.FindById(User.Identity.GetUserId()); 

      //getting the user details and storing in the object 
      Document model = new Document(); 
      model.TypeId = Convert.ToInt32(provider.FormData["TypeId"]); 
      model.TypeName = provider.FormData["TypeName"]; 
      model.LocationId = Convert.ToInt32(provider.FormData["LocationId"]); 
      model.LocationName = provider.FormData["LocationName"]; 
      model.PipeId = Convert.ToInt32(provider.FormData["PipeId"]); 
      model.PipeName = provider.FormData["PipeName"]; 
      model.CompanyId = Convert.ToInt32(provider.FormData["CompanyId"]); 
      model.CompanyName = provider.FormData["CompanyName"]; 
      model.PlantId = Convert.ToInt32(provider.FormData["PlantId"]); 
      model.PlantName = provider.FormData["PlantName"]; 
      model.CounterPartyId = Convert.ToInt32(provider.FormData["CounterPartyId"]); 
      model.CounterPartyName = provider.FormData["CounterPartyName"]; 
      string docDate = provider.FormData["DocumentDate"]; 
      model.DocumentDate = DateTime.Parse(docDate.Trim('"')); 
      model.UploadedBy = user.Name; 
      model.UploadDate = DateTime.Now; 
      model.DocumentUrl = provider.FormData["DocumentUrl"]; 

      //if there is a file then save that file to the desired location 
      if (provider.FileData.Count > 0) 
      { 
       MultipartFileData fileData = provider.FileData[0]; 
       FileInfo fi = new FileInfo(fileData.LocalFileName); 

       //getting the file saving path 
       string clientFileName = fileData.Headers.ContentDisposition.FileName.Replace(@"""", ""); 
       if (clientFileName != "") 
       { 
        string clientExtension = clientFileName.Substring(clientFileName.LastIndexOf('.')); 

        var dt = model.DocumentDate.ToString("y").Replace('/', '-').Replace(':', '-'); 
        var CompanyName = model.CompanyName.Replace('_', ' '); 

        string vPath = root.Replace(@"C:\Development\TransparentEnergy\TransparentEnergy", "~").Replace("\\", "/"); 
        string fileName = String.Format("{0}-{1}-{2}-{3}{4}", CompanyName, model.TypeName, model.CounterPartyName, dt, clientExtension); 
        string combination = Path.Combine(vPath, fileName); 
        model.DocumentUrl = combination; 

        string physicalPath = HttpContext.Current.Server.MapPath("/Files"); 
        string relativePath = Path.Combine(physicalPath, fileName); 
        FileInfo fiOld = new FileInfo(relativePath); 
        if (fiOld.Exists) 
         fiOld.Delete(); 
        //if (File.Exists()) 
        fi.MoveTo(relativePath); 
       } 
       else 
       { 
        if (fi.Exists) 
         fi.Delete(); 
       } 

      } 
      //calling DB to save the user details 
      using (var context = new ApplicationDbContext()) 
      { 
       //save to db 
       context.Documents.Add(model); 
       context.SaveChanges(); 
      } 
     } 
     catch (Exception fex) 
     { 
      return Request.CreateErrorResponse(HttpStatusCode.NotFound, fex); 
     } 
     //sending the confirmation or error back to the user 
     return Request.CreateResponse(HttpStatusCode.OK); 
    } 
+0

Не нужно делать 'if (! Directory.Exists (fi.DirectoryName))' потому что 'Directory.CreateDirectory' [" создает все каталоги и подкаталоги по указанному пути, если они уже не существуют. "] (Https: //msdn.microsoft.com/en-us/library/54a0at6s(v=vs.110).aspx). Кроме того, эти две строки действительно запутывают: 'model.DocumentUrl = поставщик.FormData [" DocumentUrl "];' затем следует 'model.DocumentUrl = model.DocumentUrl ==" "? null: model.DocumentUrl; '. – BCdotWEB

+0

ОК, избавился от обоих. model.DucmentUrl == ""? null должно быть не было – texas697

ответ

1

Я подозреваю, ваша проблема происходит потому, что в fi.MoveTo(serverFileName); (плохо названный) serverFileName фактически указывает на виртуальный путь вместо к физическому пути.

Обратите внимание, что я действительно советую переосмыслить ваш код. Некоторые примеры:

  • string space = ("-");: «-» не является пространством.
  • model.DocumentDate.ToString("y").Replace('/', '-').Replace(':', '-'); выглядит как плохой способ форматирования даты.
  • string serverFileName = vPath + CompanyName + space + model.TypeName + space + model.CounterPartyName + space + dt + clientExtension; Сначала используйте Path.Combine, чтобы присоединиться к папке и имени файла. Во-вторых, не лучше ли использовать string.Format для создания имени файла вместо длинной конкатенации? В-третьих, serverFileName - это ИМХО плохое имя, я бы назвал этот путь.
  • Я действительно не понимаю, что происходит с model.DocumentUrl: сначала получает значение provider.FormData["DocumentUrl"], то проверить, если model.DocumentUrl пустая строка (обратите внимание, что предпочтительно использовать string.Empty) и установите его в NULL, если это и затем назначьте его serverFileName.
+0

ОК, я последовал твоему совету. Является ли дата плохо отформатированной или она из-за выбранного формата? Я изменил переменные и использовал Path.Combine и string.Format. Я удалил вторую модель. DocumentumUrl. Тот же результат. Я обновил код. Я считаю, что у меня есть FileInfo fiOld = new FileInfo (путь); correct – texas697

+0

В обновленном коде 'FileInfo fiOld = new FileInfo (path);' теперь указывает на имя файла, а не на путь. Но даже если вы будете использовать комбинацию, это все равно будет ** виртуальным ** (например, «~/Files /»), а AFAIK FileInfo требует ** физического ** пути (например, «c: \ files \ «). То же для 'fi.MoveTo (vPath);'. Кроме того, ваш string.Format неверен, он должен быть 'string fileName = string.Format (" {0} - {1} - {2} - {3} {4} ", CompanyName, model.TypeName, model.CounterPartyName , dt, clientExtension); '. – BCdotWEB

+0

, поэтому я бы получил физический путь, как эта строка: физическийPath = HttpContext.Current.Server.MapPath ("/ Files"); а затем использовать это в FiloInfo (physicalPath) – texas697

Смежные вопросы