2017-03-15 93 views
2

我正在開發一個使用Xamarin Forms的移動應用程序,其中應用程序將圖像發送到服務器。爲了發送圖片,我們使用了WCF服務。遠低於使用WCF服務和Xamarin.Forms將圖像存儲到服務器

是Xamarin應用程序的代碼

using (var memoryStream = new MemoryStream()) 
     { 
      pick.GetStream().CopyTo(memoryStream); 
      pick.Dispose(); 
      byte[] byteImageArray = memoryStream.ToArray(); 
      try 
      { 
       var imageStream = new ByteArrayContent(byteImageArray); 
       var multi = new MultipartContent(); 
       multi.Add(imageStream); 

       var client = new HttpClient(); 
       var result = client.PostAsync("http://www.test.com/Services/Service.svc/SaveImage", multi).Result; 

       var json = await result.Content.ReadAsStringAsync(); 
       var strNo = JsonConvert.DeserializeObject<string>(json); 

      } 
      catch (Exception ex) 
      { 
       await DisplayAlert("Error", ex.Message, "Ok"); 
      } 
     } 

而對於WCF服務

public string SaveImage(Stream data) 
     { 
      byte[] byteImage = ReadFully(data); 
      //Database logic to insert byte array 
     } 

public static byte[] ReadFully(Stream input) 
     { 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       input.CopyTo(ms); 
       return ms.ToArray(); 
      } 
     } 

現在有了這個代碼,圖像越來越成功轉換並獲得存儲在數據庫中的BLOB。 我面臨的問題是每當我將blob轉換回圖像時,圖像就會被破壞。當我用asp.net應用程序將圖像插入blob時,blob的數據長度顯示爲18901,而插入與移動應用程序數據相同的圖像時,數據長度爲18987. 請幫我解決數據長度問題,或者請指導更簡單的方法使用WCF和Xamarin表單將圖像存儲到數據庫中。

+0

你可以使用'WebAPI'嗎?如果是,我有解決方案。 – Enrico

+0

@Enrico:是的,它是可能的。請指導 – Omkar

回答

1

例如,創建一個名爲PicturesController的WebAPI。您必須使用PUT動詞

/// <summary> 
/// Receiving an image across WebAPI 
/// </summary> 
/// <returns></returns> 
[HttpPut] 
public HttpResponseMessage Put() 
{ 
    var result = new HttpResponseMessage(HttpStatusCode.OK); 

    if (Request.Content.IsMimeMultipartContent()) 
    { 
     try 
     { 
      Request.Content.LoadIntoBufferAsync().Wait(); 
      Request.Content.ReadAsMultipartAsync<MultipartMemoryStreamProvider>(
       new MultipartMemoryStreamProvider()).ContinueWith((task) => { 
       MultipartMemoryStreamProvider provider = task.Result; 
       foreach (HttpContent content in provider.Contents) 
       { 
        Stream stream = content.ReadAsStreamAsync().Result; 
        Image image = Image.FromStream(stream); 

        try 
        { 
         string filename = string.Format("{0}{1}{2}{3}", 
                 DateTime.Now.Year, 
                 DateTime.Now.Month, 
                 DateTime.Now.Day, 
                 DateTime.Now.Second) + ".jpg"; 
         foreach (var h in content.Headers.ContentDisposition.Parameters) 
         { 
          if (h.Name.ToLower() == "filename") 
          { 
           filename = h.Value.Replace("\\", "/").Replace("\"", ""); 
           var pos = filename.LastIndexOf("/"); 
           if (pos >= 0) 
           { 
            filename = filename.Substring(pos + 1); 
           } 
           break; 
          } 
         } 

         string filePath = ConfigurationManager.AppSettings["Pictures"] 
                   .ToString(); 
         string fullPath = Path.Combine(filePath, filename); 

         EncoderParameters encparams = new EncoderParameters(1); 
         encparams.Param[0] = new EncoderParameter(Encoder.Quality, 80L); 
         ImageCodecInfo ici = null; 
         foreach (ImageCodecInfo codec in ImageCodecInfo 
                 .GetImageEncoders()) 
         { 
          if (codec.MimeType == "image/jpeg") 
          { 
           ici = codec; 
           break; 
          } 
         } 

         image.JpegOrientation().Save(fullPath, ici, encparams); 
        } 
        catch (Exception ex) 
        { 
        } 
       } 
      }); 
     } 
     catch (Exception ex) 
     { 
      result.StatusCode = HttpStatusCode.InternalServerError; 
     } 

     return result; 
    } 
    else 
    { 
     throw new HttpResponseException(Request.CreateResponse(
             HttpStatusCode.NotAcceptable, 
             "This request is not properly formatted")); 
    } 
} 

在此代碼創建一個臨時文件名。如果你傳遞一個作爲頭參數,我使用它。我將圖像保存在文件夾Pictures,我從web.config讀取此文件夾。該文件的格式爲jpeg,因爲通常這是您設備上的圖像格式。

當你這樣做時,你必須在你的Xamarin項目中創建一個webclient。

/// <summary> 
/// Uploads the photo. 
/// </summary> 
/// <returns>The photo.</returns> 
/// <param name="photoBytes">Photo bytes.</param> 
public async Task<bool> UploadPhoto(byte[] photoBytes, int PropertyId, string fileName) 
{ 
    bool rtn = false; 

    var content = new MultipartFormDataContent(); 
    var fileContent = new ByteArrayContent(photoBytes); 
    fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data"); 
    fileContent.Headers.ContentDisposition = 
         new ContentDispositionHeaderValue("attachment") { 
     FileName = fileName + ".jpg" 
    }; 
    content.Add(fileContent); 
    fileContent.Headers.ContentDisposition.Parameters.Add(
         new NameValueHeaderValue("<otherParam>", "<otherParamValue>")); 

    string url = RestURL() + "Pictures/Put"; 
    try 
    { 
     using (var client = new HttpClient()) 
     { 
      // add an authotization token if you have one 
      //client.DefaultRequestHeaders.Add("authenticationToken", "yourToken"); 
      await client.PutAsync(url, content); 
      rtn = true; 
     } 
    } 
    catch (Exception ex) 
    { 
    } 

    return rtn; 
} 

請記住,包括

using System.Net.Http; 
using System.Net.Http.Headers; 

我使用了很多應用程序的這種實現,它的工作完美。如果您有任何改進建議,請告訴我。

+0

我試用了您的解決方案,它工作完美。非常感謝Man .. – Omkar

0

簡單地改變

var multi = new MultipartContent(); 
multi.Add(imageStream); 

StreamContent scontent = new StreamContent(pick.GetStream()); 
HttpContent hp = scontent; 

解決了這個問題。希望我不會在任何地方出錯。