搜尋
首頁後端開發C#.Net教程Asp.net(二)業務處理介面專案(Web Api)

Asp.net(二)業務處理介面專案(Web Api)

Apr 04, 2017 pm 03:32 PM
asp.netweb api介面

簡介

Api作為業務邏輯提供方,承載了專案的核心邏輯,因而具有相對高的邏輯複雜性。在這樣的前提下如何簡化程式碼編寫,如何規範統一書寫風格和邏輯規範,如何提升程式碼的維護性和擴展性。專案的搭建的高內聚低耦合變得重要。
範例的是企業級項目,框架圖如下

Asp.net(二)業務處理介面專案(Web Api)

#api層.jpg

Security:重寫了Http請求(Override DelegatingHandler),在請求的切面進行合法性判斷,順便進行簽名要求的預處理。
Client:定義了統一的介面呼叫方式共呼叫端使用,簡化及統一了介面使用。
Ctrl層:作為服務的直接提供方,在伺服器上直接提供類似RestFul風格的介面(感覺嚴格的RestFul風格,需要有完整的領域模型##驅動# ,實際上的情況總是不盡人意,領域抽象能力不夠。層:作為業務模型層,提供業務邏輯的實際操作。使用統一的實體模型,並聯絡Ibatis上,進行資料操作。 具體的程式碼結構如下圖:


Api-UML.jpg

以下是各個模組的詳細介紹和程式碼範例:Asp.net(二)業務處理介面專案(Web Api)
Entity library專案程式碼範例

專案架構如下圖:

##entity.jpg

#Do

mainAsp.net(二)業務處理介面專案(Web Api)模組,作為實體模型,簡易程式碼如下

public class User
{
      public int Id { get; set; }
      public string NickName { get; set; }
      public string Avatar { get; set; }
}
Request,請求結構模型,利用了泛型接口,將請求類別和返回類別聯繫,起到了控制倒轉的作用。

public abstract class AbstractRequest
{
    public bool ValidateParameters()
    {
        //公用方法示例,验证参数合法性
    }
}
   public interface IRequest<t> where T:AbstractResponse
    {
        //获取接口名称
        string GetApiName();

        //获取接口编码
        string GetApiCode();
    }
//获取User信息的请求结构定义
  public class GetUserRequest:AbstractRequest,IRequest<getuserresponse>
    {
        public int Id { get; set; }

        public string GetApiName()
        {
            return "User.GetUserDetail";
        }

        public string GetApiCode()
        {
            return "User001";
        }
    }</getuserresponse></t>
Response模組,作為請求的回傳類型,定義統一的回傳結構,以便於消費者進行一致性回傳碼判斷處理。

public abstract class AbstractResponse
    {
        //返回码
        public int Code { get; set; }
        //报错信息
        public string Message { get; set; }
    }
 public class GetUserResponse:AbstractResponse
    {
        public User User { get; set; }
    }
Service專案程式碼範例專案結構如下圖:

service.jpg

程式碼範例:

 public interface IUserService
    {
        GetUserResponse GetUser(int id);
    }
 public class BaseService
    {
        //protected SqlInstance sqlInstance;
        public BaseService()
        {
            //sqlInstance=new SqlInstance(); //实例化数据库连接
            //...
        }
        //...
    }
  public class UserService:BaseService,IUserService
    {
        public GetUserResponse GetUser(int id)
        {
            //链接数据库获取数据
            //...
            throw new NotImplementedException();
        }
    }
Asp.net(二)業務處理介面專案(Web Api)Security
類別庫程式碼範例

類別庫只是處理了

安全性

性問題,在api請求入口處新增上權限判斷。使用重寫Http請求的方式。
程式碼範例
public class MyHandler : DelegatingHandler
    {
        protected async override Task<httpresponsemessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            IEnumerable<string> keyEnumerable;
            var t1 = request.Headers.TryGetValues("key", out keyEnumerable);
            var key = keyEnumerable.FirstOrDefault();
            if (!true)//验证类似于token的权限
            {
                return await Task.Factory.StartNew<httpresponsemessage>(
                            () => new HttpResponseMessage(HttpStatusCode.Forbidden)
                            {
                                Content = new StringContent("error message")
                            });
            }
            //如果有signature,判断,并加结果标志,没有的话,清除signature相关信息,防止伪造。
            //.....
            return await base.SendAsync(request, cancellationToken);
        }
    }</httpresponsemessage></string></httpresponsemessage>
抽象化出來的權限判斷,可直接呼叫到webapi端,加入到
路由

設定程式碼中。 WebApi專案範例

