Asp.net MVC Api项目搭建

整个解决方案按照分层思想来划分不同功能模块,以提供User服务的Api为需求,各个层次的具体实现如下所示:

1、新建数据库User表

数据库使用SQLExpress版本,表的定义如下所示:

CREATE TABLE [dbo].[User] (
    [Id]               INT           IDENTITY (1, 1) NOT NULL,
    [Name]             NVARCHAR (50) NOT NULL,
    [Password]         NVARCHAR (50) NOT NULL,
    [Age]              INT           NOT NULL,
    [Birthdate]        DATE          NOT NULL,
    [CreateTime]       DATETIME      DEFAULT (getdate()) NOT NULL,
    [CreateUserId]     NVARCHAR (50) NOT NULL,
    [CreateUserName]   NVARCHAR (50) NOT NULL,
    [ModifiedTime]     DATETIME      NULL,
    [ModifiedUserId]   NVARCHAR (50) NULL,
    [ModifiedUserName] NVARCHAR (50) NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

2、实体层

新建类库类型的项目,.net framework框架版本4.5,User实体类如下:

public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Password { get; set; }
        public int Age { get; set; }
        public DateTime Birthdate { get; set; }
        public DateTime CreateTime { get; set; }
        public string CreateUserId { get; set; }
        public string CreateUserName { get; set; }
        public DateTime? ModifiedTime { get; set; }
        public string ModifiedUserId { get; set; }
        public string ModifiedUserName { get; set; }
    }

3、数据库层

该层提供数据库接口操作,采用EntitFramework4.4.0.0作为ORM实体映射框架,

  • 定义数据库操作接口IRepository
public interface IRepository<TEntity> : IDisposable where TEntity : class
    {
        IEnumerable<TEntity> Get();
        IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter);
        IEnumerable<TEntity> Get<TOderKey>(Expression<Func<TEntity, bool>> filter, int pageIndex, int pageSize, Expression<Func<TEntity, TOderKey>> sortKeySelector, bool isAsc = true);

        int Count(Expression<Func<TEntity, bool>> predicate);
        void Update(TEntity instance);
        void Add(TEntity instance);
        void Delete(TEntity instance);
    }
  • 定义数据库上下文类BceDbContext
public class BceDbContext:DbContext
    {
        public BceDbContext():base("DaLeiDB")
        {
            Database.SetInitializer<AceDbContext>(null);
        }
        public DbSet<User> Users { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>().ToTable("User");
            base.OnModelCreating(modelBuilder);
        }
    }
  • 定义数据库通用操作实现类BceRepository
public class BceRepository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        public BceDbContext DbContext { get; private set; }
        public DbSet<TEntity> DbSet { get; private set; }
        public BceRepository(BceDbContext context)
        {
            Guard.ArgumentNotNull(context, "context");
            this.DbContext = context;
            this.DbSet = this.DbContext.Set<TEntity>();
        }

        public IEnumerable<TEntity> Get()
        {
            return this.DbSet.AsQueryable();
        }
        public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter)
        {
            return this.DbSet.Where(filter).AsQueryable();
        }
        public IEnumerable<TEntity> Get<TKey>(Expression<Func<TEntity, bool>> filter, int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> sortKeySelector, bool isAsc = true)
        {
            Guard.ArgumentNotNull(filter, "predicate");
            Guard.ArgumentNotNull(sortKeySelector, "sortKeySelector");
            if (isAsc)
            {
                return this.DbSet
                    .Where(filter)
                    .OrderBy(sortKeySelector)
                    .Skip(pageSize * (pageIndex - 1))
                    .Take(pageSize).AsQueryable();
            }
            else
            {
                return this.DbSet
                    .Where(filter)
                    .OrderByDescending(sortKeySelector)
                    .Skip(pageSize * (pageIndex - 1))
                    .Take(pageSize).AsQueryable();
            }
        }

        public int Count(Expression<Func<TEntity, bool>> predicate)
        {
            return this.DbSet.Where(predicate).Count();
        }

        public void Add(TEntity instance)
        {
            Guard.ArgumentNotNull(instance, "instance");
            this.DbSet.Attach(instance);
            this.DbContext.Entry(instance).State = EntityState.Added;
            this.DbContext.SaveChanges();
        }
        public void Update(TEntity instance)
        {
            Guard.ArgumentNotNull(instance, "instance");
            this.DbSet.Attach(instance);
            this.DbContext.Entry(instance).State = EntityState.Modified;
            this.DbContext.SaveChanges();
        }
        public void Delete(TEntity instance)
        {
            Guard.ArgumentNotNull(instance, "instance");
            this.DbSet.Attach(instance);
            this.DbContext.Entry(instance).State = EntityState.Deleted;
            this.DbContext.SaveChanges();
        }

        public void Dispose()
        {
            this.DbContext.Dispose();
        }
    }
  • 定义用户表数据库操作额外的接口IUserRepository
