如何将名为 "file[]" 的发布数据绑定到 MVC 模型?
How to bind posted data named "file[]" to an MVC model?
我正在使用 Redactor as an HTML editor, which has a component for uploading images and files。
Redactor 负责客户端位,我需要提供服务器端上传功能。
如果我在控制器中使用 Request.Files
,我可以毫无问题地进行上传。
但我想将发布的文件绑定到一个模型,但我似乎无法做到这一点,因为它们发送的参数是 files[]
- 名称中带有方括号。
我的问题:
是否可以将发布的 "file[]"
绑定到 MVC 模型?这是一个无效的 属性 名称,单独使用 file
是行不通的。
这个文件输入看起来像这样。我可以指定 file
以外的名称,但 Redactor 会在末尾添加 []
,而不管名称是什么。
<input type="file" name="file" multiple="multiple" style="display: none;">
我正在尝试像这样绑定到 属性:
public HttpPostedFileBase[] File { get; set; }
当我观看上传时,我在请求中看到了这一点(我推测编辑者可能在幕后添加了方括号):
Content-Disposition: form-data; name="file[]"; filename="my-image.jpg"
也相关:
Redactor always sends the uploading request with content-type as multipart/form-data. So you don't need to add this enctype anywhere
您应该创建一个自定义模型活页夹以将上传的文件绑定到一个 属性。
首先创建一个模型 HttpPostedFileBase[]
属性
public class RactorModel
{
public HttpPostedFileBase[] Files { get; set; }
}
然后实施 DefaultModelBinder
并覆盖 BindProperty
public class RactorModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
int len = controllerContext.HttpContext.Request.Files.AllKeys.Length;
if (len > 0)
{
if (propertyDescriptor.PropertyType == typeof(HttpPostedFileBase[]))
{
string formName = string.Format("{0}[]", propertyDescriptor.Name);
HttpPostedFileBase[] files = new HttpPostedFileBase[len];
for (int i = 0; i < len; i++)
{
files[i] = controllerContext.HttpContext.Request.Files[i];
}
propertyDescriptor.SetValue(bindingContext.Model, files);
return;
}
}
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
您还应该将活页夹提供程序添加到您的项目中,然后在 global.asax
中注册它
public class RactorModenBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
if (modelType == typeof(RactorModel))
{
return new RactorModelBinder();
}
return null;
}
}
...
ModelBinderProviders.BinderProviders.Insert(0, new RactorModenBinderProvider());
这不是一个通用的解决方案,但我想您明白了。
我在 ASP.NET MVC 项目中集成 jQuery.filer 时遇到了类似的问题。由于 jQuery.filer 将“[]”添加到输入的名称属性的末尾(即从文件到文件[]),我不得不手动更改名称属性的值,如下所示:
$('#FileUpload').attr('name', 'FileUpload');
这是我在 AJAX 的一些项目中使用的方法,并且没有任何问题。您可以尝试一下,如果有效请告诉我:
ViewModel:
[Display(Name = "Attachments")]
[DataType(DataType.Upload)]
public IEnumerable<HttpPostedFileBase> FileUpload { get; set; }
查看:
@model ViewModel
@using (Html.BeginForm("Insert", "Controller", FormMethod.Post,
new { id = "frmCreate", enctype = "multipart/form-data" }))
{
@Html.TextBoxFor(m => m.FileUpload, new { type = "file", multiple = "multiple" })
<button id="btnSubmit" onclick="insert(event)" type="button">Save</button>
}
<script>
function insert(event) {
event.preventDefault();
//As jQuery.filer adds "[]" to the end of name attribute of input (i.e. from files to files[])
//we have to change the value of name attribute manually
$('#FileUpload').attr('name', 'FileUpload');
var formdata = new FormData($('#frmCreate').get(0));
$.ajax({
type: "POST",
url: '@Url.Action("Insert", "Cotroller")',
cache: false,
dataType: "json",
data: formdata,
/* If you are uploading files, then processData and contentType must be set
to falsein order for FormData to work (otherwise comment out both of them) */
processData: false,
contentType: false,
success: function (response, textStatus, XMLHttpRequest) {
//...
}
});
};
$(document).ready(function () {
$('#FileUpload').filer({
//code omitted for brevity
});
});
</script>
控制器:
public JsonResult Insert([Bind(Exclude = null)] ViewModel model)
{
if (ModelState.IsValid)
{
List<FileAttachment> fa = new List<FileAttachment>();
if (model.FileUpload != null)
{
FileAttachment fileAttachment = new FileAttachment //entity model
{
Created = DateTime.Now,
FileMimeType = upload.ContentType,
FileData = new byte[upload.ContentLength],
FileName = upload.FileName,
AuthorId = 1
};
upload.InputStream.Read(fileAttachment.FileData, 0, upload.ContentLength);
fa.Add(fileAttachment);
}
//code omitted for brevity
repository.SaveExperimentWithAttachment(model, fa);
return Json(new { success = true, message = "Record has been created." });
}
// If we got this far, something failed, redisplay form
return Json(new { success = false, message = "Please check the form and try again." });
}
希望这对您有所帮助...
我正在使用 Redactor as an HTML editor, which has a component for uploading images and files。
Redactor 负责客户端位,我需要提供服务器端上传功能。
如果我在控制器中使用 Request.Files
,我可以毫无问题地进行上传。
但我想将发布的文件绑定到一个模型,但我似乎无法做到这一点,因为它们发送的参数是 files[]
- 名称中带有方括号。
我的问题:
是否可以将发布的 "file[]"
绑定到 MVC 模型?这是一个无效的 属性 名称,单独使用 file
是行不通的。
这个文件输入看起来像这样。我可以指定 file
以外的名称,但 Redactor 会在末尾添加 []
,而不管名称是什么。
<input type="file" name="file" multiple="multiple" style="display: none;">
我正在尝试像这样绑定到 属性:
public HttpPostedFileBase[] File { get; set; }
当我观看上传时,我在请求中看到了这一点(我推测编辑者可能在幕后添加了方括号):
Content-Disposition: form-data; name="file[]"; filename="my-image.jpg"
也相关:
Redactor always sends the uploading request with content-type as multipart/form-data. So you don't need to add this enctype anywhere
您应该创建一个自定义模型活页夹以将上传的文件绑定到一个 属性。
首先创建一个模型 HttpPostedFileBase[]
属性
public class RactorModel
{
public HttpPostedFileBase[] Files { get; set; }
}
然后实施 DefaultModelBinder
并覆盖 BindProperty
public class RactorModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
int len = controllerContext.HttpContext.Request.Files.AllKeys.Length;
if (len > 0)
{
if (propertyDescriptor.PropertyType == typeof(HttpPostedFileBase[]))
{
string formName = string.Format("{0}[]", propertyDescriptor.Name);
HttpPostedFileBase[] files = new HttpPostedFileBase[len];
for (int i = 0; i < len; i++)
{
files[i] = controllerContext.HttpContext.Request.Files[i];
}
propertyDescriptor.SetValue(bindingContext.Model, files);
return;
}
}
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
您还应该将活页夹提供程序添加到您的项目中,然后在 global.asax
中注册它public class RactorModenBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
if (modelType == typeof(RactorModel))
{
return new RactorModelBinder();
}
return null;
}
}
...
ModelBinderProviders.BinderProviders.Insert(0, new RactorModenBinderProvider());
这不是一个通用的解决方案,但我想您明白了。
我在 ASP.NET MVC 项目中集成 jQuery.filer 时遇到了类似的问题。由于 jQuery.filer 将“[]”添加到输入的名称属性的末尾(即从文件到文件[]),我不得不手动更改名称属性的值,如下所示:
$('#FileUpload').attr('name', 'FileUpload');
这是我在 AJAX 的一些项目中使用的方法,并且没有任何问题。您可以尝试一下,如果有效请告诉我:
ViewModel:
[Display(Name = "Attachments")]
[DataType(DataType.Upload)]
public IEnumerable<HttpPostedFileBase> FileUpload { get; set; }
查看:
@model ViewModel
@using (Html.BeginForm("Insert", "Controller", FormMethod.Post,
new { id = "frmCreate", enctype = "multipart/form-data" }))
{
@Html.TextBoxFor(m => m.FileUpload, new { type = "file", multiple = "multiple" })
<button id="btnSubmit" onclick="insert(event)" type="button">Save</button>
}
<script>
function insert(event) {
event.preventDefault();
//As jQuery.filer adds "[]" to the end of name attribute of input (i.e. from files to files[])
//we have to change the value of name attribute manually
$('#FileUpload').attr('name', 'FileUpload');
var formdata = new FormData($('#frmCreate').get(0));
$.ajax({
type: "POST",
url: '@Url.Action("Insert", "Cotroller")',
cache: false,
dataType: "json",
data: formdata,
/* If you are uploading files, then processData and contentType must be set
to falsein order for FormData to work (otherwise comment out both of them) */
processData: false,
contentType: false,
success: function (response, textStatus, XMLHttpRequest) {
//...
}
});
};
$(document).ready(function () {
$('#FileUpload').filer({
//code omitted for brevity
});
});
</script>
控制器:
public JsonResult Insert([Bind(Exclude = null)] ViewModel model)
{
if (ModelState.IsValid)
{
List<FileAttachment> fa = new List<FileAttachment>();
if (model.FileUpload != null)
{
FileAttachment fileAttachment = new FileAttachment //entity model
{
Created = DateTime.Now,
FileMimeType = upload.ContentType,
FileData = new byte[upload.ContentLength],
FileName = upload.FileName,
AuthorId = 1
};
upload.InputStream.Read(fileAttachment.FileData, 0, upload.ContentLength);
fa.Add(fileAttachment);
}
//code omitted for brevity
repository.SaveExperimentWithAttachment(model, fa);
return Json(new { success = true, message = "Record has been created." });
}
// If we got this far, something failed, redisplay form
return Json(new { success = false, message = "Please check the form and try again." });
}
希望这对您有所帮助...