【问题标题】:Store image to Server using WCF services and Xamarin.Forms使用 WCF 服务和 Xamarin.Forms 将图像存储到服务器
【发布时间】:2017-08-06 10:28:18
【问题描述】:

我正在使用 Xamarin Forms 开发移动应用程序,其中在应用程序中将图像发送到服务器。对于发送图像,我们使用了 WCF 服务。

下面是 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 表单将图像存储到数据库中的更简单方法。

【问题讨论】:

  • 你能用WebAPI吗?如果是,我有办法。
  • @Enrico:是的,有可能。请指导

标签: c# wcf xamarin xamarin.forms


【解决方案1】:

简单的改变

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

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

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

【讨论】:

    【解决方案2】:

    例如,创建一个名为 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;
    

    我在很多应用程序中都使用了这个实现,它运行良好。如果您有任何改进建议,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      相关资源
      最近更新 更多