2017-03-15 75 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; 

解决了这个问题。希望我不会在任何地方出错。