Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot modify ModelState using SetModelValue

I'm working on a MVC/EF Web Application. In one of the forms I edit a model. The model has an image field (public byte[] BioPhoto)

When I upload an image to that field and save data, ModelState.IsValid is false, because BioPhoto property is null in ModelState. Note that the BioPhoto in model is loaded with image data.

I tried to inject the picture to ModelState using below code but still ModelState.IsValid is false

public ActionResult Edit([Bind(Include = "BusinessId,Name,About,Phone,TollFree,FAX,Email,Bio,BioPhoto")] Business business)
{
    if (System.IO.File.Exists("image.jpg"))
    {
        business.BioPhoto = System.IO.File.ReadAllBytes("image.jpg");
        ModelState.SetModelValue("BioPhoto", 
                   new ValueProviderResult(business.BioPhoto, "", System.Globalization.CultureInfo.InvariantCulture));
    }

    if (ModelState.IsValid)
    {
        db.Entry(business).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(business);
}

What am I doing wrong. Is there any better solution for this issue?

I read couple of answer in SO but could not figure out how to solve my case.

This is my model

public class Business
{
    public int BusinessId { get; set; }

    [Required]
    [StringLength(100)]
    public string Name { get; set; }

    [Required]
    public Address address { get; set; }

    [Required]
    [StringLength(20)]
    public string Phone { get; set; }

    [StringLength(20)]
    public string TollFree { get; set; }

    [StringLength(20)]
    public string FAX { get; set; }

    [Required]
    [StringLength(50)]
    public string Email { get; set; }

    [Required]
    [StringLength(100)]
    public string WebSite { get; set; }

    [Required]
    public string About { get; set; }

    [Required]
    public string Bio { get; set; }

    [Required]
    public byte[] BioPhoto { get; set; }
}

My View

<div class="form-group">
    @Html.LabelFor(model => model.BioPhoto, "BIO Photo (Best Size: 350 x 450)", htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        <form enctype="multipart/form-data">
            <div class="form-group" style="width:400px">
                <input id="BioPhoto" type="file" multiple class="file" data-overwrite-initial="false" />
            </div>
        </form>
        @Html.ValidationMessageFor(model => model.BioPhoto, "", new { @class = "text-danger" })
    </div>
</div>
like image 477
FLICKER Avatar asked Dec 25 '16 02:12

FLICKER


People also ask

Why is ModelState not valid MVC?

You get Model state not valid error when the server side validation of the model property has failed. So go to your action where you will find the following if condition that checks model state is valid: if (ModelState. IsValid)

What causes false IsValid ModelState?

That's because an error exists; ModelState. IsValid is false if any of the properties submitted have any error messages attached to them. What all of this means is that by setting up the validation in this manner, we allow MVC to just work the way it was designed.

How do I reset my ModelState?

To clear the memory of the model state you need to use ModelState. Clear(). You could also remove only the desired field by using method of ModelState. 1ModelState.

What exactly does ModelState IsValid do?

ModelState. IsValid indicates if it was possible to bind the incoming values from the request to the model correctly and whether any explicitly specified validation rules were broken during the model binding process.


1 Answers

Like I said the issue is the form is not posting the BioPhoto to the controller-most likely. You can use Chrome to see what is in the body of the http request.

If you want to add the image even if the controller is not receiving it, then try this.

Try removing only the error related to the image property:

ModelState["BioPhoto"].Errors.Clear();

Then add the image:

business.BioPhoto = System.IO.File.ReadAllBytes("image.jpg");

Then update the model:

UpdateModel(business);

Now if you call ModelState.IsValid, it will take the setting of BioPhoto into consideration and re-evaluate the IsValid.

EDIT:

I suggest to call

ModelState.SetModelValue("BioPhoto", new ValueProviderResult(business.BioPhoto, "", System.Globalization.CultureInfo.InvariantCulture));

to actually push the value to ModelState.Values. this is not neccessary though.

like image 77
CodingYoshi Avatar answered Oct 04 '22 13:10

CodingYoshi