시나리오는 다음과 같습니다.
ASP.NET MVC로 개발 된 웹 사이트가 있습니다. 웹 사이트에는 여러 파일 업로드 필드를 포함한 여러 입력 필드가 포함 된 양식이 있습니다.
내가하려는 것은 사용자가 파일을 선택하자마자 파일을 비동기 적 으로 업로드 하여 파일이 업로드 되는 동안 사용자가 다른 입력을 계속 채울 수 있도록하는 것입니다.
서버가 파일을 수신 및 확인한 후 사용자가 제출 버튼을 클릭하면 양식이 전송되고 업로드 된 파일과 함께 저장 됩니다 .
비동기 업로드를 처리 하는 별도의 컨트롤러 작업 이 필요하다고 가정 하지만 양식 제출 을 처리 하는 다른 작업 (동일한 컨트롤러 내) 에서 이러한 업로드 된 파일에 어떻게 액세스 할 수 있습니까?
양식이 제출 될 때까지 파일 을 임시로 저장 해야하는 경우 저장 하기에 바람직한 위치는 어디입니까?
양식을 선택할 때 이미 업로드 한 경우 양식을 제출할 때 파일을 업로드 할 필요가없는 것 같습니다 (그리고 enctype
양식 요소에서 속성 을 제거하고 싶을 것입니다 .
기본 단계는 사용자가 ajax (사용 FormData
) 로 파일을 선택했을 때 파일을 업로드하고 저장 한 다음 해당 파일의 경로를 반환하여 최종적으로 양식을 제출할 때 해당 정보도 게시 할 수 있도록하는 것입니다.
보기에 표시 / 편집하려는 항목을 나타내는보기 모델을 정의하여 시작하십시오.
public class FileAttachmentVM
{
public string Path { get; set; }
public string DisplayName { get; set; }
}
public class MyViewModel
{
.... // properties to display/edit in the view
public List<FileAttachmentVM> Files { get; set; }
}
그리고보기에서
@model MyViewModel
...
@using (Html.BeginForm())
{
....
<div id="file-inputs"></div> // placeholder for the file collection hidden inputs
}
<div id="file-names"></div> // place holder for the collection of file already uploaded
<input type="file" id="file" />
<button type="button" id="upload">Upload</button>
// template for adding new inputs for the file collection
<div id="template" style="display:none">
<div class="file-details">
<input type="hidden" class="file-path" name="Files[#].Path" value="" />
<input type="hidden" class="file-name" name="Files[#].DisplayName" value="" />
<input type="text" name="Files.Index" value="#" />
</div>
</div>
파일을 업로드하고 DOM을 업데이트하는 스크립트
var fileInputs = $('#file-inputs');
var fileNames = $('#file-names');
$('#Upload').click(function () {
var file = $('#file').get(0).files[0];
if (!file) {
return;
}
var formData = new FormData();
formData.append("file", file);
$.ajax({
url: '@Url.Action("Upload", "...")',// add controller name
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function (data) {
if (!data) {
// Oops, something went wrong
return;
}
$('#file').val(''); // clear file input
// Add the display name
fileNames.append($('<div></div>').text(data.DisplayName));
// Add the inputs
var index = (new Date()).getTime(); // unique indexer
var clone = $('#template').clone(); // clone the template
clone.html($(clone).html().replace(/#/g, index)); // update the indexer
fileInputs.append(clone.html()); // append the inputs
// update the input values
var lastFile = fileInputs.find('.file-details').last();
lastFile.find('.file-path').last().val(data.Path);
lastFile.find('.file-name').last().val(data.DisplayName);
}
});
});
마지막으로 컨트롤러 방법
[HttpPost]
public JsonResult Upload(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var displayName = Path.GetFileName(file.FileName);
var fileExtension = Path.GetExtension(displayName);
var fileName = string.Format("{0}{1}", Guid.NewGuid(), fileExtension);
var path = Path.Combine(Server.MapPath("~/App_Data/Files"), fileName);
file.SaveAs(path);
return Json(new { DisplayName = displayName, Path = path });
}
return Json(null);
}
그런 다음 양식을 제출하는 컨트롤러 메서드에서
public ActionResult Create(MyViewModel model)
{
// Initialize a data model, map the view model properties to it and save
// Loop through model.Files and save each file display name and path to the database (along with the ID of the entity you created/updated
코드에 대한 몇 가지 참고 사항.
.change()
이벤트가 아닌 파일 입력 이벤트 를 처리하도록 스크립트를 수정할 수 .click()
있습니다.Guid
고유한지 확인하기 위해 로 저장되며 다른 사용자가 동일한 이름의 파일을 업로드하는 경우 파일을 덮어 쓸 위험이 없습니다.이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다