.Net WebAPI 访问其他项目层操作

1.首先,配置一个公用的WEBAPI服务接口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebAPIService.Utility;   ---引用的层
using Exceptions;                   ---引用的层

namespace Syngenta.FWA.WebUI.Controllers
{
    [RoutePrefix("api/AppService")]
    public class AppServiceController : ApiController
    {
        // GET api/<controller>
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/<controller>/5
        public string Get(string jsonParams)
        {
            return null;
        }



        //POST api/<controller>
        [Route("Post")]
        public IHttpActionResult Post([FromBody]JsonContainer container)
        {
            try
            {
                return Ok(container.GetObject());
            }
            catch (Exception Ex)
            {
                ExceptionManager.Publish(Ex);
                return BadRequest(dEx.Message);
            }
            catch (Exception ex)
            {
                var cutomException = GetCustomException(ex);
                ExceptionManager.Publish(cutomException);
                return BadRequest(cutomException.Message);
            }

        }



        [Route("PostActionList")]
        public IHttpActionResult PostActionList(JsonContainer[] containerList)
        {
            try
            {
                object[] objList = new object[containerList.Length];
                for (int i = 0; i < containerList.Length; ++i)
                    objList[i] = containerList[i].GetObject();
                return Ok(objList);
            }
            catch (Exception ex)
            {
                ExceptionManager.Publish(ex);
                return BadRequest(ex.Message + "=>" + ex.StackTrace);
            }

        }

        [Route("PostService")]
        [HttpPost]
        public IHttpActionResult PostService([FromBody]JsonContainer container)
        {
            try
            {
                return Ok(container.GetObjectFromService());
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message + "=>" + ex.StackTrace);
            }
        }

        [Route("PostAction")]
        [HttpPost]
        public IHttpActionResult PostAction([FromBody]JsonContainer container)
        {
            try
            {
                return Ok(container.GetObjectFromAction());
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message + "=>" + ex.StackTrace);
            }
        }

        // PUT api/<controller>/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/<controller>/5
        public void Delete(int id)
        {
        }

        private Exception GetCustomException(Exception exception)
        {
            if (exception.GetType() == typeof(Exception))
            {
                return exception;
            }

            if (exception.InnerException != null)
            {
                return GetCustomException(exception.InnerException);
            }

            return exception;

        }


    }
}

 

