基于C#实现自己的webapi调用软件

博主前面讲述到可以通过python下的flask框架部署自己的模型,也讲述过通过aistudio部署自己的paddle模型(可以参考基于aistudio部署自己的paddle模型),然后通过web请求实现调用。这里的webapi调用软件主要针对aistudio部署平台的webapi进行请求调用,如果是自己部署的服务,也可以参考该教程(仅需求修改解析结果json的部分即可)。先说一下软件设计的特性:

1、支持对webapi的url进行加密解密,避免站点和参数信息直接暴露给用户

2、支持webapi的结果为图片或者字符串。(其中图片以base64的形式表示)

3、在选择文件时支持点选和拖拽

软件主要由界面代码、主程序、字符串加密类、webapi调用类、图像处理类实现,本博文后面有软件下载地址。

1、界面设计

软件界面设计如下所示,其中有一个加密按钮,用于加密输出框的url地址。当软件要交付给其他人测试时,可以将加密按钮删除。
在这里插入图片描述

2、主程序的基本实现

这里主要实现各种按钮的点击事件(如点击测试按钮[button1]发送http请求调用webapi、点击加密按钮[button1]则加密输入框中的字符串、点击下方的图片控件[pictureBox1]则选择图片文件),同时也实现了pictureBox1的文件拖入效果、结果展示函数set_result(支持图像展示、字符串展示)。

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            pictureBox1.AllowDrop = true;//设置控件允许拖拽文件
        }
        public string base64_img = null;
        private void set_result(string result) {
            if (ImgUtils.IsBase64(result))
            {
                Image img = ImgUtils.ConvertBase64ToImage(result);
                pictureBox2.Image = img;
                richTextBox1.Visible = false;
                pictureBox2.Visible = true;
            }
            else
            {
                richTextBox1.Text = result;
                richTextBox1.Visible = true;
                pictureBox2.Visible = false;
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            string url = DES.Decrypt(apiKey_input.Text);
            string content= "{\"input\": \"" + base64_img + "\" }";
            string result = NetUtils.Post(url, content);
            set_result(result);
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofg = new OpenFileDialog();
            ofg.Filter = "Image Files (*.jpg;*.bmp;*.png)|*.jpg;*.bmp;*.png";
            ofg.Multiselect = false;
            //调用对象的函数
            if (ofg.ShowDialog() == DialogResult.OK)
            {
                //获取文件的路径
                string filepath = ofg.FileName;
                read_image(filepath);
            }
        }
        private void read_image(string filepath) {

            using (FileStream file = new FileStream(filepath, FileMode.Open))
            {
                Image img = Image.FromStream(file);
                img = ImgUtils.resizeImg(img, pictureBox1.Width, pictureBox1.Height);
                pictureBox1.Image = img;
                base64_img = ImgUtils.ConvertImageToBase64(pictureBox1.Image);
                set_result(base64_img);
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            string encrypt=DES.Encrypt(apiKey_input.Text);
            string decrypt=DES.Decrypt(encrypt);
            richTextBox1.Text = encrypt+"\n"+ decrypt;
            apiKey_input.Text = encrypt;
        }

        private void pictureBox1_DragDrop(object sender, DragEventArgs e)
        {
            string[] s = (string[])e.Data.GetData(DataFormats.FileDrop, false);
            read_image(s[s.Length-1]);
        }

        private void pictureBox1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.All;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }
    }

2、字符串加密类

是一个静态工具类,用于实现字符串的加密解密,在本软件中主要用于webapi的url加密解密。

 public class DES
    {
        static string encryptKey = "abcd";//定义密钥,长度为32位,故只能是4个字符
        #region 加密字符串
        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="str">要加密的字符串</param>
        /// <returns>加密后的字符串</returns>
        public static string Encrypt(string str)
        {
            DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();//实例化加/解密类对象
            byte[] key = Encoding.Unicode.GetBytes(encryptKey);//定义字节数组,用来存储密钥
            byte[] data = Encoding.Unicode.GetBytes(str);//定义字节数组,用来存储要加密的字符串
            MemoryStream MStream = new MemoryStream();//实例化内存流对象
                                                      //使用内存流实例化加密流对象
            CryptoStream CStream = new CryptoStream(MStream, descsp.CreateEncryptor(key, key), CryptoStreamMode.Write);
            CStream.Write(data, 0, data.Length);//向加密流中写入数据
            CStream.FlushFinalBlock();//释放加密流
            return Convert.ToBase64String(MStream.ToArray());//返回加密后的字符串
        }

        #endregion

        #region 解密字符串
        /// <summary>
        /// 解密字符串
        /// </summary>
        /// <param name="str">要解密的字符串</param>
        /// <returns>解密后的字符串</returns>
        public static string Decrypt(string str)
        {
            DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();//实例化加/解密对象
            byte[] key = Encoding.Unicode.GetBytes(encryptKey);//定义字节数组,用来存储密钥
            byte[] data = Convert.FromBase64String(str);//定义字节数组,用来存储要解密的字符串
            MemoryStream MStream = new MemoryStream();//实例化内存流对象
                                                      //使用内存流实例化解密流对象
            CryptoStream CStream = new CryptoStream(MStream, descsp.CreateDecryptor(key, key), CryptoStreamMode.Write);
            CStream.Write(data, 0, data.Length);//向解密流中写入数据
            CStream.FlushFinalBlock();//释放解密流
            return Encoding.Unicode.GetString(MStream.ToArray());//返回解密后的字符串
        }
        #endregion
    }

