4

I am trying to post some custom data with image to web api. Please take a look at the method below.

public void Post(FlyerDetails FlyerDetails)
    {
        var httpRequest = HttpContext.Current.Request;
        if (httpRequest.Files.Count > 0)
        {
            foreach (string file in httpRequest.Files)
            {
                var filePath = HttpContext.Current.Server.MapPath("~/Flyers/" + httpRequest.Files[file].FileName);
                Bitmap bmp = new Bitmap(httpRequest.Files[file].InputStream);
                Graphics g = Graphics.FromImage(bmp);
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g.DrawString(FlyerDetails.Message, new Font(FlyerDetails.FontColor, FlyerDetails.FontSize), Brushes.DarkRed, new PointF(0, 0));
                g.Flush();
                bmp.Save(filePath);
            }
        }
    }

Now the problem is when i keep this method with parameter and post the data from fiddler it shows me 415 Unsupported Media Type error . If i remove the parameter then it is working fine. But i really need to pass the data along with the posted image.

Can any one suggest a good way to accomplish this ?

Thanks

Sachin Trivedi
  • 2,033
  • 4
  • 28
  • 57
  • check this answer here http://stackoverflow.com/questions/20909118/the-remote-server-returned-an-error-415-unsupported-media-type - essentially many of the same issues. – Darren Wainwright Jun 13 '14 at 13:15
  • @Darren thanks. I will try to implement it this way. I am just curious about this behavior. – Sachin Trivedi Jun 13 '14 at 13:22
  • No worries. ultimately, when using the web api controllers, you deal with file upload very differently than you would in a web forms webmethod (or similar) - this will be the root of most of your issues. - this answer gives you a good idea on how to accept files. You should be able to adjust the input parameters to suit your needs. http://stackoverflow.com/questions/10320232/how-to-accept-a-file-post-asp-net-mvc-4-webapi – Darren Wainwright Jun 13 '14 at 13:27
  • Also - as a slight side-note. Make sure you're setting your content type to multipart/form-data – Darren Wainwright Jun 13 '14 at 13:28
  • @Darren Thanks. I changed the implementation but if i keep the parameter it behaves the same way. – Sachin Trivedi Jun 13 '14 at 13:32
  • @Darren Thanks for your suggestions. I have posted the solution as answer. – Sachin Trivedi Jun 26 '14 at 12:23

2 Answers2

3

After searching a lot i figured out the way to upload the data along with the image. Here is the revised version of the code. Hope that it will helpful to someone.

public async Task<HttpResponseMessage> Post()
    {

        var streamProvider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/Flyers/"));
        await Request.Content.ReadAsMultipartAsync(streamProvider);

        var response = Request.CreateResponse(HttpStatusCode.Created);
        var filePath = "";// file path
        if (System.IO.File.Exists(filePath))
        {
            string extension = Path.GetExtension(filePath);
            Bitmap bmp = new Bitmap(filePath);
            Graphics g = Graphics.FromImage(bmp);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            Color brushColor = System.Drawing.ColorTranslator.FromHtml(streamProvider.FormData["FontColorCode"]);
            g.DrawString(streamProvider.FormData["FontFamily"], new Font(brushColor.Name, Convert.ToInt32(streamProvider.FormData["FontSize"])), new SolidBrush(brushColor), new PointF(0, 0));
            g.Flush();
            bmp.Save(HttpContext.Current.Server.MapPath("~/" + Guid.NewGuid() + extension));
            response.Headers.Location = new Uri(new Uri(HttpContext.Current.Request.Url.AbsoluteUri).GetLeftPart(UriPartial.Authority) + "/Flyers/" + Guid.NewGuid() + extension);
        }
        return response;
    }

NOTE : One should post the data as mutipart-formdata.

Sachin Trivedi
  • 2,033
  • 4
  • 28
  • 57
  • How did you read in your custom FlyerDetails type (data) with this solution? It looks like it's only reading in the uploaded images now? – Aaron May 06 '15 at 11:02
  • @Aaron If you take a closer look at the code , now you will be able to fetch data using streamProvider just like the form collection. streamProvider.FormData["FontFamily"] – Sachin Trivedi May 07 '15 at 05:05
  • Ok cool, thanks. Do you know if this works with model binding? I.e. can I post a custom type in this way and have .NET model bind the custom type back into a .NET object out of the streamProvider while also grabbing the binary image data? – Aaron May 07 '15 at 10:55
  • @Aaron I think that should be possible. i.e If you post custom object then you should be able to get that. In my case i am fetching the values of the controls using streamProvider. – Sachin Trivedi May 09 '15 at 09:09
0

this line also gets a post parameter along with uploaded file:

string value = HttpContext.Current.Request.Params.Get("key");
Hossein Amini
  • 716
  • 9
  • 21