我有一个Controller方法需要接受客户端发送的multipart/form-data
作为POST请求。表单数据有2个部分。一个是序列化为application/json
的对象,另一个是以application/octet-stream
发送的照片文件。我的控制器上有一个方法,如下所示:
[AcceptVerbs(HttpVerbs.Post)]
void ActionResult Photos(PostItem post)
{
}
我可以通过Request.File
获取文件而没有问题。但是PostItem为null。
不知道为什么?任何想法
控制器代码:
/// <summary>
/// FeedsController
/// </summary>
public class FeedsController : FeedsBaseController
{
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Photos(FeedItem feedItem)
{
//Here the feedItem is always null. However Request.Files[0] gives me the file I need
var processor = new ActivityFeedsProcessor();
processor.ProcessFeed(feedItem, Request.Files[0]);
SetResponseCode(System.Net.HttpStatusCode.OK);
return new EmptyResult();
}
}
线路上的客户端请求如下所示:
{User Agent stuff}
Content-Type: multipart/form-data; boundary=8cdb3c15d07d36a
--8cdb3c15d07d36a
Content-Disposition: form-data; name="feedItem"
Content-Type: text/xml
{"UserId":1234567,"GroupId":123456,"PostType":"photos",
"PublishTo":"store","CreatedTime":"2011-03-19 03:22:39Z"}
--8cdb3c15d07d36a
Content-Disposition: file; filename="testFile.txt"
ContentType: application/octet-stream
{bytes here. Removed for brevity}
--8cdb3c15d07d36a--
答案 0 :(得分:6)
FeedItem
班级是什么样的?对于我在帖子信息中看到的内容,它应该类似于:
public class FeedItem
{
public int UserId { get; set; }
public int GroupId { get; set; }
public string PublishTo { get; set; }
public string PostType { get; set; }
public DateTime CreatedTime { get; set; }
}
否则不受约束。您可以尝试更改操作签名,看看是否有效:
[HttpPost] //AcceptVerbs(HttpVerbs.Post) is a thing of "the olden days"
public ActionResult Photos(int UserId, int GroupId, string PublishTo
string PostType, DateTime CreatedTime)
{
// do some work here
}
您甚至可以尝试在动作中添加HttpPostedFileBase
参数:
[HttpPost]
public ActionResult Photos(int UserId, int GroupId, string PublishTo
string PostType, DateTime CreatedTime, HttpPostedFileBase file)
{
// the last param eliminates the need for Request.Files[0]
var processor = new ActivityFeedsProcessor();
processor.ProcessFeed(feedItem, file);
}
如果你真的感到疯狂和顽皮,请将HttpPostedFileBase
添加到FeedItem
:
public class FeedItem
{
public int UserId { get; set; }
public int GroupId { get; set; }
public string PublishTo { get; set; }
public string PostType { get; set; }
public DateTime CreatedTime { get; set; }
public HttpPostedFileBase File { get; set; }
}
这最后一段代码片段可能就是您想要的结果,但逐步细分可能对您有所帮助。
这个答案也可以帮助你顺利指出:ASP.NET MVC passing Model *together* with files back to controller
答案 1 :(得分:1)
正如@Sergi所说,将HttpPostedFileBase文件参数添加到您的操作中我不知道MVC3但是对于1和2您必须在表单/视图中指定您将发布multipart / form-data,如下所示:< / p>
<% using (Html.BeginForm(MVC.Investigation.Step1(), FormMethod.Post, new { enctype = "multipart/form-data", id = "step1form" }))
这是在我的控制器中:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Admin, Member, Delegate")]
public virtual ActionResult Step1(InvestigationStep1Model model, HttpPostedFileBase renterAuthorisationFile)
{
if (_requesterUser == null) return RedirectToAction(MVC.Session.Logout());
if (renterAuthorisationFile != null)
{
var maxLength = int.Parse(_configHelper.GetValue("maxRenterAuthorisationFileSize"));
if (renterAuthorisationFile.ContentLength == 0)
{
ModelState.AddModelError("RenterAuthorisationFile", Resources.AttachAuthorizationInvalid);
}
else if (renterAuthorisationFile.ContentLength > maxLength * 1024 * 1204)
{
ModelState.AddModelError("RenterAuthorisationFile", string.Format(Resources.AttachAuthorizationTooBig, maxLength));
}
}
if(ModelState.IsValid)
{
if (renterAuthorisationFile != null && renterAuthorisationFile.ContentLength > 0)
{
var folder = _configHelper.GetValue("AuthorizationPath");
var path = Server.MapPath("~/" + folder);
model.RenterAuthorisationFile = renterAuthorisationFile.FileName;
renterAuthorisationFile.SaveAs(Path.Combine(path, renterAuthorisationFile.FileName));
}
...
return RedirectToAction(MVC.Investigation.Step2());
}
return View(model);
}
希望它有所帮助!