Winform 如何移植到 WebForm。

这个问题其实也就是要找一个好的方案,最大程度的复用现有的资源。

同时,WebForm的话,不一定要走ASPNET这条路,可以自己搞定HTTP协议的。

下图是Winform版

下图是Web版本

1。如何自己搞定HTTP协议

WebForm,可以重头老老实实的用ASPNET来做,不过,现在Oracle,MongoDB这样的数据库都支持本地的浏览器方式管理了,这样的应用,不用安装ASP,PHP这样的服务器,完全自己实现一个简单的HTTP服务器。

OK,我们也实现一个吧,侦听13000(这里随便什么都可以的,不过推荐使用10000以上的端口号)端口,开启多线程,做HTTP服务吧。

public void Start()
        {
            TcpListener server = null;
            try
            {
                // Set the TcpListener on port 13000.
                Int32 port = 13000;
                IPAddress localAddr = IPAddress.Parse("127.0.0.1");

// TcpListener server = new TcpListener(port);
                server = new TcpListener(localAddr, port);

// Start listening for client requests.
                server.Start();

// Enter the listening loop.
                while (true)
                {
                    ///对于每个请求创建一个线程,线程的参数是TcpClient对象
                    TcpClient client = server.AcceptTcpClient();
                    OutputLog("[Init]" + DateTime.Now + "Connected!", 0);
                    ParameterizedThreadStart ParStart = new ParameterizedThreadStart(ProcessFun);
                    Thread t = new Thread(ParStart);
                    t.Start(client);
                }
            }
            catch (SocketException e)
            {
                OutputLog("SocketException: " + e, 0);
            }
            finally
            {
                // Stop listening for new clients.
                server.Stop();
                server = null;
            }

}

这里就是不停的启动ProcessFun来响应客户端(写客户端),同时用一个无限循环来侦听请求。

private void ProcessFun(object clientObj)
        {
            TcpClient client = clientObj as TcpClient;
            // Buffer for reading data
            Byte[] bytes = new Byte[512];

OutputLog("[Init]Waiting for a connection... ", 0);

// Get a stream object for reading and writing
            NetworkStream stream = client.GetStream();
            int i;
            // Loop to receive all the data sent by the client.
            while ((client.Available != 0) && (i = stream.Read(bytes, 0, bytes.Length)) != 0)
            {
                // Translate data bytes to a ASCII string.
                String data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                //OutputLog("Received:" + data);

string[] OrgRequest = data.Split(Environment.NewLine.ToCharArray());
                if (OrgRequest[0].StartsWith("GET"))
                {
                    String[] Request = OrgRequest[0].Split(" ".ToCharArray());
                    String RequestItem = HttpUtility.UrlDecode(Request[1], System.Text.Encoding.UTF8);
                    OutputLog("[RequestItem]Received : " + RequestItem, 0);
                    String[] RequestPath = RequestItem.Split("?".ToCharArray());
                    switch (RequestPath[0])
                    {
                        case "/":
                            //根节点 
                            GETPage(stream, GetPage.ConnectionList());
                            break;
                        case "/Connection":
                            GETPage(stream, GetPage.Connection(RequestPath[1]));
                            break;
                        default:
                            GETFile(stream, RequestItem.Replace("/", "\\"));
                            break;
                    }
                }
                else
                {
                    if (OrgRequest[0].StartsWith("POST"))
                    {

}
                }
            }

// Shutdown and end connection
            client.Close();
        }

这里响应请求,我只写完了GET,POST还没有开始动手呢。这里我们通过Stream.Read来获取请求,然后根据请求内容来寻找资源,将资源返还给客户端。

/// <summary>
        /// 
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="FileName"></param>
        private void GETFile(NetworkStream stream, String FileName)
        {
            byte[] msg = null;
            byte[] bFile = new byte[0];
            String data = String.Empty;
            Boolean IsFound = false;
            if (File.Exists(ServerPath + FileName))
            {
                IsFound = true;
                bFile = ReadFile(ServerPath + FileName);
            }
            else
            {
                //资源文件里面获得
                if (FileName.StartsWith("\\MainTreeImage"))
                {
                    //MainTreeImage00.png -- 从MainTreeImage 里面获得
                    int MainTreeImageIndex = Convert.ToInt32(FileName.Substring("\\MainTreeImage".Length, 2));
                    Image img = GetSystemIcon.MainTreeImage.Images[MainTreeImageIndex];
                    bFile = GetSystemIcon.imageToByteArray(img,ImageFormat.Png);
                    IsFound = true;
                }
            }

if (IsFound)
            {
                // Process the data sent by the client.
                data = "HTTP/1.1 200 OK" + Environment.NewLine;
                //if content-type is wrong,FF can;t render it,but IE can
                string filetype = String.Empty;
                switch (new FileInfo(FileName).Extension)
                {
                    case ".css":
                        filetype = "text/css";
                        break;
                    case ".js":
                        filetype = "text/javascript";
                        break;
                    case ".png":
                        filetype = "image";
                        break;
                    default:
                        break;
                }
                data += "Content-Type: @filetype; charset=utf-8".Replace("@filetype", filetype) + Environment.NewLine;
                data += "Content-Length: ";
                data += (bFile.Length).ToString();
                data += Environment.NewLine + Environment.NewLine;
                msg = System.Text.Encoding.ASCII.GetBytes(data);
                // Send back a response.
                stream.Write(msg, 0, msg.Length);
                stream.Write(bFile, 0, bFile.Length);
                OutputLog("[System]Sent HTML OK", 0);

}
            else
            {
                data = "HTTP/1.1 404 Not Found" + Environment.NewLine;
                msg = System.Text.Encoding.ASCII.GetBytes(data);
                // Send back a response.
                stream.Write(msg, 0, msg.Length);
                OutputLog("[System]FileName Not Found:" + FileName, 0);
            }
            stream.Flush();

}
    }