作為介面的實際定義,webapi定義了介面檔案的實際規則,並做出對應的

安全管理及介面的權限控制。學習微信的權限控制,大概確定了幾種介面:

#介面權限.png

這些權限的判斷都會放在了Security做了集中管理。介面定義只需要在對應的邏輯上使用判斷合法性即可。 Asp.net(二)業務處理介面專案(Web Api)程式碼範例:

public class UserController : ApiController
    {
        private IUserService userService;

        public UserController()
        {
            userService=new UserService();
        }

        [Signature]//安全签名过滤器判断
        [HttpPost]
        public GetUserResponse GetUser(GetUserRequest request)
        {
            //参数判断,安全性判断等等
            var ret = userService.GetUser(request.Id);
            return ret;
        }

    }
以上是一個獲取用戶資訊的範例接口,而作為接口入口的路由配置,則需要對請求的合法性進行判斷,路由配置碼如下:

public static void Register(HttpConfiguration config)
{
            // Web API configuration and services
            // Configure Web API to use only bearer token authentication.
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}",
                defaults: new { id = RouteParameter.Optional }
            );
            //添加的代码,添加http请求的入口处理
            config.MessageHandlers.Add(new MyHandler());
}
Client類別庫程式碼範例


Client類別庫定義了介面呼叫的公共方法。
1、利用泛型接口,將請求類別和返回類別進行了封裝,簡化調用的程式碼書寫。

2、並使得消費者呼叫介面需要透過代理類,避開了跨域的問題。

3、消費者的呼叫都同意使用統一類別庫,是的日誌的處理統一,傳回的錯誤也可以一致化定義。

程式碼範例如下:
 public interface IClient
 {
     T Execute<t>(IRequest<t> request) where T : AbstractResponse;
 }

public class DefaultClient:IClient
    {
        private readonly string appKey;
        private readonly string appSecret;
        private readonly string baseUrl = "http://localhost:16469/api/";
        private readonly bool isNeedLogFile = false;
        private readonly LogFile logFile;
        public static readonly string SecureHeaderAppKey = "secure_head_appkey";
        public static readonly string SecureHeaderSignature = "secure_head_signature";

        public DefaultClient()
        {
            baseUrl = ConfigurationManager.AppSettings["service_base_url"];
            appKey = ConfigurationManager.AppSettings["app_key"];
            appSecret = ConfigurationManager.AppSettings["app_secret"];
            isNeedLogFile = "1".Equals(ConfigurationManager.AppSettings["client_log_file"]);
            logFile = new LogFile("client_log_path");
            logFile.SubPath = appKey;
        }

        public DefaultClient(string serviceBase, string code, string key)
        {
            baseUrl = serviceBase;
            appKey = code;
            appSecret = key;
        }
        public T Execute<t>(IRequest<t> request) where T : AbstractResponse
        {
            var webRequest = (HttpWebRequest)WebRequest.Create(baseUrl + request.GetApiName());
            webRequest.Method = "POST";

            string reqJson;
            string sign;
            using (Stream rs = webRequest.GetRequestStream())
            {
                reqJson = JsonConvert.SerializeObject(request);

                byte[] reqBytes = Encoding.UTF8.GetBytes(reqJson);
                rs.Write(reqBytes, 0, reqBytes.Length);
                rs.Close();
            }

            webRequest.ContentType = "application/json";
            webRequest.Headers.Add(SecureHeaderAppKey, appKey);
            sign = ComputeHash(appKey, appSecret, reqJson);
            webRequest.Headers.Add(SecureHeaderSignature, sign);

            //记录日志
            if (isNeedLogFile)
            {
                logFile.Log(string.Format("[{0}] 请求内容: {1}", request.GetApiCode(), reqJson));
                logFile.Log(string.Format("[{0}] 请求签名: {1}", request.GetApiCode(), sign));
            }

            try
            {
                using (var resp = (HttpWebResponse)webRequest.GetResponse())
                {
                    try
                    {
                        Stream respStream = resp.GetResponseStream();

                        if (respStream == null)
                        {
                            throw new WebException("GetResponseStream returned null");
                        }
                        var streamReader = new StreamReader(respStream);
                        string respStr = streamReader.ReadToEnd();
                        //记录日志
                        if (isNeedLogFile)
                        {
                            logFile.Log(string.Format("[{0}] 响应内容: {1}", request.GetApiCode(), respStr));
                        }
                        return JsonConvert.DeserializeObject<t>(respStr);
                    }
                    catch (Exception e)
                    {
                        //记录日志
                        if (isNeedLogFile)
                        {
                            logFile.Log(string.Format("[{0}] 响应错误: {1}", request.GetApiCode(), e.Message));
                        }
                        throw new ApplicationException(e.Message, e);
                    }
                }
            }
            catch (WebException e)
            {
                var errMsg = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
                //记录日志
                if (isNeedLogFile)
                {
                    logFile.Log(string.Format("[{0}] 请求错误: {1}", request.GetApiCode(), errMsg));
                }
                throw new APIServiceException(errMsg);
            }
        }
        private string ComputeHash(string key, string secret, string body)
        {
            return
                Convert.ToBase64String(
                    SHA1.Create().ComputeHash(Encoding.Default.GetBytes(string.Concat(key, secret, body.Trim()))));
        }
    }</t></t></t></t></t>