namespace DaLei.Repository
{
    public interface IUserRepository
    {
        User FindByName(string name);
        List<User> FindByAge(int start, int end);
    }
}
  • 定义用户表数据库操作额外的实现类UserRepository
    namespace DaLei.Repository
    {
        public class UserRepository : BceRepository<User>, IUserRepository
        {
            public UserRepository(BceDbContext bceDbContext):base(bceDbContext)
            {
    
            }
    
            public List<User> FindByAge(int start, int end)
            {
                var rst = this.DbSet.AsQueryable().Where(u=>u.Age>=start && u.Age<=end).ToList();
                return rst;
            }
    
            public User FindByName(string name)
            {
                var rst = this.DbSet.AsQueryable().Where(u => u.Name == name).FirstOrDefault();
                return rst;
            }
        }
    }

4、服务接口层

定义了对外提供用户服务的接口契约,具体如下:

namespace DaLei.IService
{
    public interface IUserService
    {
        User FindByName(string name);
        List<User> FindByAge(int start, int end);
        List<User> GetList();
    }
}

5、服务具体实现层

服务基类实现:

using System;
using System.Collections.Generic;

namespace DaLei.Service
{
    public abstract class ServiceBase : IDisposable
    {
        public IList<IDisposable> DisposableObjects { get; private set; }
        public ServiceBase()
        {
            this.DisposableObjects = new List<IDisposable>();
        }
        protected void AddDisposableObject(object obj)
        {
            IDisposable disposable = obj as IDisposable;
            if (null != disposable)
            {
                this.DisposableObjects.Add(disposable);
            }
        }

        public void Dispose()
        {
            foreach (IDisposable obj in this.DisposableObjects)
            {
                if (null != obj)
                {
                    obj.Dispose();
                }
            }
        }
    }
}

用户服务接口具体实现:

using DaLei.IService;
using DaLei.Model;
using DaLei.Repository;
using System.Collections.Generic;

namespace DaLei.Service
{
    public class UserService : ServiceBase,IUserService
    {
        private IUserRepository userRepository;
        public UserService(IUserRepository userRepository)
        {
            this.userRepository = userRepository;
            this.AddDisposableObject(userRepository);
        }
        public List<User> FindByAge(int start, int end)
        {
            return this.userRepository.FindByAge(start,end);
        }

        public User FindByName(string name)
        {
            return this.userRepository.FindByName(name);
        }

        public List<User> GetList()
        {
            return this.userRepository.FindByAge(0, 100);
        }
    }
}

6、应用层

新建Asp.net WebApi项目,引用服务接口项目、服务实现项目、实体类项目,unity相关程序集,EntityFramework程序集。

web.config配置连接字符串和unity相关内容:

<?xml version="1.0" encoding="utf-8"?>
<!--
  有关如何配置 ASP.NET 应用程序的详细信息,请访问
  https://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
    <containers>
      <container>
        <extension type="Interception" />
        <register type="DaLei.IService.IUserService, DaLei.IService" mapTo="DaLei.Service.UserService, DaLei.Service" />
        <register type="DaLei.Repository.IUserRepository, DaLei.Repository" mapTo="DaLei.Repository.UserRepository, DaLei.Repository">
          <interceptor type="InterfaceInterceptor" />
          <policyInjection />
        </register>
      </container>
    </containers>
  </unity>
  <connectionStrings>
    <add name="DaLeiDB" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=DaleiDB;User ID=sa;Password=anpiel0991;" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="webpages:Version" value="3.0.0.0"/>
    <add key="webpages:Enabled" value="false"/>
    <add key="PreserveLoginUrl" value="true"/>
    <add key="ClientValidationEnabled" value="true"/>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5"/>
    <httpRuntime targetFramework="4.5"/>
    <pages>
      <namespaces>
        <add namespace="System.Web.Helpers"/>
        <add namespace="System.Web.Mvc"/>
        <add namespace="System.Web.Mvc.Ajax"/>
        <add namespace="System.Web.Mvc.Html"/>
        <add namespace="System.Web.Routing"/>
        <add namespace="System.Web.WebPages"/>
      </namespaces>     
    </pages>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
      <remove name="OPTIONSVerbHandler"/>
      <remove name="TRACEVerbHandler"/>
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler"
        preCondition="integratedMode,runtimeVersionv4.0"/>
    </handlers>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed"/>
        <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs"
        type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701"/>
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
        type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
    </compilers>
  </system.codedom>
