Asp.net mvc NETMVC。如何创建接受多部分/表单数据的操作方法

Asp.net mvc NETMVC。如何创建接受多部分/表单数据的操作方法,asp.net-mvc,multipartform-data,Asp.net Mvc,Multipartform Data,我有一个控制器方法,需要接受客户端作为POST请求发送的多部分/表单数据。表单数据由两部分组成。一部分是序列化为application/json的对象,另一部分是作为application/octet-stream发送的照片文件。我的控制器上有一种方法,如下所示: [AcceptVerbs(HttpVerbs.Post)] void ActionResult Photos(PostItem post) { } {User Agent stuff} Content-Type: multipart

我有一个控制器方法,需要接受客户端作为POST请求发送的
多部分/表单数据。表单数据由两部分组成。一部分是序列化为
application/json
的对象,另一部分是作为
application/octet-stream
发送的照片文件。我的控制器上有一种方法,如下所示:

[AcceptVerbs(HttpVerbs.Post)]
void ActionResult Photos(PostItem post)
{
}
{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--
我可以通过
Request.file
获取文件,这里没有问题。但是positem为空。 不知道为什么?有什么想法吗

控制器代码:

/// <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();
    }

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; }
}
这最后一段代码可能是您希望得到的结果,但是逐步分解可能会帮助您


这个答案可能也会帮助您朝着正确的方向前进:

正如@Sergi所说,将HttpPostedFileBase文件参数添加到您的操作中,对于MVC3我不知道,但是对于1和2,您必须在表单/视图中指定您将发布多部分/表单数据,如下所示:

<% using (Html.BeginForm(MVC.Investigation.Step1(), FormMethod.Post, new { enctype = "multipart/form-data", id = "step1form" }))

希望有帮助

您能在视图中发布de代码吗?您正在使用ASP.NET MVC 1吗?已发布上述代码。我正在使用MVC3
[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);
    }