将资源(文件)给客户端,就是将资源转换为Bytes字节流,然后写入NetStream里面去。

当然,为了“欺骗”浏览器,我们还要在成功找到资源的时候,给个200 OK的标记,如果没有资源的话,给个404的标记。

以后,还要考虑 缓存的问题,已经请求过的资源,就给个3XX的,不用再重复取得资源了。

对于有些资源内容,这里干脆不从实体文件里面取了,直接从资源里面取了。客户才不知道这个文件到底怎么来的。

2。最大程度的复用代码

为了展示这个树形结构,原来的Windows代码非常的冗长(不是冗余)。

如何将这个树形Winform转为WebForm?如果最大程度的复用代码,这是必须要考虑的。树形展示,我使用了zTree这个Jquery插件。只要能够给他一个JSON的节点信息,就可以帮你自动完成树形了。

原来的代码的目标是生成一个Treeview,现在的目标是做个JSON。当然,可以将原来的代码里面的TreeNode的构成逻辑化为BsonDocument(MongoDB的概念,类似JSON)。不过,最最正确的做法是,直接将Treeview的结果转换为JSON。不用修改任何原来的代码,最大限度的使用原来的代码。

#region"展示数据库结构 WebForm"
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ConnectionName"></param>
        /// <returns></returns>
        public static String FillConnectionToJSON(String ConnectionName)
        {
            String strJSON = String.Empty;
            TreeView tree = new TreeView();
            FillConnectionToTreeView(tree);
            //Transform Treeview To JSON
            //必须这样做,防止二重管理的问题。如果这里的逻辑有两套的话,维护起来比较麻烦。
            //一套逻辑,来控制树的内容。然后将TreeView的内容转换为JSON。
            //递归GetSubTreeNode
            strJSON = GetSubTreeNode(tree.Nodes[0]).ToJson(SystemManager.JsonWriterSettings);
            return strJSON;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="SubNode"></param>
        /// <returns></returns>
        private static BsonDocument GetSubTreeNode(TreeNode SubNode)
        {
            if (SubNode.Nodes.Count == 0)
            {
                BsonDocument SingleNode = new BsonDocument();
                SingleNode.Add("name", SubNode.Text);
                SingleNode.Add("icon", "MainTreeImage" + String.Format("{0:00}",SubNode.ImageIndex) + ".png");
                return SingleNode;
            }
            else
            {
                BsonDocument MultiNode = new BsonDocument();
                MultiNode.Add("name", SubNode.Text);
                BsonArray ChildrenList = new BsonArray();
                foreach (TreeNode item in SubNode.Nodes)
                {
                    ChildrenList.Add(GetSubTreeNode(item));
                }
                MultiNode.Add("children", ChildrenList);
                MultiNode.Add("icon", "MainTreeImage" + String.Format("{0:00}", SubNode.ImageIndex) + ".png");
                return MultiNode;
            }
        }
        #endregion

原来的FillConnectionToTreeView(tree);是一个很庞大的方法,用来构建一个Treeview,里面存放着数据库的完整结构。

这里我们将这个Treeview ,通过GetSubTreeNode 这个方法转换为了BsonDocument,然后直接使用内置方法转为JSON,一切搞定了。10来行代码,非常优雅。

通过这个例子,我想说,作为程序员,一定要时刻注意,不要出现同样的代码,不要双重管理代码,不要改了一个地方,另一个地方也必须改动。

明天去 埃森哲 入职,上海埃森哲的朋友,多多关照阿。。。。

[NET] 如何从 Winform 移植到 Webform [自己搞定HTTP协议]相关推荐

  1. 《安富莱嵌入式周报》第312期:开源磁场照相机,仿生神经元PCB,开源无线耳机,手机系统PalmOS移植到各种单片机,开放系统组装协议OSAP

    周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Pow ...

  2. u-boot移植随笔:u-boot2010.09移植到8MB Nor Flash的S3C2440,第一步搞定(补记)

    这个本来是我发在csdn上的帖子,有一次使用搜索引擎时不小心搜索到.于是再将它放到博客里. 芯片:S3C2440(目前大部分的开发板在某个层次上讲是一样的) Nor Flash:SST39VF6401 ...

  3. 一文搞定stm32移植LWIP及代码逻辑

    文章目录 一,使用以太网的库 二,ST以太网驱动库的移植 1,stm32f4x7_eth.c 2,lan8720.c 三,移植LWIP协议栈 1,lwip_comm.c 2,ethernetif.c ...

  4. winform生成exe俩秒钟就退出_Python有多牛逼?三万多条数据,几秒钟全部搞定~

    应用场景:工作中经常遇到大量的数据需要整合.去重.按照特定格式导出等情况.如果用 Excel 操作,不仅费时费力,还不准确,有么有更高效的解决方案呢? 本文以17个 txt 文本,3万多条数据为例,使 ...

  5. 4.基于MTK的7601 WIFI网卡在X210上的移植和使用

     老规矩上笔记链接: 文档:项目4.基于MTK的7601 WIFI网卡在X210上... 链接:http://note.youdao.com/noteshare?id=5f494ebf7bf8d7b0 ...

  6. 畅谈ASP.NET 查看聊天记录

    本期嘉宾:,黄忠成,瞿杰,赵立东,主持人,聊天话题:3月14日与黄忠成.瞿杰.赵立东.畅谈ASP.NET 查看聊天记录    嘉宾发言区   _____________________________ ...

  7. 一套跨平台五子棋网游的开发经历

    闲来无事,因自己想要在服务器开发方面进行更深入的学习,积累更丰富的经验.决定写一套网络游戏的c/s. 因为主要目的是服务器的开发,因此游戏我选用规则较为简单.画面特效没有要求的回合制游戏:五子棋.我曾 ...

  8. Winform与Webform中的对话框

    参考MSDN DialogResult result = MessageBox.Show("见过打劫的没?", "打.打.打劫", MessageBoxButt ...

  9. WebForm实现增删改查

    上文,我们使用pb和c#WinForm使用分别实现了增删改查,本文,我们C#WebForm技术来实现一下.首先,说明一点,WinForm和WebForm基本是一样,代码基本雷同,就是使用的控件不一样, ...

最新文章

  1. Forefront Security For Exchange的反病毒测试
  2. 数字图像处理:第四章 点运算
  3. Android adb无线调试脚本
  4. 开发Windows Mobile和Wince(Windows Embedded CE)的部署项目(Deploy Project)时,如何修改注册表...
  5. 为什么选择做班级管理系统_为什么即使在平衡的班级下准确性也很麻烦
  6. 交换机跟计算机系统有关系,网速跟交换机有关系吗
  7. 燃鹅小助手自动抽奖源码
  8. Uncaught SyntaxError: missing ) after argument list 错误解决
  9. Linux下添加eigen头文件,移植Eigen库到SylixOS下及使用方法
  10. 嵌入式成长轨迹52 【Zigbee项目】【CC2430基础实验】【在PC用串口收数并发数】...
  11. C++ 练习题(一:布尔表达式与真值表图文详解)
  12. 个人成长 | 电子设计大赛感受
  13. NGFW module恢复密码操作方法
  14. vue里面watch监听当前路由信息
  15. 互信息和左右熵的新词发现(笔记)
  16. android sdk离线安装方法,Android 4.0 SDK的离线方式安装
  17. 嵌入式知识-ARM裸机-学习笔记(9):SD卡启动详解(S5PV210)
  18. 【不可思议的Word2Vec】 2.训练好的模型
  19. 最后1天,包邮送50豆瓣高分Python 好书
  20. 决策树(一)——构建决策树

热门文章

  1. 阿里达摩院AI抗疫最新战报:已诊断3万多疑似病例CT影像,准确率96%
  2. 超好用的自信学习:1行代码查找标签错误,3行代码学习噪声标签
  3. 430亿晶体管,1020万逻辑单元,英特尔发布全球最大容量FPGA,用全新硬件加速AI开发...
  4. BERT和ERNIE谁更强?这里有一份4大场景的细致评测
  5. sql的执行顺序 (where、groupby、having等)
  6. Java-J2SE专题复习
  7. 如何用两种方式同时实现ListBox的滚动功能
  8. 是时候搁置Grunt,耍一耍gulp了
  9. 函数作为变量,类型---golang
  10. python 子图_python 实现在一张图中绘制一个小的子图方法