</configuration>
  • Controller实例化由Unity负责处理,需要实现控制器工厂类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;

namespace WebApi.Extensions
{
    public class UnityControllerFactory : DefaultControllerFactory
    {
        static object syncHelper = new object();
        static Dictionary<string, IUnityContainer> containers = new Dictionary<string, IUnityContainer>();
        public IUnityContainer UnityContainer { get; private set; }
        public UnityControllerFactory(string containerName = "")
        {
            if (containers.ContainsKey(containerName))
            {
                this.UnityContainer = containers[containerName];
                return;
            }
            lock (syncHelper)
            {
                if (containers.ContainsKey(containerName))
                {
                    this.UnityContainer = containers[containerName];
                    return;
                }
                IUnityContainer container = new UnityContainer();
                //配置UnityContainer
                UnityConfigurationSection configSection = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
                if (null == configSection && !string.IsNullOrEmpty(containerName))
                {
                    throw new ConfigurationErrorsException("The <unity> configuration section does not exist.");
                }
                if (null != configSection)
                {
                    if (string.IsNullOrEmpty(containerName))
                    {
                        configSection.Configure(container);
                    }
                    else
                    {
                        configSection.Configure(container, containerName);
                    }
                }
                containers.Add(containerName, container);
                this.UnityContainer = containers[containerName];
            }
        }
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (null == controllerType)
            {
                return null;
            }
            return (IController)this.UnityContainer.Resolve(controllerType);
        }
//public override void ReleaseController(IController controller)
//{
//    this.UnityContainer.Teardown(controller);
//}
    }
}
  • 设置MVC框架的控制器工厂为自定义类型
using webApi.Extensions;
using System;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;

namespace WebApp
{
    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            // 在应用程序启动时运行的代码
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());
        }
    }
}
  • 新建Controller基类,所有的自定义Controller均继承此类
using WebApi.Extensions;
using System.Web.Mvc;
using System;
using System.Collections.Generic;

namespace WebApp.Controllers
{
    public class BaseController:Controller
    {
        public IList<IDisposable> DisposableObjects { get; private set; }
        public BaseController()
        {
            this.DisposableObjects = new List<IDisposable>();
        }
        protected void AddDisposableObject(object obj)
        {
            IDisposable disposable = obj as IDisposable;
            if (null != disposable)
            {
                this.DisposableObjects.Add(disposable);
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                foreach (IDisposable obj in this.DisposableObjects)
                {
                    if (null != obj)
                    {
                        obj.Dispose();
                    }
                }
            }
            base.Dispose(disposing);
        }
    }
}
  • 新建测试Controller
using DaLei.IService;
using System.Web.Mvc;

namespace WebApp.Controllers
{
    public class TestController : BaseController
    {
        private IUserService userService;
        public TestController(IUserService userService)
        {
            this.userService = userService;
            this.AddDisposableObject(userService);
        }

        // GET: Test
        public ActionResult Index()
        {
            var users = this.userService.GetList();
            return View();
        }
    }
}

浏览器输入地址测试TestController!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET Core是一种跨平台的开发框架,用于构建Web应用程序和服务。它是ASP.NET的下一代版本,具有许多新的特性和改进。 搭建ASP.NET Core应用程序有以下步骤: 1. 安装开发环境:在开始之前,您需要安装所需的开发工具。首先,您需要安装.NET Core SDK,这是用于构建和运行ASP.NET Core应用程序的开发工具集。您还可以选择安装一个集成开发环境(IDE),如Visual Studio或Visual Studio Code。 2. 创建项目:使用dotnet命令行工具或IDE创建一个新的ASP.NET Core项目。您可以选择不同类型的项目模板,如Web APIMVC、Razor Pages等,以满足您的需求。 3. 配置应用程序:在项目文件中,可以设置应用程序的基本配置,如端口号、数据库连接字符串、身份验证等。ASP.NET Core采用了配置文件和环境变量等机制来管理应用程序的设置。 4. 编写代码:使用C#或其他支持的编程语言编写应用程序的业务逻辑和功能。ASP.NET Core提供了丰富的开发功能和API,如路由、中间件、依赖注入等,以简化开发过程。 5. 运行和调试:使用dotnet命令行工具或IDE中的调试功能,可以运行和调试您的应用程序。您可以在浏览器中访问应用程序,并查看输出结果。 6. 部署应用程序:一旦您完成了应用程序的开发和测试,可以将其部署到生产环境中。您可以选择不同的部署方式,如自承载、Docker容器、云服务等。 ASP.NET Core具有许多优点,如高性能、跨平台支持、模块化开发、易于测试等。通过搭建ASP.NET Core应用程序,您可以快速构建出强大和可扩展的Web应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值