cari
Rumahpembangunan bahagian belakangTutorial C#.Net通过asp.net mvc开发微信自定义菜单编辑工具的代码示例

这篇文章主要介绍了使用asp.net mvc,boostrap及knockout.js开发微信自定义菜单编辑工具,非常不错,具有参考借鉴价值,需要的朋友可以参考下

前言

  微信的接口调试工具可以编辑自定义菜单,不过是提交json格式数据创建菜单,非常的不方便还容易出错。网上的工具不好用,所以就自己写了一个。

正文

  先用bootstrap排个页面框架出来,调用自定义菜单接口需要用到AccessToken,放个输入框输入AccessToken。也不排除想直接输入AppId和AppSecret来获取AccessToken的用户,所以还需要下拉菜单来选择是输入AccessToken还是直接获取AccessToken。为了兼顾微信企业号应用创建菜单还需要AgentId,CorpId,套件永久授权码,SuiteId,SuiteSecret,SuiteTicket,参数的输入框大致就是这些。

  使用knockout定义好observables监控属性。并绑定到输入框上。

   

   定义菜单展示及菜单编辑模块,排版为微信公众号菜单三个大菜单,每个大菜单下面可以配五个子菜单。大致思路如下,页面排版为六行三列,三个大菜单未配置满时在右侧显示增加菜单按钮

每个父级菜单的子菜单未配置满时在上方显示增加菜单按钮。未配置满时以空白p占位。

  定义个函数生成自定义长度数组

  使用knockout定义好菜单监控属性,格式为

{
 "button": [
  {
   "name": "父级菜单1",
   "sub_button": [
    {
     "type": "view",
     "name": "子菜单1",
     "url": ""
    }
   ]
  },
  {
   "name": "父级菜单1",
   "sub_button": [
    {
     "type": "view",
     "name": "子菜单2",
     "url": ""
    },
    {
     "type": "view",
     "name": "子菜单1",
     "url": ""
    }
   ]
  }
 ]
}

   定义添加,编辑,删除菜单函数,定义添加编辑菜单时临时监控属性,定义当前编辑菜单索引的监控属性。

  一个一个编辑菜单还不是很方便,所以还要定义菜单的 上 下 左 右 的移动,及复制粘贴功能。

function MenuFormValidate() {
   $("#MenuForm").validate({
    rules: {
     name: {
      required: true
     },
     value: {
      required: false
     }
    },
    messages: {
     name: {
      required: "请输入名称"
     },
     value: {
      required: $("#txtMenuButtonValue").attr("placeholder")
     }
    }
   });
  }
          MenusReset:function () {
     var menus = JSON.stringify(model.Menus());
     model.Menus(undefined);
     model.Menus(JSON.parse(menus));//刷新菜单对象
     MenuFormValidate();//重新绑定验证方法
    },
