2

I'm using Web API in my project but I have a problem when I try add a picture to employee, all data register OK, only picture get an error. In other projects work fine, but using Web API I can't add this.

Error:

JsonSerializationException: Error getting value from 'ReadTimeout' on 'System.Web.HttpInputStream'.

My model:

public class EmployeeViewModel
{

    public int Id { get; set; }

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

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

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

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

    public int OcupationId { get; set; }

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

    public virtual Occupation Occupation { get; set; }

    public HttpPostedFileBase Pic { get; set; }
}

My controller:

        [HttpPost]
    public ActionResult AddOrEdit(EmployeeViewModel employee)
    {

        if (employee.Id == 0)
        {

            if (employee.Pic != null)
            {
                var pic = Ultilidades.UploadPhoto(employee.Pic);
                if (!string.IsNullOrEmpty(pic))
                {
                    employee.Picture = string.Format("~/Content/Pictures/{0}", pic);
                }
            }
            HttpResponseMessage response = GlobalVariables.WebApiClient.PostAsJsonAsync("Employee",employee).Result;
            TempData["SuccessMessage"] = "sucess!";
        }
    }

enter image description here

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
Cesar Augusto
  • 151
  • 1
  • 9

1 Answers1

2

This error occurred because PostAsJsonAsync method tries to serialize HttpInputStream object as string instead of byte array (note that JSON serializer works better with arrays rather than stream). You can create another model class specially designed for Web API which contains duplicated int & string properties from MVC viewmodel with additional byte array property to store HttpPostedFileBase object like this:

public class EmployeeWebApiModel
{
    public int Id { get; set; }

    // other properties

    public string Picture { get; set; }

    // byte array to hold HttpPostedFileBase content in Web API context
    public byte[] PicData { get; set; } 
}

Using Web API model class defined above, then read HttpPostedFileBase object and store it inside byte array property using BinaryReader, assuming you're already declared the model with new keyword:

var apiModel = new EmployeeWebApiModel();

// other logic here

var br = new BinaryReader(employee.Pic.InputStream);
apiModel.PicData = br.ReadBytes(employee.Pic.ContentLength);

Then, you can serialize Web API model class with PostAsJsonAsync:

HttpResponseMessage response = GlobalVariables.WebApiClient.PostAsJsonAsync("Employee", apiModel).Result;

A similar issue can be found here (with IEnumerable<HttpPostedFileBase> instead of single HttpPostedFileBase).

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61