将图像从客户端发送到 WCF 服务器 C# 时出错(Base-64 字符数组的长度无效)

本文关键字:数组 字符 Base-64 无效 出错 客户端 图像 服务器 WCF | 更新日期: 2023-09-27 18:30:17

Hallo 我有一个 wcf 服务器和一个客户端,我想以字符串形式从客户端发送/接收图像(转换为 base64)。我已经从服务器发送到客户端并且可以工作。我想从客户端发送到服务器并收到错误:Base-64 字符数组的长度无效。错误可能出在 xml 文件中。

这是我的代码:

服务器端: (WCFService.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization.Json;
namespace Services
{
    public class WCFService : Services_Form, IWCFService
    {
        public string ImageToBase64(Image image)
        {
            using (MemoryStream m = new MemoryStream())
            {
                image.Save(m, image.RawFormat);
                byte[] imageBytes = m.ToArray();
                string base64String = Convert.ToBase64String(imageBytes);
                return base64String;
            }
        }
        public Image Base64ToImage(string base64String)
        {
            // Convert Base64 String to byte[]
            byte[] imageBytes = Convert.FromBase64String(base64String);
            MemoryStream ms = new MemoryStream(imageBytes, 0,
              imageBytes.Length);
            // Convert byte[] to Image
            ms.Write(imageBytes, 0, imageBytes.Length);
            Image image = Image.FromStream(ms, true);
            return image;
        }
        //RECEIVE IMAGE
        public string getimage()
        {
            return ImageToBase64(pictureBox1.Image);
        }
        //SEND IMAGE
        public string postimage(string im)
        {
            pictureBox2.Image = Base64ToImage(im);
            return "Ok";
        }
    }
}

(IWCFS服务.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
namespace Services
{
    [ServiceContract]
    public interface IWCFService
    {
        [OperationContract(Name = "image")]
        [WebInvoke(Method = "GET",
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Bare,
            UriTemplate = "getimage")]
        string getimage();
        [OperationContract(Name = "image2")]
        [WebInvoke(Method = "GET",
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Bare,
            UriTemplate = "postimage?Image={im}")]
        string postimage(string im);
    }
}

服务器窗体

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Data.SqlClient;
namespace Services
{
    public partial class Services_Form : Form
    {
        ServiceHost host;
        string WCFPort;
        //SERVER FORM
        public Services_Form()
        {
            InitializeComponent();
        }
        private void StartWCFServer()
        {
                if (host == null)
                {
                    Uri baseAddress = new Uri("http://localhost:"+WCFPort+"/");
                    host = new ServiceHost(typeof(WCFService), baseAddress);
                    host.AddServiceEndpoint(typeof(IWCFService), new WSHttpBinding(), "Services");
                    try
                    {
                        host.Open();
                    }
                    catch
                    {
                        MessageBox.Show("ERROR");
                    }
                }
                else
                {
                    MessageBox.Show("Change PORT");
                }
        }
        private void btn_StopServer_Click(object sender, EventArgs e)
        {
            if (host != null)
            {
                host.Close();
            }
            else MessageBox.Show("Server already closed!");
        }
        //START SERVER BUTTON
        private void button1_Click_1(object sender, EventArgs e)
        {
            WCFPort = "8000";
            StartWCFServer();    
        }
    }
}

服务器的应用程序.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Services.WCFService" behaviorConfiguration="ServiceBehaviour">
        <endpoint bindingConfiguration="webHttpBindingDev" address="" binding="webHttpBinding" contract="Services.IWCFService"  behaviorConfiguration="web"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviour">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBindingDev">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"  maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
        </binding>
      </webHttpBinding>
    </bindings>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true" />
  </system.webServer>
</configuration>

现在客户端:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.Serialization.Json;
using System.Web.Script.Serialization;
namespace Διαχείριση
{
    public partial class Administator_Form : Form
    {
        string IpAddress = "localhost";
        string Port = "8000";

        //CLIENT FORM
        public Administator_Form()
        {
            InitializeComponent();
            try
            {
                WebRequest request = WebRequest.Create(UrlTag(""));
                WebResponse response = request.GetResponse();  
            }
            catch
            {
                MessageBox.Show("Error connect to server");
            }
        }
        public string ImageToBase64(Image image)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // Convert Image to byte[]
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] imageBytes = ms.ToArray();
                // Convert byte[] to Base64 String
                string base64String = Convert.ToBase64String(imageBytes);
                return base64String;
            }
        }
        public Image Base64ToImage(string base64String)
        {
            // Convert Base64 String to byte[]
            byte[] imageBytes = Convert.FromBase64String(base64String);
            MemoryStream ms = new MemoryStream(imageBytes, 0,
              imageBytes.Length);
            // Convert byte[] to Image
            ms.Write(imageBytes, 0, imageBytes.Length);
            Image image = Image.FromStream(ms, true);
            return image;
        }
        private T GetDataFromServer<T>(string url)
        {
            WebRequest request = WebRequest.Create(string.Format(url));
            WebResponse response = request.GetResponse();
            Stream stream = request.GetResponse().GetResponseStream();
            DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(T));
            T result = (T)json.ReadObject(stream);
            return result;
        }
        private string UrlTag(string tag)
        {
            return "http://" + IpAddress + ":" + Port + "/" + tag;
        }
        //SEND IMAGE
        private void button2_Click(object sender, EventArgs e)
        {
            string myParameters = "";
            myParameters = "?Image=" + ImageToBase64(pictureBox1.Image) + "";
            string responseMessage = GetDataFromServer<String>(UrlTag("postimage" + myParameters));
        }
        //RECEIVE IMAGE
        private void button3_Click(object sender, EventArgs e)
        {
            string img = GetDataFromServer<string>(UrlTag("getimage"));
            pictureBox2.Image = Base64ToImage(img);
        }
    }
}

将图像从客户端发送到 WCF 服务器 C# 时出错(Base-64 字符数组的长度无效)

最后,

我在我的问题中找到了一个解决方案。所有代码都是一样的,但在我将图像转换为 base64 和将 base64 转换为图像的函数中,我必须用其他字符替换 base64 字符串中的 =/+ 字符,因为这些字符 url 不可用。

以下是正确的函数:

public string ImageToBase64(Image image)
    {
        using (MemoryStream m = new MemoryStream())
        {
            image.Save(m, image.RawFormat);
            byte[] imageBytes = m.ToArray();
            string base64String = Convert.ToBase64String(imageBytes);
            string a = base64String.Replace('/', '_').Replace('+', '-').Replace('=', ',');
            base64String = a;
            return base64String;
        }
    }
    public Image Base64ToImage(string base64String)
    {
        // Convert Base64 String to byte[]
        string a = base64String.Replace('_', '/').Replace('-', '+').Replace(',', '=');
        base64String = a;
        byte[] imageBytes = Convert.FromBase64String(base64String);
        MemoryStream ms = new MemoryStream(imageBytes, 0,
          imageBytes.Length);
        // Convert byte[] to Image
        ms.Write(imageBytes, 0, imageBytes.Length);
        Image image = Image.FromStream(ms, true);
        return image;
    }

通过这种方式,它可以完美地工作。如果你有任何其他更好的想法,告诉我学习更多的想法。