ASP. NET (ii) Business Processing Interface project (Web API)

Source: Internet
Author: User

Brief introduction

As a business logic provider, the API carries the core logic of the project and thus has a relatively high logical complexity. How to simplify the code writing, how to standardize the unified writing style and the logic specification, how to improve the maintainability and extensibility of the code. High cohesion and low coupling of the construction of the project becomes important.
The example is an enterprise project, as shown in the framework below


API layer. jpg

Security: Overrides the HTTP request (override Delegatinghandler) to make a legitimate judgment on the requested slice, and by the way, the preprocessing of the signature requirement.
Client: Defines a unified interface invocation method, which simplifies and unifies the interface usage.
CTRL layer: As the direct provider of the service, directly on the server to provide similar to the restful style of the interface (feel strict restful style, need to have a complete domain model-driven, in fact, the situation is always not satisfactory, the domain abstraction ability is not enough. ), get request data, invoke filter filter on demand, further judge, call
Model layer: As the business model layer, provides the actual operation of the business logic. Use a unified entity model, and contact the Ibatis for data manipulation.
The specific code structure is as follows:


Api-uml.jpg

The following are detailed descriptions and code examples for each module:

Entity Library Project code example

Project structure such as:


Entity.jpg

Domain module, as the entity model, the simple code is as follows

public class user{Public      int Id {get; set;}      public string Nickname {get; set;}      public string Avatar {get; set;}}

request, requesting the structure model, takes advantage of the generic interface, which links the request class to the return class, and plays a role in controlling the reversal.

Publicly abstract class abstractrequest{    public bool Validateparameters ()    {        //Common Method example, verifying parameter Legality    }}   public interface irequest<t> where T:abstractresponse    {        //Gets the interface name        string Getapiname ();        Gets the interface encoding        string Getapicode ();    } Gets the user information request structure definition public  class getuserrequest:abstractrequest,irequest<getuserresponse>    {        public int Id {get; set;}        public string Getapiname ()        {            return "User.getuserdetail";        }        public string Getapicode ()        {            return ' User001 ';        }    }

The response module, as the return type of the request, defines a unified return structure, which makes it easy for consumers to judge the consistency return code.

Public abstract class Abstractresponse    {        //Return code public        int code {get; set;}        Error message Public        string Message {get; set}    } public class Getuserresponse:abstractresponse {public        User User {get; set;}    }

Service Project code sample

Project structure such as:


Service.jpg

code example:

Public interface Iuserservice    {        getuserresponse GetUser (int id),    } public class Baseservice    {        // protected sqlinstance sqlinstance;        Public Baseservice ()        {            //sqlinstance=new sqlinstance ();//Instantiate database connection//            ...        }        //...    }  public class Userservice:baseservice,iuserservice    {public        getuserresponse GetUser (int id)        {            // Link database Get Data            //...            throw new NotImplementedException ();        }    }

Security Class Library code example

The class library simply handles security issues and adds permission judgments at the API request entrance. Use the way to override HTTP requests.
code example

public class Myhandler:delegatinghandler {protected Async override task& Lt Httpresponsemessage> SendAsync (httprequestmessage request, CancellationToken CancellationToken) {IEn            Umerable<string> keyenumerable; var T1 = Request.            Headers.trygetvalues ("Key", out keyenumerable);            var key = Keyenumerable.firstordefault ();                            if (!true)//Verify a permission similar to token {return await task.factory.startnew

The abstraction of the permission to judge, can be directly called to the Webapi side, added to the routing configuration code.

WEBAPI Project Examples

As the actual definition of the interface, WEBAPI defines the actual rules of the interface file, and makes the corresponding security management and control of the interface. Learning permissions control, presumably identified several interfaces:


Interface permissions. png


These permissions are judged on the security of the centralized management. The definition of an interface requires only the appropriate logic to use the judgment legitimacy.
code example:

public class Usercontroller:apicontroller    {        private iuserservice userservice;        Public Usercontroller ()        {            userservice=new userservice ();        }        [signature]//Security Signature filter Judgment        [HttpPost] public        getuserresponse GetUser (getuserrequest request)        {            // Parameter determination, safety judgment, etc.            var ret = userservice.getuser (Request. ID);            return ret;        }    }

The above is a sample interface to obtain user information, and as the interface entry routing configuration, you need to judge the legality of the request, the routing configuration Code is as follows:

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}            );            Add the code to add the HTTP request to the Portal Processing            config. Messagehandlers.add (New MyHandler ());}

Client class Library code example

The Client class library defines the public methods for interface invocation.
1, using the generic interface, the request class and the return class are encapsulated, simplifying the invocation of code writing.
2, and make the consumer call interface through the proxy class, to avoid cross-domain problems.
3, the consumer calls all agree to use the Uniform class Library, is the processing of the log is unified, the return error can also be consistent definition.
The code examples are as follows:

 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 webreques t = (HttpWebRequest) webrequest.create (BASEURL + request).            Getapiname ());            Webrequest.method = "POST";            String Reqjson;            string sign; using (Stream rs = Webrequest.getrequeststream ()) {Reqjson = Jsonconvert.serializeobject (reques                T);                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);           Log if (isneedlogfile) {LogFile.Log (string. Format ("[{0}] requested content: {1}", request.                Getapicode (), Reqjson)); LogFile.Log (String. Format ("[{0}] requested signature: {1}", request.            Getapicode (), sign));                     } try {using (var resp = (HttpWebResponse) webrequest.getresponse ()) { try {Stream Respstream = resp.                        GetResponseStream (); if (Respstream = = null) {throw new WebException ("GetResponseStream Retu                        rned null ");                        } var streamReader = new StreamReader (respstream);                        String respstr = Streamreader.readtoend (); Log if (isneedlogfile) {LogFile.Log (string. Format ("[{0}] response content: {1}", request. Getapicode (), respstr));                    } return jsonconvert.deserializeobject<t> (RESPSTR); } catch (Exception e) {//log if (IsN Eedlogfile) {LogFile.Log (string. Format ("[{0}] Response error: {1}", request.                        Getapicode (), e.message));                    } throw new ApplicationException (E.message, E); }}} catch (WebException e) {var errmsg = new Streamreade R (E.response.getresponsestream ()).                ReadToEnd (); Log if (isneedlogfile) {LogFile.Log (string. Format ("[{0}] requested error: {1}", request.                Getapicode (), errmsg));            } throw new Apiserviceexception (errmsg); }} private string ComputeHash (string key, StringSecret, String body) {return convert.tobase64string (SHA1. Create (). ComputeHash (Encoding.Default.GetBytes (String. Concat (key, Secret, body.        Trim ()))); }    }
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.