2016-09-03 2 views
0

저자가 파일을 업로드 할 수있는 간단한 CMS를 만들려고합니다. (특히 이미지는 있지만 파일 형식은 현재 중요하지 않습니다.)보기에 파일 이름 전달하기

파일 업로드가 정상적으로 작동합니다. 그러나 나는 파일을 나열하고 나중에 삭제할 수있는 기능을 제공하려고합니다. (나중에는 여러 개의 파일이 필요하지만 지금은 한 번에 하나의 파일 만 있으면됩니다.)

나는 그물을 둘러 보았다. DB에 파일의 위치를 ​​저장하기 위해 EF를 사용하는 예제가 많이 있습니다. 예를 들어, 권한과 역할 등을 가지고 있기 때문에 앞으로는 필 요할 것입니다. 복잡성의 레이어가 아니라 바로 추가 할 의향이 있습니다. 지금.

내가 원하는 것은 단순히 삭제 링크를 누르는 것입니다 (마치 DB에서 레코드를 삭제하는 것처럼). 삭제 확인보기를 호출하는 작업을 트리거하려면. 그런 다음 해당보기에서 삭제 단추를 사용하여 실제로 파일을 삭제하고 사용자를 목록으로 되돌립니다. 다음은 내 코드는 지금까지 : 그것은 비교적 간단하고 나는 데 문제가 없습니다 (I의 나는이 뷰의 컨트롤러를 보여 실 거예요

@model IEnumerable<FileInfo> 

@{ 
    ViewBag.Title = "File List"; 
} 

<h2>Index</h2> 

<p> 
    @Html.ActionLink("Upload", "Upload") 
</p> 
<table class="table"> 
    <tr> 
     <th>File Name</th> 
     <th>Actions</th> 
    </tr> 

    @foreach (FileInfo file in Model) 
    { 
     <tr> 
      <td>@file.Name</td> 
      <td>@Html.ActionLink("Delete", "Delete", new { fileName = @file.Name })</td> 
     </tr> 
    } 
</table> 

:

이이 파일을 나열 뷰 것 생각한다). 너가 삭제 연결을 볼 수 있고 나에게 틀린 것이 있으면 저에게 말하기 위하여 나는 이것을 단지 보였다. 내가 연결되지 않는 경우 아래

@model FileInfo 

@{ 
    ViewBag.Title = "Delete"; 
} 

<h2>Delete</h2> 

<h3>Are you sure you want to delete this?</h3> 

<dl class="dl-horizontal"> 
    <dt> 
     @Html.DisplayNameFor(model => model.FullName) 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.FullName) 
    </dd> 
</dl> 
@using (Html.BeginForm("Delete", "FileManagement", FormMethod.Post, new { enctype = "multipart/form-data" })) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-actions no-color"> 
     @Html.ActionLink("Back to list of views", "Index", null, new { @class = "btn btn-success" }) 
     &nbsp;|&nbsp; 
     @*@Html.ActionLink("Delete", "Delete", null, new { @class = "btn btn-danger" })*@ 
     <input type="submit" value="Delete file" formaction="Delete" formmethod="delete" class="btn btn-danger" /> 
    </div> 
} 

는 (GET과 POST가/삭제)

// GET: FileManagement/Delete/filename 
    public ActionResult Delete() 
    { 
     return View(); 
    } 

    // POST: FileManagement/Delete/filename 
    [HttpDelete] 
    [ValidateAntiForgeryToken] 
    public ActionResult Delete(string fileName) 
    { 
     var path = Path.Combine(Server.MapPath("~/UserFiles"), fileName); 

     if (System.IO.File.Exists(path)) 
      System.IO.File.Delete(path); 
     else 
      return HttpNotFound(); 

     return RedirectToAction("Index"); 
    } 

내가보기 모델이없는이 삭제 작업입니다 : 아래

은 삭제 확인이다 데이터베이스 (아직). 파일은 ~/UserFiles/someFileName.ext 폴더에 업로드되고 전체 경로는 일반적인 방법으로 server.mappath에 추가됩니다.

문제는 삭제 확인보기에 파일 이름이 표시되고 삭제 작업에 파일을 전달하는 삭제 버튼에도 표시됩니다.

도움 주셔서 감사합니다.

+0

양식은 어떤 값을 게시하지 않습니다 - 당신은 입력하거나 값 때문에 fileName''에 대한 경로 값이없는 'string {file}'매개 변수는 항상'null'이됩니다. ('new {enctype = "multipart/form-data"}'는 필요 없습니다 - 서버에 파일을 업로드하기 위해서만 필요합니다) –

+0

GET 메소드는 'ActionLink()'에서'fileName'을받을 매개 변수가 있어야합니다. 그리고 나서 뷰에 모델을 전달하지 않으므로'null'이됩니다 (그리고 메인 뷰에서 확인 표시를 고려해야합니다) –

