2

I have this model with required properties. Yes they are required for creating an item, but when I want to update a single column of them, I get this error about required fields. So it seems that my controller wants to update all of them.

In this case there's an item for sale and one can make an offer for it.

Part of my model:

public class Ad
{
    public int AdID { get; set; }

    [Required()]
    [Display(Name = "Otsikko")]
    public string Title { get; set; }

    [Required()]
    [DataType(DataType.MultilineText)]
    [AllowHtml]
    [Display(Name = "Kuvaus")]
    public string Text { get; set; }

    [Required()]
    [DataType(DataType.Currency)]
    [Display(Name = "Hinta")]
    public float Price { get; set; }

    [DataType(DataType.Currency)]
    [Display(Name = "Tarjottu")]
    public float Offer { get; set; }

My controller:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Offer([Bind(Include = "Offer")] Ad ad)
{
    if (ModelState.IsValid)
    {
       db.Entry(ad).State = EntityState.Modified;
       db.SaveChanges();
       return RedirectToRoute("ilmoitus", new { id = ad.AdID });
    }
    else
    {
       var message = string.Join(" | ", ModelState.Values
       .SelectMany(v => v.Errors)
       .Select(e => e.ErrorMessage));
       return new HttpStatusCodeResult(HttpStatusCode.BadRequest, message);
    }
}

Part of view:

@using (Html.BeginForm("Offer", "Ads"))
{
     @Html.AntiForgeryToken()
     @Html.HiddenFor(model => model.AdID)
     @Html.EditorFor(model => model.Offer, new { htmlAttributes = new { @class = "form-control offer-input", @placeholder = "Tarjoa..." } })
     <button class="btn-default btn offer-btn">Tarjoa {{offer}} €</button>
 }

I've tried this with same error How to Update only single field using EF

3
  • Could you please post the exact error? In your linked question I didn't find an error message too. Commented Jul 29, 2016 at 9:12
  • I think the issue is you haven't included all the properties for your Ad entity on your html form, so the post has lost the values. i.e. @Html.HiddenFor(model => model.Price) Commented Jul 29, 2016 at 9:13
  • Well the error is just "The x field is required". But hey, thanks, it works now. I added all the values as hidden and bound all the values in controller. It seems a bit silly and not very secure way, but what do I know, it works! Commented Jul 29, 2016 at 9:30

2 Answers 2

1

I got it working like this, included all the other properties as hidden and bound them in the controller:

View:

@using (Html.BeginForm("Offer", "Ads"))
{
       @Html.AntiForgeryToken()
       @Html.HiddenFor(model => model.AdID)
       @Html.HiddenFor(model => model.Title)
       @Html.HiddenFor(model => model.Text)
       @Html.HiddenFor(model => model.Price)
       @Html.HiddenFor(model => model.Location)
       @Html.HiddenFor(model => model.PaymentOptions)
       @Html.HiddenFor(model => model.DeliveryOptions)
       @Html.HiddenFor(model => model.SellerEmail)
       @Html.EditorFor(model => model.Offer, new { htmlAttributes = new { @class = "form-control offer-input", @placeholder = "Tarjoa..." } })
       <button class="btn-default btn offer-btn">Tarjoa {{offer}} €</button>
 }

Controller:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Offer([Bind(Include = "AdID,Title,Text,Price,Offer,Location,PaymentOptions,DeliveryOptions,SellerEmail")] Ad ad)
    {
        if (ModelState.IsValid)
        {
            db.Entry(ad).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToRoute("ilmoitus", new { id = ad.AdID });
        }
        else
        {
            var message = string.Join(" | ", ModelState.Values
            .SelectMany(v => v.Errors)
            .Select(e => e.ErrorMessage));
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest, message);
        }

    }

Is this a security issue though?

Sign up to request clarification or add additional context in comments.

Comments

0

I have two solution for the above query.

  • You can use two different models for updating and insertion example

  • Remove the properties from ModelState then TryUpdateModel

    public ActionResult UpdateAd(Ad ad)
    {
        ModelState.Remove("Title");
        ModelState.Remove("Text");
        ModelState.Remove("Price");
        var p = GetAd();   
        if (TryUpdateModel(p))
        {
             //Save Changes;
        }
     }
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.