Question

I am building a mobile app using xamarin while the server is hosted in azure. I am uploading images in the following way: Client:

public static async Task<string> UploadImage (string url, byte[] imageData)
        {
            var content = new MultipartFormDataContent();
            var fileContent = new ByteArrayContent(imageData);
            fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = Guid.NewGuid() + ".Png"
            };
            content.Add(fileContent);

            using (var client = new HttpClient())
            {
                try
                {
                    HttpResponseMessage msg = await client.PutAsync (url, content);
                    if(msg.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        return msg.Headers.GetValues ("ImageUrl").First();
                    }
                    return string.Empty;

                }
                catch (Exception ex)
                {
                    return string.Empty;
                }
            }          
        }

and here is the server code:

[HttpPut]
        public async Task<HttpResponseMessage> PostNewDishImage(string imageID)
        {
            try
            {
                _dishImagescontainer = BlobStorageHandler.GetContainer("dishuserimages");
                if (!Request.Content.IsMimeMultipartContent("form-data"))
                {
                    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
                }

                var provider = new BlobStorageProvider(_dishImagescontainer);
                await Request.Content.ReadAsMultipartAsync(provider);
                IList<string> urls = provider.Urls;
                if (urls.Count > 0)
                {
                    var response = new HttpResponseMessage();
                    response.StatusCode = HttpStatusCode.OK;
                    response.Headers.Add("ImageUrl", urls[0]);
                    return response;
                }
                return new HttpResponseMessage(HttpStatusCode.InternalServerError);
            }
            catch (System.Exception e)
            {
                return new HttpResponseMessage(HttpStatusCode.InternalServerError) { ReasonPhrase = e.ToString() };
            }
        }

It works fine but I don't like the way I am returning the new imageurl back to the client (through the http headers) I have tried some other ways but this is the best one so far :) Does anyone have any better ideas?

Thanks

Was it helpful?

Solution

Returning data to the client in an HTTP header like that does have a bit of a smell. How about returning a DTO serialized to JSON?

An example DTO class:

public class ImageUploadResponse
{
    public string Url { get; set; }
}

Then change your server side code to something like this:

var responseDto = new ImageUploadResponse { Url = urls[0] };
var response = new HttpResponseMessage(HttpStatusCode.OK)
    {
       Content = new StringContent(JsonConvert.SerializeObject(responseDto), 
           Encoding.UTF8, "application/json")
    };

which will send the results back to the client in the content of the HTTP response as JSON. Then the client can parse the JSON into an object (or not) as you see fit. This approach will also be more friendly to making such a call from JavaScript in the future if you desire because the result is standard JSON.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top