MenuIndex: ko.observable(), //父级菜单索引
    isEditMenu: ko.observable(false), //是否是编辑菜单
    BottonIndex: ko.observable(-1), //编辑菜单的父级菜单索引
    SubBottonIndex: ko.observable(-1), //编辑菜单的子菜单索引
    Menu: ko.observable(),//编辑菜单时临时监控属性
    CopyMenu: ko.observable(),//复制的菜单对象
    Copy: function () { //复制
     if (model.Menu() != undefined) {
      var menu = JSON.stringify(model.Menu());
      model.CopyMenu(JSON.parse(menu));
      model.Menu(undefined);
     }
    },
    Paste: function () {//粘贴
     if (model.CopyMenu() != undefined) {
      var menu = JSON.parse(JSON.stringify(model.CopyMenu()));
      if (model.SubBottonIndex() !== -1 && menu.sub_button != undefined || (!model.isEditMenu() && model.MenuIndex() != undefined)) {
       delete menu.sub_button;
      }
      model.Menu(menu);
      MenuFormValidate();
     }
    },
    Up: function () {//向上移动
     var bottonIndex = model.BottonIndex();
     var subBottonIndex = model.SubBottonIndex();
     var newSubBottonIndex = subBottonIndex - 1;
     model.Menus().button[bottonIndex].sub_button[subBottonIndex] = model.Menus().button[bottonIndex].sub_button[newSubBottonIndex];
     model.Menus().button[bottonIndex].sub_button[newSubBottonIndex] = model.Menu();
     model.MenusReset();
     model.SubBottonIndex(newSubBottonIndex);
    },
    Down: function () {//向下移动
     var bottonIndex = model.BottonIndex();
     var subBottonIndex = model.SubBottonIndex();
     var newSubBottonIndex = subBottonIndex + 1;
     model.Menus().button[bottonIndex].sub_button[subBottonIndex] = model.Menus().button[bottonIndex].sub_button[newSubBottonIndex];
     model.Menus().button[bottonIndex].sub_button[newSubBottonIndex] = model.Menu();
     model.MenusReset();
     model.SubBottonIndex(newSubBottonIndex);
    },
    Left: function () {//向左移动
     var bottonIndex = model.BottonIndex();
     var subBottonIndex = model.SubBottonIndex();
     if (subBottonIndex === -1) {
      var newBottonIndex = bottonIndex - 1;
      model.Menus().button[bottonIndex] = model.Menus().button[newBottonIndex];
      model.Menus().button[newBottonIndex] = model.Menu();
      model.MenusReset();
      model.BottonIndex(newBottonIndex);
     }
    },
    Right: function () {//向右移动
     var bottonIndex = model.BottonIndex();
     var subBottonIndex = model.SubBottonIndex();
     if (subBottonIndex === -1) {
      var newBottonIndex = bottonIndex + 1;
      model.Menus().button[bottonIndex] = model.Menus().button[newBottonIndex];
      model.Menus().button[newBottonIndex] = model.Menu();
      model.MenusReset();
      model.BottonIndex(newBottonIndex);
     }
    },
    EditMenu: function (obj, bottonindex, subbottonindex) {//编辑菜单
     model.BottonIndex(bottonindex);
     model.SubBottonIndex(subbottonindex);
     model.isEditMenu(true);
     var data = JSON.stringify(obj);
     model.Menu(JSON.parse(data));
     MenuFormValidate();
    },
    AddMenu: function (index) {//添加菜单
     model.BottonIndex(-1);
     model.SubBottonIndex(-1);
     model.isEditMenu(false);
     model.MenuIndex(index);
     var menu = { type: "view", name: "", value: "" };
     model.Menu(menu);
     MenuFormValidate();
    },
    DeleteMenu: function () {//删除菜单
     $(model.Menus().button).each(function (index, item) {
      if (index === model.BottonIndex() && model.SubBottonIndex() === -1) {
       model.Menus().button.splice(index, 1);
      }
      if (item.sub_button instanceof Array) {
       $(item.sub_button).each(function (index1) {
        if (index === model.BottonIndex() && index1 === model.SubBottonIndex()) {
         item.sub_button.splice(index1, 1);
        }
       });
      }
     });
     model.Menu(undefined);
     model.MenuIndex(undefined);
     model.BottonIndex(-1);
     model.SubBottonIndex(-1);
     model.MenusReset();
    },
    CancelMenuSave: function () {//取消编辑,重置参数
     model.Menu(undefined);
     model.MenuIndex(undefined);
     model.BottonIndex(-1);
     model.SubBottonIndex(-1);
    },
    MenuSave: function () {//保存编辑的菜单
     if (!$("#MenuForm").data("validator").form()) {
      return;
     }
     if (model.isEditMenu()) {
      var menuIndex = model.BottonIndex();
      var subMenuIndex = model.SubBottonIndex();
      if (subMenuIndex === -1) {
       model.Menus().button[menuIndex] = model.Menu();
      } else {
       model.Menus().button[menuIndex].sub_button[subMenuIndex] = model.Menu();
      }
     } else {
      if (model.MenuIndex() != undefined) {
       if (model.Menus().button[model.MenuIndex()].sub_button == undefined) {
        model.Menus().button[model.MenuIndex()].sub_button = new Array();
       }
       model.Menus().button[model.MenuIndex()].sub_button.unshift(model.Menu());
      } else {
       model.Menus().button.push(model.Menu());
      }
     }
     model.Menu(undefined);
     model.MenuIndex(undefined);
     model.BottonIndex(-1);
     model.SubBottonIndex(-1);
     model.MenusReset();
    },

