Содержимое ViewModel имеет значение Null после отправки формы в контроллер

Таким образом, ViewModel имеет 2 набора данных. CurrentDetails и UpdatedDetails. Оба являются экземплярами одного и того же класса, который содержит строки и еще много чего внутри и т.д.

Этот метод работал со всеми другими представлениями и моделями, с которыми я пытался работать, но для ЭТОГО одного экземпляра, когда форма отправляется в контроллер, ее содержимое (CurrentDetails и UpdatedDetails) оказывается нулевым.

Я пытался изменить имя параметра с модели на тест и другие произвольные вещи, но безрезультатно.

Единственное, что сработало (но не является решением для меня), это НЕ наличие экземпляров класса внутри 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>
}

ViewModel:

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;
}

person Andrew Salib    schedule 25.02.2016    source источник


Ответы (1)


И CurrentDetails, и UpdatedDetails в вашей модели MerchantFloristProfileViewModel являются полями, а не свойствами (без геттера/установщика), поэтому DefaultModelBinder не может устанавливать значения. Измените их на

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

Но вы не должны отправлять все эти дополнительные данные в представление, а затем отправлять их обратно без изменений. Помимо дополнительных накладных расходов, любой злоумышленник может изменить значения в скрытых полях, что приведет к сбою вашего приложения. Просто получите оригинал из репозитория еще раз, если он вам нужен в методе POST

person Community    schedule 25.02.2016
comment
Большое спасибо за помощь, очень глупо с моей стороны! Я также возьму свежие данные из репо/базы данных, так они будут более безопасными и с меньшими накладными расходами, как вы сказали! - person Andrew Salib; 25.02.2016