Send image to WebApi service

2019-03-03 12:02发布

I'm making a project on Windows Phone where user can take a photo, save it on phone and next upload on my server. So there are two projects, WP8.1 and ASP.NET WEB API.

Currently I don't know how to upload photo to my server(from phone), I even don't know how to catch it in API. What's the best way to make it?

Here is my method to show on the screen(phone), picture which was taken by user.

private async void LoadCapturedphoto(string filename)
    {
        //load saved image
        StorageFolder pictureLibrary = KnownFolders.SavedPictures;
        StorageFile savedPicture = await pictureLibrary.GetFileAsync(filename);
        ImageProperties imgProp = await savedPicture.Properties.GetImagePropertiesAsync();
        var savedPictureStream = await savedPicture.OpenAsync(FileAccessMode.Read);

        //set image properties and show the taken photo
        bitmap = new WriteableBitmap((int)imgProp.Width, (int)imgProp.Height);
        await bitmap.SetSourceAsync(savedPictureStream);
        takenImage.Source = bitmap;
        takenImage.Visibility = Visibility.Visible;

    }

I think that I should convert WriteableBitmap to Byte[], send these Byte[] by API to server and on server convert Byte[] to JPG/PNG/etc.

private byte[] ConvertBitmapToByteArray(WriteableBitmap bitmap)
    {
        WriteableBitmap bmp = bitmap;

        using (Stream stream = bmp.PixelBuffer.AsStream())
        {
            MemoryStream memoryStream = new MemoryStream();
            stream.CopyTo(memoryStream);
            return memoryStream.ToArray();
        }
    }

Any ideas? Do you think it's good idea to make it like that? WriteableBitmap -> Byte[] and next on server Byte[] -> JPG/PNG etc. Is it even possible?

If it can be done much more easier please write some samples.

it's my method for calling api methods

public string apiCommand(string api, string json)
    {
        using (var httpClient = new HttpClient())
        {
            HttpContent content = new StringContent(json, Encoding.UTF8);
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            HttpResponseMessage response = httpClient.PostAsync(Variables.apiURL + api, content).Result;
            response.EnsureSuccessStatusCode();

            Task<string> responseBody = response.Content.ReadAsStringAsync();
            //var msg = new MessageDialog(responseBody.Result.ToString());

            if (response.StatusCode.ToString() != "OK")
            {
                return "ERROR: " + response.StatusCode.ToString();
            }
            else
            {
                return "SUCCES: " + responseBody.Result.ToString();
            }
        }
    }

2条回答
地球回转人心会变
2楼-- · 2019-03-03 12:07

I handle image and word files in my project by this way, hope it helps.

1) Server side, I have a generic api method to process Json requests.

     [HttpPost]
     public HttpResponseMessage ProcessRequest([FromBody] string sJsonRequest)
     {
         ResponseMsg rspMsg = null;
         RequestMsg oRequestMsg = null;
         string sDeteializeMsg = "";
         try
         {
             string sUnescapeJsonData = System.Uri.UnescapeDataString(sJsonRequest);
             sJsonRequest = sUnescapeJsonData;
             oRequestMsg = (RequestMsg)JsonHelper.Deserialize(typeof(RequestMsg), sJsonRequest);
         }
         catch (Exception ex)
         {
             ...
         }
         if (oRequestMsg == null)
         {
             return AppHelper.GetUTF8PlainTextHttpResponse(@"Invalid request message.");
         }

         rspMsg = new ResponseMsg(oRequestMsg);
         string sJsonRet = "";
         try
         {
             if(oRequestMsg.RequestType==SavingFile)
              {
                   byte[] bytes = System.Convert.FromBase64String(oRequestMsg.Base64Data);
                   System.IO.File.WriteAllBytes(sFileName, bytes);
                   ....
               }
            //update rspMsg ....
         }
         catch (Exception ex)
         {
             ...
         }
         finally
         {
             sJsonRet = JsonHelper.Serialize(rspMsg);
         }
         return AppHelper.GetUTF8PlainTextHttpResponse(sJsonRet);
     }

Client side, 1) call through .net code, I use system.Net.webclient,

system.Net.webclient cli=new system.Net.webclient();
cli.Credentials = Credentials;
cli.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
//http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx
sJsonRequest = "=" + EscapeDataStringBig(sJsonRequest);
response = cli.UploadString(sRemoteUrl, "POST", sJsonRequest);
ResponseMsg rsp = (ResponseMsg)JsonHelper.Deserialize(typeof(ResponseMsg), response);
return rsp;

2) call it through JavaScript, usually I will create a method in website controller and forward the json request to the method defined as above. if your javascript code and api code share same json objects, it is quite easy.

2.1) web site controller code,

[HttpPost]
    public ActionResult AjaxRequest(int nPostType = -1, string sJsonObject = "")
    {
          try
          {
              WebModelAjaxRequestTypes nReqType = (WebModelAjaxRequestTypes)nPostType;
              bool bIsBase64Data = IsBase64Request(nReqType);

              string sJsonRet = "";
              if (!bIsBase64Data)
              {
                  ....
              }
              else
              {
                  //base64 content requests
                  string sBase64Data = sJsonObject;
                  //put the string into a json request and send it to api call. and get the return => sJsonRet
                  }

              return Content(sJsonRet);           }
          catch (Exception ex)
          {
             ....
          }
      }

2.2) JavaScript ajax call sample code:

    var type = "POST";
    var sContentType = "";
    var sData = ""
    if (bIsBase64) {
        //sJsonParas is base64 string. don't use encodeURI to encode it.!!!
        sContentType = 'application/json; charset=utf-8';
        sData = '{ "nPostType" :' + nPostType.toString() + ',"sJsonObject" : "' + sJsonParas + '" }';
    }
    else {
        sContentType = "application/x-www-form-urlencoded; charset=UTF-8";
        sData = "nPostType=" + nPostType.toString() + "&sJsonObject=" + encodeURIComponent(sJsonParas);
    }

    jQuery.ajax({
        url: sUrl,
        type: type,
        data: sData,
        contentType: sContentType,
        success: function (result) {
            ....
        },
        error: function (jqXHR, textStatus, errorThrown) {
            ....
        },
        complete: function (jqXHR, textStatus) {
            ....

        } //end complete
    });
查看更多
We Are One
3楼-- · 2019-03-03 12:30

You need to use multipart/form-data request to the server. You can send the json to the web api using payload field (another alternative is send every field separately, but you need reflection to do that.)

This maybe can help you:

public string UploadUserPictureApiCommand(string api, string json, byte[] picture)
{
    using (var httpClient = new HttpClient())
    {

       MultipartFormDataContent form = new MultipartFormDataContent();

       form.Add(new StringContent(json), "payload");
       form.Add(new ByteArrayContent(picture, 0, picture.Count()), "user_picture", "user_picture.jpg");

       HttpResponseMessage response = await httpClient.PostAsync(api, form);

       response.EnsureSuccessStatusCode();

       Task<string> responseBody = response.Content.ReadAsStringAsync();

        if (response.StatusCode.ToString() != "OK")
        {
            return "ERROR: " + response.StatusCode.ToString();
        }
        else
        {
            return "SUCCES: " + responseBody.Result.ToString();
        }
    }
}
查看更多
登录 后发表回答