绑定好监控属性,生成菜单排版

<p class="panel-body" data-bind="with:Menus" id="pMenu" style="display: none;">
  <p style="height: 200px;" data-bind="foreach:newArray(3)">
   <p class="list-group col-xs-4 clearFill bn">
    <!--ko if:($parent.button.length>0 && $parent.button[$index()]!=undefined && $parent.button[$index()].sub_button!=undefined ) -->
    <!--ko foreach:newArray((4-$parent.button[$index()].sub_button.length)) -->
    <p class="list-group-item bn"></p>
    <!--/ko-->
    <!--ko if:$parent.button[$index()].sub_button.length<5 -->
    <p class="list-group-item" data-bind="click:function (){$root.AddMenu($index())}"><i class="fa fa-plus"></i>
    </p>
    <!--/ko-->
    <!--ko foreach:($parent.button[$index()].sub_button) -->
    <p class="list-group-item" data-bind="text:name,attr:{&#39;bottonIndex&#39;:$parent.value,&#39;subbottonIndex&#39;:$index()},click:function (){$root.EditMenu($data,$parent.value,$index())}"></p>
    <!--/ko-->
    <!--/ko -->
    <!--ko if: $parent.button[$index()]!=undefined && $parent.button[$index()].sub_button==undefined -->
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item" data-bind="click:function (){$root.AddMenu($index())}"><i class="fa fa-plus"></i>
    </p>
    <!--/ko-->
    <!--ko if: $parent.button[$index()]==undefined -->
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <!--/ko-->
   </p>
  </p>
  <!--ko foreach:button -->
  <p class="col-xs-4 list-group-item list-group-item-danger" data-bind="text:name,attr:{&#39;bottonindex&#39;:$index()},click:function (){$root.EditMenu($data,$index(),-1)}"></p>
  <!--/ko-->
  <!--ko if:button.length < 3 -->
  <p class="col-xs-4 list-group-item" data-bind="click:function (){$root.AddMenu();}"><i class="fa fa-plus"></i>
  </p>
  <!--/ko-->
  <p class="clearfix"></p>
  <p class="col-xs-12" style="border: 1px solid #EEEEEE; padding-top: 15px; margin-top: 15px;" data-bind="with:$root.Menu,visible:($root.Menu()!=undefined)">
   <form id="MenuForm" onsubmit="return false;">
    <p class="form-group col-xs-4">
     <input type="text" class="form-control" name="name" placeholder="请输入名称" data-bind="value:name">
    </p>
    <p class="form-group col-xs-4">
     <select class="form-control" onchange="$(&#39;#txtMenuButtonValue&#39;)
 .attr(&#39;placeholder&#39;, $(this).find(&#39;option:selected&#39;).attr(&#39;pl&#39;))" data-bind="value:type">
      <option value="view" pl="请输入Url">跳转URL</option>
      <option value="click" pl="请输入Key">点击推事件</option>
      <option value="scancode_push" pl="请输入Key">扫码推事件</option>
      <option value="scancode_waitmsg" pl="请输入Key">扫码推事件且弹出“消息接收中”提示框</option>
      <option value="pic_sysphoto" pl="请输入Key">弹出系统拍照发图</option>
      <option value="pic_photo_or_album" pl="请输入Key">弹出拍照或者相册发图</option>
      <option value="pic_weixin" pl="请输入Key"> 弹出微信相册发图器</option>
      <option value="location_select" pl="请输入Key">弹出地理位置选择器</option>
     </select>
    </p>
    <p class="form-group col-xs-8">
     <input type="text" id="txtMenuButtonValue" name="value" class="form-control" placeholder="请输入Url" data-bind="value:value">
    </p>
    <p class="form-group col-xs-12">
     <button type="submit" class="btn btn-primary" data-bind="click:$root.MenuSave">确定</button>
     <button type="submit" class="btn btn-danger" data-bind="visible:$root.isEditMenu,click:$root.DeleteMenu">删除</button>
     <button type="button" class="btn btn-default" title="上移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsUp(),click:$root.Up"><i class="fa fa-chevron-circle-up" aria-hidden="true"></i></button>
     <button type="button" class="btn btn-default" title="下移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsDown(),click:$root.Down"><i class="fa fa-chevron-circle-down" aria-hidden="true"></i></button>
     <button type="button" class="btn btn-default" title="左移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsLeft(),click:$root.Left"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></button>
     <button type="button" class="btn btn-default" title="右移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsRight(),click:$root.Right"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></button>
     <button type="button" class="btn btn-default" title="复制菜单" data-bind="visible:$root.isEditMenu(),click:$root.Copy">复制</button>
     <button type="button" class="btn btn-default" title="粘贴菜单" data-bind="click:$root.Paste">粘贴</button>
     <button type="submit" class="btn btn-default" data-bind="click:$root.CancelMenuSave">关闭</button>
    </p>
   </form>
  </p>
  <p class="clearfix"></p>
 </p>

最后增加菜单的查询函数及发布函数。因为编辑菜单方便,菜单对象和微信自定义菜单接口所需要的json格式不对应,所以在查询现有菜单和发布菜单时,需要对json数据进行一下格式变化。,             

 EditMenus: function (isQuery) {
     if (isQuery == undefined) {
      var menu = {};
      menu.button = new Array();
      model.Menus(menu);
     } else {
      var appId = model.AppId();
      var appSecret = model.AppSecret();
      var accessToken = model.AccessToken();
      var type = model.Type();
      var tokenType = model.TokenType();
      var corpId = model.CorpId();
      var permanentCode = model.PermanentCode();
      var agentId = model.AgentId();
      var suiteId = model.SuiteId();
      var suiteSecret = model.SuiteSecret();
      var suiteTicket = model.SuiteTicket();
      if (type === "1" && tokenType === "2") {
       if (appId == undefined || $.trim(appId).length === 0) {
        alert("请输入AppId");
        return;
       }
       if (appSecret == undefined || $.trim(appSecret).length === 0) {
        alert("请输入AppSecret");
        return;
       }
      } else if (type === "2" && tokenType === "2") {
       if (corpId == undefined || $.trim(corpId).length === 0) {
        alert("请输入CorpId");
        return;
       }
       if (permanentCode == undefined || $.trim(permanentCode).length === 0) {
        alert("请输入永久授权码");
        return;
       }
       if (agentId == undefined || $.trim(agentId).length === 0) {
        alert("请输入AgentId");
        return;
       }
       if (suiteId == undefined || $.trim(suiteId).length === 0) {
        alert("请输入SuiteId");
        return;
       }
       if (suiteSecret == undefined || $.trim(suiteSecret).length === 0) {
        alert("请输入SuiteSecret");
        return;
       }
       if (suiteTicket == undefined || $.trim(suiteTicket).length === 0) {
        alert("请输入SuiteTicket");
        return;
       }
      } else if (tokenType === "1") {
       if (accessToken == undefined || $.trim(accessToken).length === 0) {
        alert("请输入AccessToken");
        return;
       }
      }
      $("#btnQueryMenu").button("查询中...");
      $.ajax({
       url: "",
       datatype: "JSON",
       type: "POST",
       async: true,
       data: JSON.stringify({
        appId: appId, appSecret: appSecret, accessToken: accessToken, type: type, tokenType: tokenType, corpId: corpId, permanentCode: permanentCode, agentId: agentId,
        suiteId: suiteId, suiteSecret: suiteSecret, suiteTicket: suiteTicket
       }),
       contentType: "application/json; charset=UTF-8",
       success: function (obj) {
        $("#btnQueryMenu").button("reset");
        if (obj.Success) {
         var data = obj.Data;
         var menus = JSON.parse(data).menu;
         $(menus.button).each(function (index, item) {
          if (item.type === "view") {
           item.value = item.url;
           delete item.url;
          } else {
           item.value = item.key;
           delete item.key;
          }
          if (item.type == undefined) {
           item.type = "view";
           item.value = "";
          }
          if (item.sub_button instanceof Array) {
           $(item.sub_button).each(function (index1, item2) {
            if (item2.type === "view") {
             item2.value = item2.url;
             delete item2.url;
            } else {
             item2.value = item2.key;
             delete item2.key;
            }
           });
          }
         });
         model.Menu(undefined);
         model.MenuIndex(undefined);
         model.BottonIndex(-1);
         model.SubBottonIndex(-1);
         model.Menus(undefined);
         model.Menus(menus);
        } else {
         alert(obj.Messages);
        }
       },
       error: function (xmlHttpRequest, textStatus, errorThrown) {
        $("#btnQueryMenu").button("reset");
        console.error(errorThrown);
       }
      });
     }
    },
    SaveMenus: function () {
     var menus = JSON.parse(JSON.stringify(model.Menus()));
     $(menus.button).each(function (index, item) {
      if (item.type === "view") {
       item.url = item.value;
       delete item.value;
      } else {
       item.key = item.value;
       delete item.value;
      }
      if (item.sub_button instanceof Array) {
       $(item.sub_button).each(function (index1, item2) {
        if (item2.type === "view") {
         item2.url = item2.value;
         delete item2.value;
        } else {
         item2.key = item2.value;
         delete item2.value;
        }
       });
       if (item.sub_button.length > 0) {
        delete item.key;
        delete item.url;
        delete item.type;
       } else {
        delete item.sub_button;
       }
      }
     });
     console.log(JSON.stringify(menus));
     var appId = model.AppId();
     var appSecret = model.AppSecret();
     var accessToken = model.AccessToken();
     var type = model.Type();
     var tokenType = model.TokenType();
     var agentId = model.AgentId();
     var suiteId = model.SuiteId();
     var suiteSecret = model.SuiteSecret();
     var suiteTicket = model.SuiteTicket();
     if (type === "1" && tokenType === "2") {
      if (appId == undefined || $.trim(appId).length === 0) {
       alert("请输入AppId");
       return;
      }
      if (appSecret == undefined || $.trim(appSecret).length === 0) {
       alert("请输入AppSecret");
       return;
      }
     } else if (type === "2" && tokenType === "2") {
      if (agentId == undefined || $.trim(agentId).length === 0) {
       alert("请输入AgentId");
       return;
      }
      if (suiteId == undefined || $.trim(suiteId).length === 0) {
       alert("请输入SuiteId");
       return;
      }
      if (suiteSecret == undefined || $.trim(suiteSecret).length === 0) {
       alert("请输入SuiteSecret");
       return;
      }
      if (suiteTicket == undefined || $.trim(suiteTicket).length === 0) {
       alert("请输入SuiteTicket");
       return;
      }
     } else if (tokenType === "1") {
      if (accessToken == undefined || $.trim(accessToken).length === 0) {
       alert("请输入AccessToken");
       return;
      }
     }
     $("#btnSubmitMenu").button("发布中...");
     $.ajax({
      url: "",
      datatype: "JSON",
      type: "POST",
      async: true,
      data: JSON.stringify({
       appId: appId, appSecret: appSecret, accessToken: accessToken, type: type, tokenType: tokenType, agentId: agentId,
       suiteId: suiteId, suiteSecret: suiteSecret, suiteTicket: suiteTicket, menu: JSON.stringify(menus)
      }),
      contentType: "application/json; charset=UTF-8",
      success: function (obj) {
       $("#btnSubmitMenu").button("reset");
       if (obj.Success) {
        alert("发布成功");
       } else {
        alert(obj.Messages);
       }
      },
      error: function (xmlHttpRequest, textStatus, errorThrown) {
       $("#btnSubmitMenu").button("reset");
       console.error(errorThrown);
      }
     });
    }

 最终效果如下

【相关推荐】

1. ASP.NET免费视频教程

2. ASP.NET教程

3. 极客学院ASP.NET视频教程

4.  什么是ASP.NET MVC ?总结ASP.NET MVC

5. 详细介绍ASP.NET MVC--控制器(controller)

6. 详细介绍ASP.NET MVC--视图

7. 详细介绍ASP.NET MVC--路由

8. 深入了解ASP.NET MVC与WebForm的区别

Atas ialah kandungan terperinci 通过asp.net mvc开发微信自定义菜单编辑工具的代码示例. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
C# kod dalam .NET: Meneroka proses pengaturcaraanC# kod dalam .NET: Meneroka proses pengaturcaraanApr 12, 2025 am 12:02 AM

Proses pengaturcaraan C# dalam .NET termasuk langkah -langkah berikut: 1) Menulis C# Code, 2) Menyusun bahasa pertengahan (IL), dan 3) yang dilaksanakan oleh Runtime .NET (CLR). Kelebihan C# dalam .NET adalah sintaks moden, sistem jenis yang kuat dan integrasi yang ketat dengan Rangka Kerja .NET, sesuai untuk pelbagai senario pembangunan dari aplikasi desktop ke perkhidmatan web.

C# .NET: Meneroka Konsep Teras dan Asas PengaturcaraanC# .NET: Meneroka Konsep Teras dan Asas PengaturcaraanApr 10, 2025 am 09:32 AM

C# adalah bahasa pengaturcaraan yang berorientasikan objek moden yang dibangunkan oleh Microsoft dan sebagai sebahagian daripada Rangka Kerja .NET. 1.C# menyokong pengaturcaraan berorientasikan objek (OOP), termasuk enkapsulasi, warisan dan polimorfisme. 2. Pengaturcaraan Asynchronous dalam C# dilaksanakan melalui Async dan menunggu kata kunci untuk meningkatkan respons aplikasi. 3. Gunakan LINQ untuk memproses koleksi data dengan ringkas. 4. Kesilapan umum termasuk pengecualian rujukan null dan pengecualian indeks luar. Kemahiran penyahpepijatan termasuk menggunakan debugger dan pengendalian pengecualian. 5. Pengoptimuman Prestasi termasuk menggunakan StringBuilder dan mengelakkan pembungkusan yang tidak perlu dan unboxing.

Ujian C# .NET Aplikasi: Unit, Integrasi, dan Ujian Akhir ke AkhirUjian C# .NET Aplikasi: Unit, Integrasi, dan Ujian Akhir ke AkhirApr 09, 2025 am 12:04 AM

Strategi ujian untuk aplikasi C#. NET termasuk ujian unit, ujian integrasi, dan ujian akhir-ke-akhir. 1. Ujian unit memastikan bahawa unit minimum kod berfungsi secara bebas, menggunakan rangka kerja MSTest, Nunit atau Xunit. 2. Ujian Bersepadu Mengesahkan fungsi pelbagai unit yang digabungkan, data simulasi yang biasa digunakan dan perkhidmatan luaran. 3. Ujian akhir-ke-akhir mensimulasikan proses operasi lengkap pengguna, dan selenium biasanya digunakan untuk ujian automatik.

Advanced C# .NET Tutorial: Ace Wawancara Pemaju Kanan Anda SeterusnyaAdvanced C# .NET Tutorial: Ace Wawancara Pemaju Kanan Anda SeterusnyaApr 08, 2025 am 12:06 AM

Temu bual dengan pemaju kanan C# memerlukan menguasai pengetahuan teras seperti pengaturcaraan asynchronous, LINQ, dan prinsip kerja dalaman Rangka .NET. 1. Pengaturcaraan Asynchronous memudahkan operasi melalui async dan menunggu untuk meningkatkan respons aplikasi. 2.Linq mengendalikan data dalam gaya SQL dan perhatikan prestasi. 3. CLR kerangka bersih menguruskan ingatan, dan pengumpulan sampah perlu digunakan dengan berhati -hati.

C# .NET Soalan & Jawapan Wawancara: Tahap kepakaran andaC# .NET Soalan & Jawapan Wawancara: Tahap kepakaran andaApr 07, 2025 am 12:01 AM

C#.NET Soalan dan jawapan wawancara termasuk pengetahuan asas, konsep teras, dan penggunaan lanjutan. 1) Pengetahuan asas: C# adalah bahasa berorientasikan objek yang dibangunkan oleh Microsoft dan digunakan terutamanya dalam rangka .NET. 2) Konsep teras: Delegasi dan peristiwa membolehkan kaedah mengikat dinamik, dan LINQ menyediakan fungsi pertanyaan yang kuat. 3) Penggunaan Lanjutan: Pengaturcaraan Asynchronous meningkatkan respons, dan pokok ekspresi digunakan untuk pembinaan kod dinamik.

Membina Microservices dengan C# .NET: Panduan Praktikal untuk ArkitekMembina Microservices dengan C# .NET: Panduan Praktikal untuk ArkitekApr 06, 2025 am 12:08 AM

C#.NET adalah pilihan yang popular untuk membina microservices kerana ekosistem yang kuat dan sokongan yang kaya. 1) Buat RestfulAPi menggunakan ASP.Netcore untuk memproses penciptaan pesanan dan pertanyaan. 2) Gunakan GRPC untuk mencapai komunikasi yang cekap antara microservices, menentukan dan melaksanakan perkhidmatan pesanan. 3) Memudahkan penggunaan dan pengurusan melalui microservices kontena Docker.

C# .NET Keselamatan Amalan Terbaik: Mencegah Kelemahan BiasaC# .NET Keselamatan Amalan Terbaik: Mencegah Kelemahan BiasaApr 05, 2025 am 12:01 AM

Amalan terbaik keselamatan untuk C# dan .NET termasuk pengesahan input, pengekodan output, pengendalian pengecualian, serta pengesahan dan kebenaran. 1) Gunakan ungkapan biasa atau kaedah terbina dalam untuk mengesahkan input untuk mengelakkan data berniat jahat memasuki sistem. 2) Pengekodan output Untuk mencegah serangan XSS, gunakan kaedah httputility.htmlencode. 3) Pengendalian Pengecualian Menghindari kebocoran maklumat, ralat rekod tetapi tidak mengembalikan maklumat terperinci kepada pengguna. 4) Gunakan Asp.Netidentity dan kebenaran berasaskan tuntutan untuk melindungi aplikasi daripada akses yang tidak dibenarkan.

Dalam bahasa C: Apa maksudnyaDalam bahasa C: Apa maksudnyaApr 03, 2025 pm 07:24 PM

Makna kolon (':') dalam bahasa C: Penyataan bersyarat: Memisahkan ekspresi bersyarat dan pernyataan blok pernyataan pernyataan: Memisahkan permulaan, bersyarat dan tambahan ekspresi makro Definisi: Memisahkan nama makro dan nilai makro Single Line Comment: Mewakili kandungan dari kolon hingga akhir garis sebagai dimensi array komen: Tentukan dimensi array

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

VSCode Windows 64-bit Muat Turun

VSCode Windows 64-bit Muat Turun

Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft

mPDF

mPDF

mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

MantisBT

MantisBT

Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

Versi Mac WebStorm

Versi Mac WebStorm

Alat pembangunan JavaScript yang berguna

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Persekitaran pembangunan bersepadu PHP yang berkuasa