将表单发布到控制器后,ViewModel内容为空

时间:2016-02-25 02:22:30

标签: asp.net-mvc asp.net-mvc-5 nullreferenceexception asp.net-mvc-viewmodel

因此ViewModel有2组数据。 CurrentDetails和UpdatedDetails。两者都是同一类的实例,它们携带字符串等等。

此方法适用于我尝试过的所有其他视图和模型,但对于这个实例,当表单发布到控制器时,其内容(CurrentDetails和UpdatedDetails)都被发现为null。

我已经尝试将参数名称从模型更改为测试以及其他任意内容,但无济于事。

有一件事(但不是我的解决方案)是没有ViewModel中的类的实例,只是在那里有数据(但我不明白为什么我应该被迫做这个事情方式。

这是控制器:

[HttpPost]
public ActionResult FloristProfile(MerchantFloristProfileViewModel test)
{
    if (!ModelState.IsValid)
        return View(test);

    using (var db = new ApplicationDbContext())
    {
        Florist florist = db.Florists.Find(MerchantBase.FloristID);
        if (Request.Form["editSubmit"] != null)
        {
            florist.Name = test.UpdatedDetails.Name;
            florist.Website = test.UpdatedDetails.Website;
            db.SaveChanges();
            return RedirectToAction("FloristProfile");
        }
        else if (Request.Form["photoSubmit"] != null)
        {
            if (test.CurrentDetails.File.ContentLength > 0)
            {
                CloudBlobContainer container = FlowerStorage.GetCloudBlobContainer();
                string blobName = String.Format("florist_{0}.jpg", Guid.NewGuid().ToString());
                CloudBlockBlob photoBlob = container.GetBlockBlobReference(blobName);
                    photoBlob.UploadFromStream(test.CurrentDetails.File.InputStream);
                florist.LogoPath = blobName;
                florist.isRendering = true;
                db.SaveChanges();
                return RedirectToAction("FloristProfile");
            }
        }
    }
    return Content("Invalid Request");
}

查看:

@using (Html.BeginForm("FloristProfile", "Merchant", FormMethod.Post, new { @class = "form-horizontal" }))
{
    @Html.ValidationSummary(false, "", new { @class = "text-danger" })
    @Html.HiddenFor(x => x.CurrentDetails.FloristID)
    @Html.HiddenFor(x => x.CurrentDetails.Name)
    @Html.HiddenFor(x => x.CurrentDetails.StaffCount)
    @Html.HiddenFor(x => x.CurrentDetails.StoreCount)
    @Html.HiddenFor(x => x.CurrentDetails.Website)
    <div class="form-group">
        @Html.LabelFor(x => x.UpdatedDetails.Name, new { @class = "col-sm-2 control-label" })
        <div class="col-sm-10">
            @Html.TextBoxFor(x => x.UpdatedDetails.Name, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(x => x.UpdatedDetails.Website, new { @class = "col-sm-2 control-label" })
        <div class="col-sm-10">
            @Html.TextBoxFor(x => x.UpdatedDetails.Website, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" name="editSubmit" class="btn btn-success">Save</button>
        </div>
    </div>
}

视图模型:

public class MerchantFloristProfileViewModel
{
    public class FloristProfileDetails
    {
        public int FloristID { get; set; }
        [Required(ErrorMessage = "Please Enter a Name")]
        public string Name { get; set; }
        [DataType(DataType.Url)]
        [Required(ErrorMessage = "Please Enter a Website")]
        public string Website { get; set; }
        public int StoreCount { get; set; }
        public int StaffCount { get; set; }
        // For Picture Upload
        public HttpPostedFileBase File { get; set; }
    }
    public FloristProfileDetails CurrentDetails;
    public FloristProfileDetails UpdatedDetails;
}

1 个答案:

答案 0 :(得分:3)

CurrentDetails模型中的UpdatedDetailsMerchantFloristProfileViewModel都是字段,而不是属性(没有getter / setter),因此DefaultModelBinder不能设置价值。将它们更改为

public FloristProfileDetails CurrentDetails { get; set; }
public FloristProfileDetails UpdatedDetails { get; set; }

但是您不应该将所有额外数据发送到视图,然后将所有数据再次发送回来。除了额外的开销之外,任何恶意用户都可能会更改隐藏字段中的值,从而导致应用失败。如果您需要在POST方法中再次从存储库中获取原始文件