1. 程式人生 > >實戰Angular2+web api增刪改查 (二)

實戰Angular2+web api增刪改查 (二)

webapi配置

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            //SwaggerConfig.Register();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            //Nhibernate及日誌初始化
            LoggingConfig.Register();
            //依賴注入初始化
            IocConfig
.Register();
        }

在Global.asax的啟動方法中加入依賴注入的配置,NHibernate配置,以及webapi配置,區域路由配置等,如果使用安全策略也許要在此加入,本例目前還沒進行身份認證處理,後面將會重點介紹。

AutoFac依賴注入配置

public static void Register()
        {
            ContainerBuilder builder = new ContainerBuilder();
            Type baseType = typeof(IDependency);
            var
 assemblies = AppDomain.CurrentDomain.GetAssemblies();
            // 獲取所有相關類庫的程式集
            builder.RegisterAssemblyTypes(assemblies)
                .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract)
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope();
            var config = GlobalConfiguration.Configuration;
            builder.RegisterWebApiFilterProvider(config);
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
            //builder.RegisterType<GroupListController>().InstancePerRequest();
            var container = builder.Build();
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        }

這個配置可以看出是利用反射技術獲取當前應用下的所有assemblies ,通過Type baseType = typeof(IDependency)指定凡是繼承該介面的例項都將注入到ContainerBuilder 容器中。

除此之外,要在wabapi中使用依賴注入還需處理webapi的注入,這就需要使用另一個工具Autofac.WebApi,使用PM > Install-Package Autofac.WebApi獲取。然後使用config.DependencyResolver = new AutofacWebApiDependencyResolver(container)就可將webapicontroller注入到容器中。

NHibernate配置

public class LoggingConfig
   {
       public static void Register()
       {
           SessionBuilder.Instance("web");
           string logfile = CachedConfigContext.Current.ConfigService.GetFilePath("log4net");
           var ms = new MemoryStream(Encoding.Default.GetBytes(logfile));
           log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(logfile));
       }
   }

這裡我還是用了log4net加入了log功能,這裡注意SessionBuilder.Instance("web");由於我們開發的是webapi應用所以這裡例項話是選擇為web。這裡的SessionBuilder是前面封裝的對Nhibernate的ISession管理的類。

Web Api跨域訪問配置

Web api跨越訪問需要使用另外一個工具

PM>install-package Microsoft.AspNet.WebApi.Cors

global中的webapi register中增加

var cors = newEnableCorsAttribute(

            origins: "*",

            headers: "*",

            methods: "*");

        config.EnableCors(cors);

public static class WebApiConfig
   {
       public static void Register(HttpConfiguration config)
       {
           // Web API 跨域訪問
           var cors = new EnableCorsAttribute(
           origins: "*",
           headers: "*",
           methods: "*");
           config.EnableCors(cors);
           // Web API 路由
           config.MapHttpAttributeRoutes();
           config.Routes.MapHttpRoute(
               name: "DefaultApi",
               routeTemplate: "api/{controller}/{id}",
               defaults: new { id = RouteParameter.Optional }
           );
       }
   }

Web api Controller

[EnableCors("*""*""*")]
    public class GroupListController : ApiController
    {
        private IGroupService _groupService;
        public GroupListController(IGroupService groupService)
        {
            _groupService = groupService;
        }
        public IList<GroupBaseDto> GetAll()
        {
           var list =  _groupService.GetAll();
           List<GroupBaseDto> groupList =AutoMapperHelper.MapToList<GroupBaseDto>(list);
           return groupList;
        }
        public GroupBaseDto GetByID(string id)
        {
            var item = _groupService.GetByID(id);
            GroupBaseDto groupdto = AutoMapperHelper.MapTo<GroupBaseDto>(item);
            return groupdto;
        }
        public HttpResponseMessage PostGroup(GroupBaseDto group)
        {
            try
            {
                group.ID = Guid.NewGuid().ToString();
                TGroup entity = AutoMapperHelper.MapTo<TGroup>(group);
                _groupService.Add(entity);
                return new HttpResponseMessage(HttpStatusCode.NoContent);
            }
            catch
            {
                throw new HttpResponseException(HttpStatusCode.InternalServerError);
            }
        }
        public HttpResponseMessage PutGroup(string id, GroupBaseDto group)
        {
            try
            {
                group.ID = id;
                TGroup entity = AutoMapperHelper.MapTo<TGroup>(group);
                _groupService.Update(entity);
                return new HttpResponseMessage(HttpStatusCode.NoContent); 
            }
            catch(Exception se)
            {
                throw new  HttpResponseException(HttpStatusCode.InternalServerError); 
            }
        }
        public HttpResponseMessage DeleteGroup(string id)
        {
            try
            {
                 _groupService.Delete(id);
                 return new HttpResponseMessage(HttpStatusCode.NoContent); 
            }
            catch
            {
                throw new HttpResponseException(HttpStatusCode.InternalServerError);
            }
        }
    }

這裡看到通過使用了前面webapi的依賴注入配置,我們在controller的建構函式中就可以使用構造注入Iservice了。這裡也可以看到我們的資料傳遞使用了DTO,一方面是為了效率只傳輸與業務有關的資料,另一方面業務為了不暴露我們的資料屬性。

public class GroupBaseDto
   {
       public virtual string ID { getset; }
       public virtual string GROUPNAME { getset; }
       public virtual decimal? NORDER { getset; }
       public virtual string PARENTID { getset; }
       public virtual string GROUPTYPE { getset; }
       public virtual string GROUPCODE { getset; }
   }

為了簡單,這個例項我所使用DTO與我所在的領域模型一致,這裡還是用了一個AutoMapper工具,Automapper能夠讓我們在DTO與DO的轉換過程更簡單了,下面是對AutoMapper的一個封裝類,用於處理常用轉換。

///<summary>
    /// AutoMapper擴充套件幫助類
    ///</summary>
    public static class AutoMapperHelper
    {
        ///<summary>
        ///型別對映
        ///</summary>
        public static T MapTo<T>(this object obj)
        {
            if (obj == nullreturn default(T);
            Mapper.Initialize(cfg=>cfg.CreateMap(obj.GetType(),typeof(T)));
            return Mapper.Map<T>(obj);
        }
        ///<summary>
        ///集合列表型別對映
        ///</summary>
        public static List<TDestination> MapToList<TDestination>(this IEnumerable source)
        {
            foreach (var first in source)
            {
                var type = first.GetType();
                Mapper.Initialize(cfg => cfg.CreateMap(type, typeof(TDestination)));
                break;
            }
            return Mapper.Map<List<TDestination>>(source);
        }
        ///<summary>
        ///集合列表型別對映
        ///</summary>
        public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
        {
            //IEnumerable<T> 型別需要建立元素的對映
            Mapper.Initialize(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination)));
            return Mapper.Map<List<TDestination>>(source);
        }
        ///<summary>
        ///型別對映
        ///</summary>
        public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
            where TSource : class
            where TDestination : class
        {
            if (source == nullreturn destination;
            Mapper.Initialize(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination)));
            return Mapper.Map(source, destination);
        }
    }

到此我們一個簡單的api就已經完成了,可以通過Swashbuckle 進行測試,安裝PM> Install-Package Swashbuckle,使用時只需在路徑後加入swagger,如http://localhost:6611/swagger/ui/index