<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      angularjs和ajax的結(jié)合使用 (四)

      知道的朋友了解 我不是屬于講按部就班技術(shù)的那種人。什么xx入門 ,入門到精通,入門到入土。 其實(shí)非要嚴(yán)格說的話已經(jīng)跟angularjs 什么ajax 偏的有點(diǎn)遠(yuǎn)了,之所以還是叫這個(gè)名稱,因?yàn)槎紝儆趙eb應(yīng)用 ,叫這個(gè)名稱是一種延續(xù),其實(shí)這個(gè)系列持續(xù)了幾年了 是我自己從學(xué)習(xí)到一種適合我自己環(huán)境的特有應(yīng)用方式的一種總結(jié)。主題還是一個(gè):web應(yīng)用,往細(xì)了裝逼了說一種同時(shí)適合web 和winform 客戶端 獨(dú)到的 數(shù)據(jù)架構(gòu) 處理方式。當(dāng)然所有的都是基于以前的基礎(chǔ)之上的。

      主題:一種同時(shí)適合web 和winform 客戶端 獨(dú)特的 數(shù)據(jù)架構(gòu) 處理方式

      后臺(tái)API權(quán)限控制

      首先是后臺(tái)的接口 ,使用webapi的方式 返回 json 數(shù)據(jù) 。當(dāng)然這里有一個(gè)技巧 , 也就是權(quán)限控制。眾所周知 http 有一種 方式 可以把授權(quán)放在header 里。后臺(tái)驗(yàn)證 ,每個(gè)接口都要權(quán)限符合才能 請(qǐng)求到數(shù)據(jù)。都知道asp.net MVC有filter 可以用來先進(jìn)行過濾 ,都在Java做web后臺(tái)滿大街 的年代 我們還在用中古時(shí)期的ASP.Net MVC。首先我們對(duì)后臺(tái)代碼和web部分進(jìn)行了分層,數(shù)據(jù)訪問對(duì)象為Entity ,controllers 為各個(gè)請(qǐng)求的API web的和winform的在一起,我們依舊使用了簡(jiǎn)單的三層架構(gòu),xxxLogic.cs 其實(shí)是實(shí)際的業(yè)務(wù)邏輯代碼:

       

       

      所有的是基于WebAPI形式的 老套路在初始化時(shí)進(jìn)行 router注冊(cè) 以便讓請(qǐng)求映射到對(duì)應(yīng)的controller 不用多說了,還有是asp.net MVC是可以配置返回?cái)?shù)據(jù)格式為xml 或者json的。

       1 public class Global : System.Web.HttpApplication
       2 {
       3 
       4     protected void Application_Start(object sender, EventArgs e)
       5     {
       6         
       7         AreaRegistration.RegisterAllAreas();
       8         //GlobalConfiguration.Configuration.ParameterBindingRules.
       9         //    Insert(0,SimplePostVariableParameterBinding.HookupParameterBinding);
      10         WebApiConfig.Register(GlobalConfiguration.Configuration);
      11         FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
      12         RouteConfig.RegisterRoutes(RouteTable.Routes);
      13     }
      14 
      15     protected void Session_Start(object sender, EventArgs e)
      16     {
      17 
      18     }
      19     protected void Application_BeginRequest(object sender, EventArgs e)
      20     {
      21         if (Context.Request.FilePath == "/") Context.RewritePath("Default.aspx");
      22     }
      23 
      24     
      25 
      26     public override void Init()
      27     {
      28         PostAuthenticateRequest += WebApiApplication_PostAuthenticateRequest;
      29 
      30         base.Init();
      31     }
      32     void WebApiApplication_PostAuthenticateRequest(object sender, EventArgs e)
      33     {
      34         HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
      35     }
      36 }
       1 public class RouteConfig
       2 {
       3     public static void RegisterRoutes(RouteCollection routes)
       4     {
       5         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
       6         
       7         routes.MapRoute(
       8             name: "Default",
       9             url: "{controller}/{action}/{id}",
      10             defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
      11         );
      12     }
      13 }
       1 public static class WebApiConfig
       2 {
       3     public static void Register(HttpConfiguration config)
       4     {
       5         System.Web.Mvc.ValueProviderFactories.Factories.Add(new System.Web.Mvc.JsonValueProviderFactory());
       6         //下面這句務(wù)必加上 否則就只能在IE下才能得到正確的json數(shù)據(jù) 
       7         //必須要添加http.formating 那個(gè)dll的引用
       8         GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
       9         //GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
      10         config.Routes.MapHttpRoute(
      11             name: "DefaultApi",
      12             routeTemplate: "api/{controller}/{action}/{id}",
      13             defaults: new { controller = "Home", action = "Index", id = RouteParameter.Optional }//new { id = RouteParameter.Optional }
      14         );
      15 
      16     }
      17 }

      來看下我們的后臺(tái)進(jìn)行權(quán)限控制的代碼,我們并未進(jìn)行復(fù)雜的權(quán)限控制 僅僅只是判斷登錄:

       1 public class Power : System.Web.Http.Filters.ActionFilterAttribute
       2 {
       3     public Power(string actioinName)
       4     {
       5 
       6     }
       7     public override void OnActionExecuting(HttpActionContext actionContext)
       8     {
       9         HttpRequest request = HttpContext.Current.Request;
      10         string username = request.Headers["username"];
      11         string password = request.Headers["password"];
      12 
      13 
      14         LicWebUtil util = new LicWebUtil();
      15         var loginuser = util.loginNormal(username, password);
      16         if (loginuser==null)
      17         {
      18             throw new Exception("未登錄啊");
      19         }
      20     }
      21 }

      數(shù)據(jù)處理

      然后是數(shù)據(jù)處理,我們?cè)诜?wù)端構(gòu)建了統(tǒng)一的數(shù)據(jù)格式APIResult:

      1 public class APIResult
      2 {
      3     public bool Success { get; set; }
      4     public object Data { get; set; }
      5 
      6     public string Msg { get; set; }
      7 
      8 }

       

      web端的 通用 js請(qǐng)求 ,get和post 注意promise 應(yīng)用的機(jī)巧 ,以及提交時(shí)在登錄成功了的情況下 會(huì)自動(dòng)往header里加權(quán)限 。

       1 var app = angular.module("scpSite", ["ui.router"]);
       2 
       3 //注入一個(gè)util 工具類
       4 app.service("Util", function ($http, $rootScope, $q, $compile) {
       5 
       6     var boxPromise = function (promise) {
       7         var myPromise = {
       8             prom: promise,
       9             then: function (fun1, fun2) {
      10                 promise.then(function (response) {
      11                     //response.status==200// response.status==500 這里就不使用這種方式判斷了
      12                     if (response && response.data && response.data.Success) {
      13                         fun1(response);
      14                     }
      15                     else {
      16                         //服務(wù)端有正常的錯(cuò)誤消息返回
      17                         if (response && response.data && response.data.Success == false) {
      18                             alert("獲取數(shù)據(jù)失敗:" + response.data.Message);
      19                         }
      20                             //throw exception 500錯(cuò)誤
      21                         else {
      22                             alert("獲取數(shù)據(jù)失敗:" + response.data.ExceptionMessage);
      23                         }
      24 
      25                         if (fun2 != undefined)
      26                             fun2(response);
      27                     }
      28                 }, function () {//在剛httpget的時(shí)候可以 而在此處根本就不會(huì)執(zhí)行此函數(shù) 
      29                 });
      30             }
      31         };
      32         return myPromise;
      33     };
      34 
      35     var _this = {
      36         get: function (path, _params) {
      37             var promise;
      38             if (_params != undefined && _params != null) {
      39                 promise = $http.get(path, { headers: { username: $rootScope.username, password: $rootScope.password }, params: _params }).then(function (response) {
      40                     return response;
      41                 }, function (response) {
      42                     return response;
      43                 });
      44             } else {
      45                 promise = $http.get(path, { headers: { username: $rootScope.username, password: $rootScope.password } }).then(function (response) {
      46                     return response;
      47                 }, function (response) {
      48                     return response;
      49                 });
      50             }
      51             return boxPromise(promise);
      52         },
      53         post: function (url, data) {
      54             var promise;
      55             if (data != undefined && data != null) {
      56                 promise = $http.post(url,data , { headers: { username: $rootScope.username, password: $rootScope.password }}).then(function (response) {
      57                     return response;
      58                 }, function (response) {
      59                     return response;
      60                 });
      61             } else {
      62                 promise = $http.post(url, { headers: { username: $rootScope.username, password: $rootScope.password } }).then(function (response) {
      63                     return response;
      64                 }, function (response) {
      65                     return response;
      66                 });
      67             }
      68             return boxPromise(promise);
      69         }
      70 
      71     }
      72 
      73     return _this;
      74 
      75 });

      然后是登錄 ,登錄成功了 angularjs 全局變量就會(huì)有用戶信息 ,提交時(shí)post就會(huì)自動(dòng)往權(quán)限里加。結(jié)合上面的一起運(yùn)作 ,體會(huì)一下這樣設(shè)計(jì) 以及聯(lián)動(dòng)運(yùn)作的精妙之處,并且如果服務(wù)端有錯(cuò)誤 在post之初就會(huì)自動(dòng)報(bào)出錯(cuò)誤 并且利用promise的機(jī)制 自動(dòng)阻斷 不讓執(zhí)行進(jìn)程傳到下層 不讓邏輯往后走,如果數(shù)據(jù)成功 則會(huì)自動(dòng)調(diào)用下層promise的數(shù)據(jù)展現(xiàn)操作進(jìn)行頁面渲染,這樣來達(dá)到規(guī)范化:

       1 app.controller("MainController", function ($rootScope, $scope, $rootScope, $stateParams, $state, Util) {
       2 
       3     $rootScope.loginok = false;
       4 
       5     $scope.username = "";
       6     $scope.password = "";
       7 
       8     $rootScope.username = "";
       9     $rootScope.password = "";
      10 
      11     //登錄測(cè)試 否則彈出登錄對(duì)話框
      12     $scope.loginTest = function () {
      13 
      14         if ($scope.loginok == false) {
      15             $('#myModal').modal({ backdrop: 'static', keyboard: false, show: true });
      16         }
      17     }
      18 
      19     $scope.login = function () {
      20 
      21         Util.get("/api/Util/login", { username: $scope.username, password: $scope.password }).then(function (res) {
      22             if (res.data.Data==null||res.data.Data == "") {
      23                 alert("登錄失敗");
      24             }
      25             else {
      26                 alert("登錄成功");
      27                 $rootScope.username = $scope.username;
      28                 $rootScope.password = $scope.password;
      29                 $rootScope.loginok = true;
      30 
      31 
      32                 $('#myModal').modal('hide');
      33             }
      34         }, function (res) {
      35             alert("登錄遇到錯(cuò)誤");
      36         });
      37 
      38 
      39     }
      40 
      41     $scope.copyrightEndYear = "2018";
      42     $scope.GetCopyrightEndYear = function () {
      43         Util.get("/api/Util/GetCopyrightEndYear").then(function (res) {
      44             $scope.copyrightEndYear = res.data.Data;
      45         });
      46     }
      47     $scope.GetCopyrightEndYear();
      48 });

      如果登錄成功后那么后續(xù)就是簡(jiǎn)單的平鋪直述的調(diào)用了,下面是一個(gè)簡(jiǎn)單的示例。

      1 app.controller("DefaultController", function ($scope, Util) {
      2     $scope.newsList = [];
      3     $scope.inititalData = function () {
      4         Util.get("/api/CMS/GetContentByCategory", { category: "新聞中心", top: 5, getContent: false }).then(function (res) {
      5             $scope.newsList = res.data.Data;
      6         });
      7     }
      8     $scope.inititalData();
      9 });

      看下我們的使用效果

       

       不用想當(dāng)然的在客戶端調(diào)試把mask去掉以為就可用了哈,我們是做了完善的后臺(tái)校驗(yàn)機(jī)制的。

       

      同一接口應(yīng)用于winform端

       看,跟上面相結(jié)合的統(tǒng)一處理 WebAPI promise post  的結(jié)合應(yīng)用正是這個(gè)框架的優(yōu)雅之處 ,并且 APIResult格式 是統(tǒng)一的  在winform客戶端只要實(shí)現(xiàn)一個(gè)json解析 ,同一個(gè)接口或者業(yè)務(wù)邏輯就可應(yīng)用于Windows客戶端了 就這樣簡(jiǎn)單的就達(dá)到了同步。關(guān)于winform 接口 結(jié)果數(shù)據(jù)的處理,很簡(jiǎn)單 我們構(gòu)建一個(gè)跟json一致c#的類  反序列化即可。這是winform 構(gòu)造出的請(qǐng)求 和其他代碼,注意我們是用上面同一規(guī)格APIResult 來進(jìn)行json解析的,通過httprequest 請(qǐng)求 ,原先設(shè)計(jì)的我們有廣告 也就是圖片 還有文本。那么應(yīng)該怎么處理呢? 不是有泛型嗎? 看我的:注意泛型的應(yīng)用 ,如果是img則轉(zhuǎn)而使用stream解析,普通的則使用APIResult 解析出文本。

       1 public static T DownloadSomething<T>(string url,string appendUrl,Dictionary<string,string> pars)
       2 {
       3     try
       4     {
       5         if (string.IsNullOrEmpty(appendUrl) == false)
       6         {
       7             url += appendUrl;
       8         }
       9 
      10         if (pars != null)
      11         {
      12             var enumer = pars.GetEnumerator();
      13             int parIndex = 0;
      14             while (enumer.MoveNext())
      15             {
      16                 if (parIndex == 0)
      17                 {
      18                     url += string.Format("?{0}={1}", enumer.Current.Key, enumer.Current.Value);
      19                 }
      20                 else
      21                 {
      22                     url += string.Format("&{0}={1}", enumer.Current.Key, enumer.Current.Value);
      23                 }
      24                 parIndex++;
      25             }
      26         }
      27 
      28         HttpWebRequest rq = (HttpWebRequest)WebRequest.Create(url);
      29         rq.Headers["Accept-Encoding"] = "utf-8";
      30 
      31         if (WriterRuntime.loginUser != null && string.IsNullOrEmpty(WriterRuntime.loginUser.UserNameOrHardwareID) == false)
      32         {
      33             rq.Headers["username"] = WriterRuntime.loginUser.UserNameOrHardwareID;
      34             rq.Headers["password"] = WriterRuntime.loginUser.Password;
      35         }
      36         rq.Method = "GET";
      37         rq.Timeout = 10000;//2秒超時(shí)
      38         T retData = default(T);
      39 
      40         HttpWebResponse rc = (HttpWebResponse)rq.GetResponse();
      41         Stream stream = rc.GetResponseStream();
      42         StreamReader sr = new StreamReader(stream, Encoding.UTF8);
      43 
      44 
      45         if (typeof(T) == typeof(Image))
      46         {
      47             retData = (T)(object)Image.FromStream(stream);
      48         }
      49         else
      50         {
      51             APIResult apiResult = JsonConvert.DeserializeObject<APIResult>(sr.ReadToEnd());
      52 
      53             if (apiResult.Data != null)
      54             {
      55                 if ((typeof(T) == typeof(string)))
      56                 {
      57                     retData = (T)(object)apiResult.Data;
      58                 }
      59                 else if ((typeof(T) == typeof(Int64)))
      60                 {
      61                     retData = (T)(object)apiResult.Data;
      62                 }
      63                 else if((typeof(T) == typeof(bool))){
      64                     retData = (T)(object)apiResult.Data;
      65                 }
      66                 else
      67                 {
      68                     retData = ((Newtonsoft.Json.Linq.JObject)apiResult.Data).ToObject<T>();
      69                 }
      70 
      71             }
      72         }
      73 
      74         sr.Close();
      75         rc.Close();
      76 
      77         if (typeof(T) == typeof(string))
      78         {
      79             return retData;
      80         }
      81         else if (typeof(T) == typeof(Image))
      82         {
      83             return retData;
      84         }
      85         else
      86         {
      87             return retData;
      88         }
      89 
      90     }
      91     catch (Exception ex)
      92     {
      93         MessageBox.Show("與服務(wù)器連接失敗");
      94         Application.Exit();
      95     }
      96     return default(T);
      97 }

       

      還有,我們的客戶端是支持升級(jí)的,固定的連接上服務(wù)器后先進(jìn)性API版本校驗(yàn) ,如果校驗(yàn)失敗 會(huì)強(qiáng)迫客戶端進(jìn)行版本更新。強(qiáng)不強(qiáng)迫客戶端更新的決定權(quán)在我們 只要把服務(wù)端的ver接口數(shù)字調(diào)高 就可以把低于某版本的客戶端淘汰掉了。看資本的力量如此強(qiáng)大 ,這不就像手機(jī)上的某某xxAPP嗎 其實(shí)啥實(shí)質(zhì)功能都沒更新 ,更新了一堆的廣告。

       1 private void LoginForm_Load(object sender, EventArgs e)
       2 {
       3 
       4     //先進(jìn)行聯(lián)網(wǎng)和版本檢測(cè) 失敗則退出
       5     Int64 serverVer = USBKeyWriterUtil.DownloadSomething<Int64>(WriterRuntime.apiUrl, "Util/ClientAPI_Ver", null);
       6     if (serverVer > WriterRuntime.ver)
       7     {
       8         USBKeyWriter.UI.Upgrade uDlg = new USBKeyWriter.UI.Upgrade();
       9         uDlg.ShowDialog(this);
      10         return;
      11     }
      12     Process[] app = Process.GetProcessesByName("NewScp");
      13     if (app.Length > 0)
      14     {
      15         MessageBox.Show("請(qǐng)先退出Dicom打印服務(wù)軟件,再運(yùn)行此授權(quán)機(jī)程序。");//請(qǐng)先退出Dicom打印服務(wù)軟件(任務(wù)管理器NewScp進(jìn)程)再運(yùn)行此授權(quán)機(jī)程序
      16         Application.Exit();
      17         return;
      18     }
      19 
      20     //初始化runtime
      21     rt = WriterRuntime.GetInstance();
      22     rt.Initial();
      23 
      24     string deviceUserName = USBKeyWriterUtil.getDefaultLoginId();
      25     if (string.IsNullOrEmpty(deviceUserName))
      26     {
      27         tbxuname.Text = "admin";
      28     }
      29     else
      30     {
      31         tbxuname.Text = deviceUserName;
      32     }
      33 }

       

       

       

      好了 全部 結(jié)束 ,感謝各位看官觀賞,周末愉快。

       

      posted @ 2022-11-06 15:57  assassinx  閱讀(237)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 蜜芽久久人人超碰爱香蕉| 乱人伦人妻中文字幕不卡| 国产毛片三区二区一区| 国产精品福利中文字幕| 无码中文字幕av免费放| 老熟女重囗味hdxx69| 国产福利片一区二区三区| 黄床大片免费30分钟国产精品| a级黑人大硬长爽猛出猛进| 长腿校花无力呻吟娇喘| 亚洲高潮喷水无码AV电影| 久久a级片| 五月婷婷久久中文字幕| 国产粉嫩学生高清专区麻豆| 亚洲一区二区经典在线播放| 2021国产精品视频网站| 日本一卡2卡3卡四卡精品网站| 亚洲国产色一区二区三区| 亚洲中文字幕日产无码成人片| 亚洲婷婷综合色高清在线| 88国产精品视频一区二区三区| 精品少妇av蜜臀av| 麻豆久久久9性大片| 99热这里只有成人精品国产 | 久久精品国产蜜臀av| 97欧美精品系列一区二区| 蜜臀av色欲a片无码精品一区| 国产九九视频一区二区三区| 麻豆国产传媒精品视频| 久久av无码精品人妻出轨| 国产福利视频区一区二区| 亚洲一区二区三区日本久久| 欧洲无码一区二区三区在线观看| 国产丰满乱子伦无码专区| 精品久久久久国产免费| 又黄又爽又色的少妇毛片| 日韩精品视频一二三四区| а天堂中文最新一区二区三区 | 九九九国产精品成人免费视频| 亚洲欧美日韩成人综合一区 | 国产无遮挡猛进猛出免费软件|