aspnet web api how to validate using modelstate in multipart form data?

1.5k views Asked by At

I am new for using asp net web api. I want to create UploadDocument feature in my web api. so, I create this way.

From Client

api.post('vendor/UploadDocument', formData, { headers: { 'Content-Type': 'multipart/form-data' } })

Controller

public class VendorController : ApiController {
    [HttpPost]
    public HttpResponseMessage UploadDocument()
    {
        try
        {
           if (!Request.Content.IsMimeMultipartContent())
           throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

           var request = HttpContext.Current.Request;
           var model = new UploadDocumentViewModel();
           model.field1 = request.Form["field1"];
           model.field2 = request.Form["field2"];
           model.Document = request.Files["Document"];

           if (ModelState.IsValid)
           {
                return Request.CreateResponse(HttpStatusCode.OK);
           }
           else //ModelState is not valid
           {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
           }
        }
        catch (Exception exception)
        {
           return Request.CreateResponse(HttpStatusCode.InternalServerError);
        }
    }
}

Model

public class UploadDocumentViewModel
{
    [Required]
    public string field1 { get; set; }

    [Required]
    public int field2 { get; set; }

    [Required]
    public HttpPostedFile Document { get; set; }
}

My problem is, in controller ModelState always empty. I have tried to add code

Validate(model);
if (ModelState.IsValid)...

but it didn't work too. can someone have any idea for validating model data annotation in multipart form data ?

2

There are 2 answers

1
Hüseyin Burak Karadag On BEST ANSWER

try clear model state before validate

ModelState.Clear(); 
this.Validate(model); 
if (ModelState.IsValid) {

}

Check this answer : Custom DataAnnotation

4
Merchezatter On

Your method should look like this:

public class VendorController : ApiController {

      [HttpPost]
        public IHttpActionResult UploadDocument(UploadDocumentViewModel viewModel)
        {
            try
            {
               if (!Request.Content.IsMimeMultipartContent())
return StatusCode(HttpStatusCode.UnsupportedMediaType);

               if (viewNodel == null)
                   return BadRequest("Model is empty");

               var field1 = viewModel.field1;
               var field2 = viewModel.field2;
               var documents = viewModel.document;

               if (ModelState.IsValid)
               {
                    return Ok();
               }
               else
               {
                    return BadRequest(ModelState);
               }
            }
            catch (Exception exception)
            {
               return InternalServerError(exception);
            }
        }
    }

I prefer to passing some of those validations in action filters, to make your methods cleaner (try/catch, modelstate).

If you will have some problems with model binding, you can implement your custom model binder.