Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have written a webservice and one of the function needs to return a System.Drawing.Image

Here is my service function:

public class GetVisitorImageController : ApiController
    [Route("GetVisitorImage/{id}")]
    [HttpGet]
    public System.Drawing.Image Get(string id)
        string[] authorization = Request.Headers.Authorization.ToString().Split('|');
        string PartnerId = Request.Headers.GetValues("PartnerId").First();
        string DeviceId = Request.Headers.GetValues("DeviceId").First();
            return VisitorFunctions.GetVisitorImage(authorization[0], authorization[1], id, PartnerId, DeviceId);
        catch
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NoContent));

and here is my client function:

public static System.Drawing.Image GetVisitorImage(NetworkInfo networkInfo, string partnerId, string deviceId, string visitorId)
    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(AcceptAllCertifications);
    var httpWebRequest = (HttpWebRequest)WebRequest.Create(networkInfo.baseUrl + "GetVisitorImage" + "/" + visitorId);
    httpWebRequest.ContentType = "application/json";
    httpWebRequest.Method = "GET";
    httpWebRequest.Headers.Add("Authorization", "" + networkInfo.userName + "|" + networkInfo.userPassword + "");
    httpWebRequest.Headers.Add("PartnerId", partnerId);
    httpWebRequest.Headers.Add("DeviceId", deviceId);
    httpWebRequest.Proxy = ConfigureProxy(networkInfo);
    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        var result = streamReader.ReadToEnd();
        return JsonConvert.DeserializeObject<System.Drawing.Image>(result);

As you can probably see I have tried using Json library to convert the results of the StreamReader to a System.Drawing.Image

I get the feeling the json library is not able to do what I am trying to do.

Can I convert the StreamReader string "result" and return it as a System.Drawing.Image?

Thanks

Looks to me you are making a traditional SO question mistake. You futzed around for a while to solve the problem, gave up and posted your least-likely-to-be-correct version of your code. My crystal ball says that your first attempt passed httpResponse.GetResponseStream() to Image.FromStream() and got a non-descriptive generic GDI+ exception. That can't work, FromStream() requires a stream that supports seeking. NetworkStream doesn't. You have to slurp the response data into a MemoryStream first, set the Position back to 0, now you can pass it to FromStream. – Hans Passant Jul 9, 2014 at 13:31

You can't simply serialize a System.Drawing.Image to Json, and then deserialize the json back to a System.Drawing.Image. Json simply serializes the public properties of an object, and System.Drawing.Image is a wrapper around the GDI2 library.

Instead you should save your System.Drawing.Image to a byte array using some image encoder (jpg or png), and return that byte array from your GetVisitorImage action. On the client side you read all of the bytes (using ReadToEnd on the ResponseStream) and render them, or you still have the option to reconstruct your System.Drawing.Image from your stream - if you really need a System.Drawing.Image.

I am completely unfamiliar with the web API, so I am not entirely sure what the best way is to declare this in your webAPI method.

Here is how I fixed it.

Basically, in the service I converted the image to a base64 string and returned that.

In the client I converted the returned base64 string back to a System.Drawing.Image

This is the new Service controller:

public class GetVisitorImageController : ApiController
    [Route("GetVisitorImage/{id}")]
    [HttpGet]
    public string Get(string id)
        string[] authorization = Request.Headers.Authorization.ToString().Split('|');
        string PartnerId = Request.Headers.GetValues("PartnerId").First();
        string DeviceId = Request.Headers.GetValues("DeviceId").First();
        System.Drawing.Image visitorimage = VisitorFunctions.GetVisitorImage(authorization[0], authorization[1], id, PartnerId, DeviceId);
        MemoryStream memStream = new MemoryStream();
        visitorimage.Save(memStream, ImageFormat.Jpeg);
        byte[] imageBytes = memStream.ToArray();
        string base64String = Convert.ToBase64String(imageBytes);
        return base64String;

And this is the new client function

public static System.Drawing.Image GetVisitorImage(NetworkInfo networkInfo, string partnerId, string deviceId, string visitorId)
        ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(AcceptAllCertifications);
        var httpWebRequest = (HttpWebRequest)WebRequest.Create(networkInfo.baseUrl + "GetVisitorImage" + "/" + visitorId);
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "GET";
        httpWebRequest.Headers.Add("Authorization", "" + networkInfo.userName + "|" + networkInfo.userPassword + "");
        httpWebRequest.Headers.Add("PartnerId", partnerId);
        httpWebRequest.Headers.Add("DeviceId", deviceId);
        httpWebRequest.Proxy = ConfigureProxy(networkInfo);
        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            var result = streamReader.ReadToEnd();
            result = result.Remove(0, 1); // remove first character
            result = result.Remove(result.Length - 1); // remove last character
            byte[] imageBytes = Convert.FromBase64String(result);
            MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
            ms.Write(imageBytes, 0, imageBytes.Length);
            Image image = Image.FromStream(ms, true);
            return image;
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.