Search code examples
c#.netimagewcfstream

How to upload image of various type (jpg/png/gif) to the server through Stream using WCF web API


For some reason, Im using WCF for webAPIs..I have been using WCF for few days now. On the hunt to find the code to upload image to the server I found many answers and solutions like:

Could not upload Image to WCF Rest service

Uploading image as attachment in RESTful WCF Service

Uploading an image using WCF RESTFul service full working example

the above (full woking) example is working for me..accept for the part that it accepts only jpeg images. Since im using Postman to hit on the request, Stream datatype is accepting it and run to the program. Is there anyway to get a file type or file name from input stream data?

Following is the code

interface:
 Method = "POST",
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json)]
string PostImage(Stream stream);

method implementation:
public string PostImage(Stream stream)
    {
        byte[] buffer = new byte[10000];
        stream.Read(buffer, 0, 10000);
        FileStream f = new FileStream("C:\\temp\\sample.jpg", FileMode.OpenOrCreate);
        f.Write(buffer, 0, buffer.Length);
        f.Close();

        return "Recieved the image on server";
    }

PS: im using postman request to send image like the following simple browse file option under byte section like this:

enter image description here

PS: Along with the image, I cannot pass the file name if even i want to, since Stream parameter does not allow any other parameter with it.


Solution

  • As joehoper mentioned, presently we could pass the additional information to the server by using Http header, please refer to my code design.
    Server-side.
    Service interface.

    [OperationContract]
            [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json,BodyStyle =WebMessageBodyStyle.Bare)]
            Task UploadStream(Stream stream);
    

    Service implementation.

    public async Task UploadStream(Stream stream)
    {
        var context = WebOperationContext.Current;
        string filename = context.IncomingRequest.Headers["filename"].ToString();
        string ext = Path.GetExtension(filename);
        using (stream)
        {
            //save the image under the Uploads folder on the server-side(root directory).
            using (var file = File.Create(Path.Combine(HostingEnvironment.MapPath("~/Uploads"), Guid.NewGuid().ToString() + ext)))
            {
                await stream.CopyToAsync(file);
            }
        }
    }
    

    Client-side.
    enter image description here The body section will post the binary data, just like you do.
    Besides, WCF doesn’t support the form-data by default, while we could take advantage of the third-party library, which enables us to pass the form-data parameter.
    https://archive.codeplex.com/?p=multipartparser
    Then we could post form-data to transfer the file information. Please refer to the below code.

    public async Task UploadStream(Stream stream)
            {
                MultipartParser parser = new MultipartParser(stream);
    
                if (parser.Success)
                {
                    //absolute filename, extension included.
                    var filename = parser.Filename;
                    var filetype = parser.ContentType;
                    var ext = Path.GetExtension(filename);
                    using (var file = File.Create(Path.Combine(HostingEnvironment.MapPath("~/Uploads"), Guid.NewGuid().ToString() +ext)))
                    {
                        await file.WriteAsync(parser.FileContents, 0, parser.FileContents.Length);
                    }
                }
            }
    

    enter image description here
    Finally, there is built-in support for passing the form-data in Asp.net WebAPI.
    https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-2
    Feel free to let me know if there is anything I can help with.