以上就是Api项目端的各个核心环节的详细介绍。
接下来会对调用端即前端进行简单的介绍。Asp.net(三)Web端展示

以上是Asp.net(二)業務處理介面專案(Web Api)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
將C#.NET應用程序部署到Azure/AWS:逐步指南將C#.NET應用程序部署到Azure/AWS:逐步指南Apr 23, 2025 am 12:06 AM

如何將C#.NET應用部署到Azure或AWS?答案是使用AzureAppService和AWSElasticBeanstalk。 1.在Azure上,使用AzureAppService和AzurePipelines自動化部署。 2.在AWS上,使用AmazonElasticBeanstalk和AWSLambda實現部署和無服務器計算。

C#.NET:強大的編程語言簡介C#.NET:強大的編程語言簡介Apr 22, 2025 am 12:04 AM

C#和.NET的結合為開發者提供了強大的編程環境。 1)C#支持多態性和異步編程,2).NET提供跨平台能力和並發處理機制,這使得它們在桌面、Web和移動應用開發中廣泛應用。

.NET框架與C#:解碼術語.NET框架與C#:解碼術語Apr 21, 2025 am 12:05 AM

.NETFramework是一個軟件框架,C#是一種編程語言。 1..NETFramework提供庫和服務,支持桌面、Web和移動應用開發。 2.C#設計用於.NETFramework,支持現代編程功能。 3..NETFramework通過CLR管理代碼執行,C#代碼編譯成IL後由CLR運行。 4.使用.NETFramework可快速開發應用,C#提供如LINQ的高級功能。 5.常見錯誤包括類型轉換和異步編程死鎖,調試需用VisualStudio工具。

揭開c#.net的神秘面紗:初學者的概述揭開c#.net的神秘面紗:初學者的概述Apr 20, 2025 am 12:11 AM

C#是一種由微軟開發的現代、面向對象的編程語言,.NET是微軟提供的開發框架。 C#結合了C 的性能和Java的簡潔性,適用於構建各種應用程序。 .NET框架支持多種語言,提供垃圾回收機制,簡化內存管理。

C#和.NET運行時:它們如何一起工作C#和.NET運行時:它們如何一起工作Apr 19, 2025 am 12:04 AM

C#和.NET運行時緊密合作,賦予開發者高效、強大且跨平台的開發能力。 1)C#是一種類型安全且面向對象的編程語言,旨在與.NET框架無縫集成。 2).NET運行時管理C#代碼的執行,提供垃圾回收、類型安全等服務,確保高效和跨平台運行。

C#.NET開發:入門的初學者指南C#.NET開發:入門的初學者指南Apr 18, 2025 am 12:17 AM

要開始C#.NET開發,你需要:1.了解C#的基礎知識和.NET框架的核心概念;2.掌握變量、數據類型、控制結構、函數和類的基本概念;3.學習C#的高級特性,如LINQ和異步編程;4.熟悉常見錯誤的調試技巧和性能優化方法。通過這些步驟,你可以逐步深入C#.NET的世界,並編寫高效的應用程序。

c#和.net:了解兩者之間的關係c#和.net:了解兩者之間的關係Apr 17, 2025 am 12:07 AM

C#和.NET的關係是密不可分的,但它們不是一回事。 C#是一門編程語言,而.NET是一個開發平台。 C#用於編寫代碼,編譯成.NET的中間語言(IL),由.NET運行時(CLR)執行。

c#.net的持續相關性:查看當前用法c#.net的持續相關性:查看當前用法Apr 16, 2025 am 12:07 AM

C#.NET依然重要,因為它提供了強大的工具和庫,支持多種應用開發。 1)C#結合.NET框架,使開發高效便捷。 2)C#的類型安全和垃圾回收機制增強了其優勢。 3).NET提供跨平台運行環境和豐富的API,提升了開發靈活性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版