3、webapi调用类

这里主要实现发生http请求调用webapi,并解析结果。如果是自己部署的服务,则需求修改本代码中结果解析的部分。

class NetUtils
{
    #region Post请求
    /// <summary>
    /// http Post请求
    /// </summary>
    /// <param name="parameterData">参数</param>
    /// <param name="serviceUrl">访问地址</param>
    /// <param name="ContentType">默认 application/json , application/x-www-form-urlencoded,multipart/form-data,raw,binary </param>
    /// <param name="Accept">默认application/json</param>
    /// <returns></returns>
    public static string Post(string serviceUrl, string parameterData, string ContentType = "application/json", string Accept = "application/json")
    {
        try
        {
            //先根据用户请求的uri构造请求地址
            //string serviceUrl = string.Format("{0}/{1}", this.BaseUri, uri);

            //创建Web访问对象
            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl);
            //把用户传过来的数据转成“UTF-8”的字节流
            byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(parameterData);

            myRequest.Method = "POST";
            //myRequest.Accept = "application/json";
            //myRequest.ContentType = "application/json";  // //Content-Type: application/x-www-form-urlencoded 
            myRequest.AutomaticDecompression = DecompressionMethods.GZip;
            myRequest.Accept = Accept;
            //myRequest.ContentType = ContentType;
            myRequest.ContentType = "application/json; charset=UTF-8";
            myRequest.ContentLength = buf.Length;
            myRequest.MaximumAutomaticRedirections = 1;
            myRequest.AllowAutoRedirect = true;

            //myRequest.Headers.Add("content-type", "application/json");
            //myRequest.Headers.Add("accept-encoding", "gzip");
            //myRequest.Headers.Add("accept-charset", "utf-8");

            //发送请求
            Stream stream = myRequest.GetRequestStream();
            stream.Write(buf, 0, buf.Length);
            stream.Close();

            //通过Web访问对象获取响应内容
            HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
            //通过响应内容流创建StreamReader对象,因为StreamReader更高级更快
            StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
            //string returnXml = HttpUtility.UrlDecode(reader.ReadToEnd());//如果有编码问题就用这个方法
            string returnData = reader.ReadToEnd();//利用StreamReader就可以从响应内容从头读到尾

            reader.Close();
            myResponse.Close();

            JObject jo = (JObject)JsonConvert.DeserializeObject(returnData);
            try
            {
                return jo["result"]["output"].ToString();
            }
            catch (Exception ex)
            {
                return returnData;
            }
        }
        catch (Exception ex)
        {
            return "接口调用失败";
        }
    }
    #endregion
}

4、图像处理类

图像处理类主要实现base64字符串转image,image转base64字符串和iamge的resize。

 class ImgUtils
    {
        private static char[] base64CodeArray = new char[]
       {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            '0', '1', '2', '3', '4',  '5', '6', '7', '8', '9', '+', '/', '='
       };
        public static bool IsBase64(string base64Str)
        {
            //string strRegex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";

            if (string.IsNullOrEmpty(base64Str))
                return false;
            else
            {
                if (base64Str.Contains(","))
                    base64Str = base64Str.Split(',')[1];
                if (base64Str.Length % 4 != 0)
                    return false;
                if (base64Str.Any(c => !base64CodeArray.Contains(c)))
                    return false;
            }
            try
            {
                return true;
            }
            catch (FormatException)
            {
                return false;
            }
        }
        public static string ConvertImageToBase64(Image bmp)
        {
            try
            {
                MemoryStream ms = new MemoryStream();
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] arr = new byte[ms.Length]; ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length); ms.Close();
                return Convert.ToBase64String(arr);
            }
            catch (Exception ex)
            {
                return "转换错误";
            }
        }
        public static Image ConvertBase64ToImage(string base64String)
        {
            try
            {
                byte[] imageBytes = Convert.FromBase64String(base64String);
                using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
                {
                    ms.Write(imageBytes, 0, imageBytes.Length);
                    return Image.FromStream(ms, true);
                    }
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public static Image resizeImg(Image sourceImage, int targetWidth, int targetHeight)
        {
            int width;//图片最终的宽
            int height;//图片最终的高
            try
            {
                //获取图片宽度
                int sourceWidth = sourceImage.Width;
                //获取图片高度
                int sourceHeight = sourceImage.Height;

                System.Drawing.Imaging.ImageFormat format = sourceImage.RawFormat;
                Bitmap targetPicture = new Bitmap(targetWidth, targetHeight);
                Graphics g = Graphics.FromImage(targetPicture);
                g.Clear(Color.White);
                g.DrawImage(sourceImage, 0,0, targetWidth, targetHeight);
                sourceImage.Dispose();
                return targetPicture;
            }
            catch (Exception ex)
            {

            }
            return null;
        }

    }

5、软件测试

软件的下载地址为:https://download.csdn.net/download/a486259/86505608
解压后即可运行,可以自己将上述代码复制到自己的vs项目中。

选择图片

在这里插入图片描述

点击测试

在这里插入图片描述

启动服务后再次测试

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万里鹏程转瞬至

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值