1

I have MVC controller action which takes some model as parameter. If the model is not valid it returns JSON otherwise it returns file.

public class MainModel
{
   public DownloadModel Downlaod {get;set;}
}

[ValidateAjaxRequest]
public ActionResult DownloadFile(DownloadVM model)
{
  // get file using model
  return File(byte[],"contenttype")
}

Note that ValidateAjaxRequest is ActionFilterAttribute which check if it is ajax request, and if it is then returns all errors using Json

public class ValidateAjaxRequestAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAjaxRequest())
            return;

        var modelState = filterContext.Controller.ViewData.ModelState;
        if (!modelState.IsValid)
        {
            var errors = new List<MyStatus>();
            //loop through all errors here and build errors list

            filterContext.Result = new JsonResult()
            {
                Data = errors
            };
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
        }
    }
}

Then in javascript i am using jQuery to post the data and handle errors.

    $.ajax({
        type: "POST",
        data: $('#formid').serialize(),
        url: '/Home/DownloadFile'
    })
    .done(function (response, textStatus, jqXHR)
    {
       // how do i show file here as popup?
    }
    .fail(function (jqXHR, textStatus, errorThrown) {
        //show returned errors from the server
    })

The reason im using ajax post instead of typical form post, is because i have some other controls on the same view which i dont want to post and also i dont want to refresh the whole view if ModelState is not valid. Something like below i DONT want to do

public ActionResult DownloadFile(MainModel model)
{
   if(ModelState.IsValid)
   { 
      // get file using model.Download
      return File(byte[],"contenttype")
   }

    return View("Index",model)

   // here i have to post entire MainModel and also re-render 
   // entire View if ModelState is not valid.
   // i do not like this approach so im using ajax to post only 
   // what i needed and without needing to re-render view
}
LP13
  • 30,567
  • 53
  • 217
  • 400
  • You cant return a file in an ajax method. You could however return a url to the file path to allow the user to download it - refer [these answers](http://stackoverflow.com/questions/16670209/download-excel-file-via-ajax-mvc) for examples –  Jun 03 '16 at 22:26
  • @StephenMuecke i saw article earlier but for that to work i have to store the file on the server first. and then i also need some *job* to delete that file. Instead I was trying to create file in memory and return it as blob. – LP13 Jun 05 '16 at 19:37

0 Answers0