+0

어떤 이유로 든 삭제 확인 양식에 파일 이름이 표시되지 않습니다. 나는 내가 삭제보기 버튼을 클릭했을 때 초기보기 (목록)에서 그것을 얻고 있다고 가르쳤지 만 어떤 이유에서 삭제 확인 양식을 보지 않았다. 필드 이름과 값 위에 삭제보기의 양식을 이동하면 도움이 될까요? 아마도 파일 이름이있는 목록 양식에 숨겨진 컨트롤을 넣고 삭제 컨트롤러에서 어떤 방식으로 읽어야합니까? 또는 viewbag/data를 사용합니까? –

답변

1

기본보기 (나는 Index.cshtml라고 가정)에서 fileName에 대한 쿼리 문자열 값을 올바르게 생성하지만 GET 메서드에는이를 받아들이는 매개 변수가 없습니다. 그것은

// GET: FileManagement/Delete/filename 
public ActionResult Delete(string fileName) 

및 그 방법에 당신이 fileName 기반으로 새 FileInfo 클래스를 초기화하고보기에 그 모델을 통과해야 할 필요가있다.

다음 문제는 확인 페이지의 양식이 파일 이름을 POST 메서드로 다시 전달하지 않지만 동일한 signatute와 함께 GET 및 POST 메서드를 사용할 수 없다는 점에서 다른 문제가 제기된다는 것입니다. 당신은 크게 형태를 생성하여 성능을 향상시킬 수 있습니다, 그러나

@using (Html.BeginForm("Delete", "FileManagement", new { fileName = Model.Name })) // enctype not required 
{ 
    @Html.AntiForgeryToken() 
    <input type="submit" value="Delete file" class="btn btn-danger" /> 
} 

에 양식을 페이지를 삭제 예를

[HttpGet] 
public ActionResult ConfirmDelete(string fileName) 

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Delete(string fileName) 

과 확인에 방법 중 하나의 이름을 변경 변경해야 Index보기 및 디스플레이 어 확인 대화 상자를 잉 (GET 메서드는 더 이상 필요하지 않습니다)

@foreach (FileInfo file in Model) 
{ 
    .... 
    @using(Html.BeginForm("Delete", "FileManagement", new { fileName = file.Name })) 
    { 
     @Html.AntiForgeryToken() 
     <input type="submit" value="delete" /> 
    } 
} 

및 스크립트를 추가하면 브라우저 자바 스크립트 확인 대화 상자를 표시합니다 대화

$('form').submit(function() { 
    return conform("Are your sure .... "); 
}); 

표시합니다. (this article의 설명에 따라, 또는 자신을 구현하는) 당신은 더 확인 대화 상자에 대한 jQuery 플러그인을 사용하여 UI를 향상시킬 수

또한 (양식을 제출 아약스를 사용하는 것이 좋습니다

및 성공 콜백에서, 단추 및 관련 테이블 행 제거). 일반적인 구현은

@foreach (FileInfo file in Model) 
{ 
    <tr> 
     <td>@file.Name</td> 
     <td> 
      <form class="deleteform"> 
       @Html.AntiForgeryToken() 
       <input type="hidden" name="fileName" value="@file.Name" /> 
       <input type="submit" value="delete" /> 
      </form> 
     </td> 
    </tr> 
} 

var url = '@Url.Action("Delete", "FileManagement")'; 
$('.deleteform').submit(function() { 
    var formData = $(this).serialize(); 
    var row = $(this).closest('tr'); 
    $.post(url, formData, function(response) { 
     if (response) { 
      row.remove(); 
     } else { 
      // Oops - display message? 
     } 
    }).fail(function (response) { 
     // Oops 
    }); 
    return false; // cancel the default submit 
}); 

및 컨트롤러 방법처럼 보일 수 있습니다

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Delete(string fileName) 
{ 
    .... // delete the file 
    return Json(true); // indicate success 
    // or return Json(null); to indicate failure 
} 
+0

Stephen에게 도움을 청합니다. –

+0

나는 당신이 말한 것을 대부분했습니다. 그러나 때때로 IOException이 발생하고 catch 블록에서 ModelState.AddModelError를 설정하고 유효성 검사 요약 /validationmessage를 페이지에 추가하여 처리하려고합니다. 그러나 페이지가 새로 고침되면 메시지가 표시되지 않습니다.어떤 아이디어입니까, 아니면 다른 질문으로 더 잘 물어 보는가요? –

+0

당신이 사용하는 모든 코드를 볼 수 있도록 새로운 질문을해야 할 것입니다. (그러나 아약스를 사용하여 게시하는 경우 대답 편집에 따라 쉽게 할 수 있습니다) –