2.在引用的项目层里添加JasonContainer类(即引用),用来访问对应的类 ,规则是以BL开头及以Service结尾的.cs文件,通过反射生产对应的类实例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace WebAPIService
{
    public class JsonContainer
    {
        const string BusinessNamespace = "BusinessLayer.";

        const string ServiceNamespace = "WebAPIService.Implements.";

        const string AdapterNamespace = "WebAPIService.Adapter.";

        public string Class { get; set; }

        public string Action { get; set; }

        public Dictionary<string, object> Parameters { get; set; }

        public object GetObject()
        {
            if (this.Class.EndsWith("service", StringComparison.OrdinalIgnoreCase))
            {
                var t = Type.GetType(ServiceNamespace + Class);
                if (t == null) t = Type.GetType(ServiceNamespace + "BL" + Class);
                object obj = Activator.CreateInstance(t);
                var method = FindMethod(t);
                return method.Invoke(obj, GetParameters(method));
            }
            else
            {
                if (!Class.StartsWith("BL", StringComparison.OrdinalIgnoreCase)) Class = "BL" + Class;

                Assembly assembly = AssemblyProvider.Provider.GetAssembly(AssemblyProvider.BusinessAssembly);
                var t = assembly.GetType(BusinessNamespace + Class);
                object bl = Activator.CreateInstance(t); //BL class instance
                var method = FindMethod(t);

                //Find if there's adpater
                var tAdapter = Assembly.GetCallingAssembly().GetType(AdapterNamespace + Class + "Adapter");

                if (tAdapter == null)
                {
                    return CallMethod(bl, method);
                }
                else
                {
                    object objAdapter = Activator.CreateInstance(tAdapter);
                    MethodInfo methodAdapter = tAdapter.GetMethod(Action + "Convert");
                    if (methodAdapter == null)  //No such Apdater method, invoke BL method directly
                        return CallMethod(bl, method);
                    return methodAdapter.Invoke(objAdapter, new object[] { Parameters, bl, method });
                }
            }
        }

        private MethodInfo FindMethod(Type t)
        {
            var members = t.GetMember(Action, MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance);

            if (members.Length == 1) return members.Single() as MethodInfo;
            else if (members.Length > 1)
            {
                var methods = members.Cast<MethodInfo>().Where(m => m.GetParameters().Length == this.Parameters.Count);

                foreach (var m in methods)  //Find method with consistent parameter names
                {
                    var matched = m.GetParameters().Select(p => p.Name).SequenceEqual(this.Parameters.Keys);
                    if (matched) return m;
                }
            }

            throw new EntryPointNotFoundException(String.Format("{0} Not Found in {1}", Action, Class));
        }

        [Obsolete]
        public object GetObjectFromService()
        {
            Type t = Type.GetType(ServiceNamespace + Class);
            object obj = Activator.CreateInstance(t);
            MethodInfo method = t.GetMethod(Action);
            if (method.GetParameters().Length > 0)
                return method.Invoke(obj, new object[] { Parameters });
            else
                return method.Invoke(obj, null);
        }

        [Obsolete]
        public object GetObjectFromAction()
        {
            Assembly assembly = AssemblyProvider.Provider.GetAssembly(AssemblyProvider.BusinessAssembly);
            Type t = assembly.GetType(BusinessNamespace + Class);
            object obj = Activator.CreateInstance(t);
            MethodInfo method = t.GetMethod(Action);

            Type tAdapter = Type.GetType(AdapterNamespace + Class + "Adapter");
            object objAdapter = Activator.CreateInstance(tAdapter);
            MethodInfo methodAdapter = tAdapter.GetMethod(Action + "Convert");
            return methodAdapter.Invoke(objAdapter, new object[] { Parameters, obj, method });
        }

        private object CallMethod(object bl, MethodInfo method)
        {
            var pValues = GetParameters(method);
            return method.Invoke(bl, pValues);
        }

        /// <summary>
        /// Generete parameters order by the method's signature
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        private object[] GetParameters(MethodInfo method)
        {
            var pValues = method.GetParameters().Select(p =>
            {
                var value = this.Parameters.Single(p2 => p2.Key.Equals(p.Name, StringComparison.OrdinalIgnoreCase)).Value;
                return value == null || value.GetType() == p.ParameterType ? value : Convert.ChangeType(value, p.ParameterType);
            }).ToArray();

            if (pValues.Length == 0) return null;
            return pValues;
        }
    }
}

 

3.在引用的项目层里添加AssemblyProvider.cs

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace WebAPIService
{
    public class AssemblyProvider
    {
        static readonly AssemblyProvider instance = new AssemblyProvider();

        public const string BusinessAssembly = "BusinessLayer";

        static readonly Assembly businessAssembly = Assembly.Load(BusinessAssembly);

        static AssemblyProvider()
        {
        }

        AssemblyProvider()
        {
        }

        public Assembly GetAssembly(string assembleName)
        {
            if (assembleName == BusinessAssembly)
                return businessAssembly;
            return null;
        }

        public static AssemblyProvider Provider
        {
            get
            {
                return instance;
            }
        }
    }
}

 

4.WebAPIConig.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace Syngenta.FWA.WebUI
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }
}

 

 

 

 

 

前台代码可以配置一个公用的访问层来调用webapi  (以AngularJS为例)

(function () {
    'use strict';

    angular
        .module('fwa')
        .factory('webapi', webapi);

    webapi.$inject = ['$http', '$httpParamSerializer'];

    function webapi($http, $httpParamSerializer) {

        return {

            post: function (className, actionName, parameters) {

                return $http({
                    method: 'POST',
                    url: 'api/AppService/Post',
                    data: JSON.stringify({ Class: className, Action: actionName, Parameters: parameters })
                });

            },

            getMenu: function () {
                return $http({
                    method: 'get',
                    url: 'api/Security'
                });
            },

            postList: function (actionList) {
                return $http({
                    method: 'POST',
                    url: 'api/AppService/PostActionList',
                    data: JSON.stringify(actionList)
                });
            }

        }


    }


})();

 

posted @ 2019-01-09 14:32  Aaron_M  阅读(578)  评论(0编辑  收藏  举报