成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

ABP是什么-創(chuàng)新互聯(lián)

這篇文章給大家分享的是有關(guān)ABP是什么的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

成都創(chuàng)新互聯(lián)公司的客戶來(lái)自各行各業(yè),為了共同目標(biāo),我們?cè)诠ぷ魃厦芮信浜?,從?chuàng)業(yè)型小企業(yè)到企事業(yè)單位,感謝他們對(duì)我們的要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。專業(yè)領(lǐng)域包括成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、電商網(wǎng)站開(kāi)發(fā)、微信營(yíng)銷、系統(tǒng)平臺(tái)開(kāi)發(fā)。

ABP是“ASP.NET Boilerplate Project (ASP.NET樣板項(xiàng)目)”的簡(jiǎn)稱。

ASP.NET Boilerplate是一個(gè)用很好實(shí)踐和流行技術(shù)開(kāi)發(fā)現(xiàn)代WEB應(yīng)用程序的新起點(diǎn),它旨在成為一個(gè)通用的WEB應(yīng)用程序框架和項(xiàng)目模板。

ABP的官方網(wǎng)站:http://www.aspnetboilerplate.com

ABP在Github上的開(kāi)源項(xiàng)目:https://github.com/aspnetboilerplate

ABP 的由來(lái)

“DRY——避免重復(fù)代碼”是一個(gè)優(yōu)秀的開(kāi)發(fā)者在開(kāi)發(fā)軟件時(shí)所具備的最重要的思想之一。我們?cè)陂_(kāi)發(fā)企業(yè)WEB應(yīng)用程序時(shí)都有一些類似的需求,例如:都需要登錄頁(yè)面、用戶/角色管理、權(quán)限驗(yàn)證、數(shù)據(jù)有效性驗(yàn)證、多語(yǔ)言/本地化等等。一個(gè)高品質(zhì)的大型軟件都會(huì)運(yùn)用一些很好實(shí)踐,例如分層體系結(jié)構(gòu)、領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)、依賴注入等。我們也可能會(huì)采用ORM、數(shù)據(jù)庫(kù)遷移(Database Migrations)、日志記錄(Logging)等工具。

從零開(kāi)始創(chuàng)建一個(gè)企業(yè)應(yīng)用程序是一件繁瑣的事,因?yàn)樾枰貜?fù)做很多常見(jiàn)的基礎(chǔ)工作。許多公司都在開(kāi)發(fā)自己的應(yīng)用程序框架來(lái)重用于不同的項(xiàng)目,然后在框架的基礎(chǔ)上開(kāi)發(fā)一些新的功能。但并不是每個(gè)公司都有這樣的實(shí)力。假如我們可以分享的更多,也許可以避免每個(gè)公司或每個(gè)項(xiàng)目的重復(fù)編寫類似的代碼。作者之所以把項(xiàng)目命名為“ASP.NET Boilerplate”,就是希望它能成為開(kāi)發(fā)一般企業(yè)WEB應(yīng)用的新起點(diǎn),直接把ABP作為項(xiàng)目模板。

ABP是什么?

ABP是為新的現(xiàn)代Web應(yīng)用程序使用很好實(shí)踐和使用最流行工具的一個(gè)起點(diǎn)。可作為一般用途的應(yīng)用程序的基礎(chǔ)框架或項(xiàng)目模板。它的功能包括:

服務(wù)器端:

  • 基于新的.NET技術(shù) (目前是ASP.NET MVC 5、Web API 2、C# 5.0,在ASP.NET 5正式發(fā)布后會(huì)升級(jí))

  • 實(shí)現(xiàn)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(實(shí)體、倉(cāng)儲(chǔ)、領(lǐng)域服務(wù)、領(lǐng)域事件、應(yīng)用服務(wù)、數(shù)據(jù)傳輸對(duì)象,工作單元等等)

  • 實(shí)現(xiàn)分層體系結(jié)構(gòu)(領(lǐng)域?qū)?,?yīng)用層,展現(xiàn)層和基礎(chǔ)設(shè)施層)提供了一個(gè)基礎(chǔ)架構(gòu)來(lái)開(kāi)發(fā)可重用可配置的模塊集成一些最流行的開(kāi)源框架/庫(kù),也許有些是你正在使用的。

  • 提供了一個(gè)基礎(chǔ)架構(gòu)讓我們很方便地使用依賴注入(使用Castle Windsor作為依賴注入的容器)

  • 提供Repository倉(cāng)儲(chǔ)模式支持不同的ORM(已實(shí)現(xiàn)Entity Framework 、NHibernate、MangoDb和內(nèi)存數(shù)據(jù)庫(kù))

  • 支持并實(shí)現(xiàn)數(shù)據(jù)庫(kù)遷移(EF 的 Code first)模塊化開(kāi)發(fā)(每個(gè)模塊有獨(dú)立的EF DbContext,可單獨(dú)指定數(shù)據(jù)庫(kù))

  • 包括一個(gè)簡(jiǎn)單的和靈活的多語(yǔ)言/本地化系統(tǒng)

  • 包括一個(gè) EventBus來(lái)實(shí)現(xiàn)服務(wù)器端全局的領(lǐng)域事件統(tǒng)一的異常處理(應(yīng)用層幾乎不需要處理自己寫異常處理代碼)

  • 數(shù)據(jù)有效性驗(yàn)證(Asp.NET MVC只能做到Action方法的參數(shù)驗(yàn)證,ABP實(shí)現(xiàn)了Application層方法的參數(shù)有效性驗(yàn)證)

  • 通過(guò)Application Services自動(dòng)創(chuàng)建Web Api層(不需要寫ApiController層了)

  • 提供基類和幫助類讓我們方便地實(shí)現(xiàn)一些常見(jiàn)的任務(wù)

  • 使用“約定優(yōu)于配置原則”

客戶端:

  • Bootstrap、Less、AngularJs、jQuery、Modernizr和其他JS庫(kù): jQuery.validate、jQuery.form、jQuery.blockUI、json2等

  • 為單頁(yè)面應(yīng)用程序(AngularJs、Durandaljs)和多頁(yè)面應(yīng)用程序(Bootstrap+Jquery)提供了項(xiàng)目模板。

  • 自動(dòng)創(chuàng)建Javascript 的代理層來(lái)更方便使用Web Api封裝一些Javascript 函數(shù),更方便地使用ajax、消息框、通知組件、忙狀態(tài)的遮罩層等等

除ABP框架項(xiàng)目以外,還開(kāi)發(fā)了名叫“Zero”的模塊,實(shí)現(xiàn)了以下功能:

  • 身份驗(yàn)證與授權(quán)管理(通過(guò)ASP.NET Identity實(shí)現(xiàn)的)

  • 用戶&角色管理系統(tǒng)設(shè)置存取管理(系統(tǒng)級(jí)、租戶級(jí)、用戶級(jí),作用范圍自動(dòng)管理)

  • 審計(jì)日志(自動(dòng)記錄每一次接口的調(diào)用者和參數(shù))

ABP不是什么?

ABP提供了一個(gè)應(yīng)用程序開(kāi)發(fā)模型用于很好實(shí)踐。它擁有基礎(chǔ)類、接口和工具使我們?nèi)菀捉⑵鹂删S護(hù)的大規(guī)模的應(yīng)用程序。

然而:

它不是RAD工具之一,RAD工具的目的是無(wú)需編碼創(chuàng)建應(yīng)用程序。相反,ABP提供了一種編碼的很好實(shí)踐。

它不是一個(gè)代碼生成工具。在運(yùn)行時(shí)雖然它有一些特性構(gòu)建動(dòng)態(tài)代碼,但它不能生成代碼。

它不是一個(gè)一體化的框架。相反,它使用流行的工具/庫(kù)來(lái)完成特定的任務(wù)(例如用EF做ORM,用Log4Net做日志記錄,使得Castle Windsor作為賴注入容器, AngularJs 用于SPA 框架)。

就我使用了ABP幾個(gè)月的經(jīng)驗(yàn)來(lái)看,雖然ABP不是RAD,但是用它開(kāi)發(fā)項(xiàng)目絕對(duì)比傳統(tǒng)三層架構(gòu)要快很多。

雖然ABP不是代碼生成工具,但因?yàn)橛辛怂?,使我們?xiàng)目的代碼更簡(jiǎn)潔規(guī)范,這有利于使用代碼生成工具。

我自己使用VS2013的Scaffolder+T4開(kāi)發(fā)的代碼生成器,可根據(jù)領(lǐng)域?qū)ο蟮腢ML類圖自動(dòng)生成全部前后端代碼和數(shù)據(jù)庫(kù),簡(jiǎn)單的CURD模塊幾乎不需要編寫代碼,有復(fù)雜業(yè)務(wù)邏輯的模塊主要補(bǔ)充領(lǐng)域?qū)哟a即可。這樣就能把時(shí)間多花在領(lǐng)域模型的設(shè)計(jì)上,減少寫代碼的時(shí)間。

下面通過(guò)原作者的“簡(jiǎn)單任務(wù)系統(tǒng)”例子,演示如何運(yùn)用ABP開(kāi)發(fā)項(xiàng)目

從模板創(chuàng)建空的web應(yīng)用程序

ABP提供了一個(gè)啟動(dòng)模板用于新建的項(xiàng)目(盡管你能手動(dòng)地創(chuàng)建項(xiàng)目并且從nuget獲得ABP包,模板的方式更容易)。

轉(zhuǎn)到www.aspnetboilerplate.com/Templates從模板創(chuàng)建你的應(yīng)用程序。

ABP是什么

你可以選擇SPA(AngularJs或DurandalJs)或者選擇MPA(經(jīng)典的多頁(yè)面應(yīng)用程序)項(xiàng)目??梢赃x擇Entity Framework或NHibernate作為ORM框架。

這里我們選擇AngularJs和Entity Framework,填入項(xiàng)目名稱“SimpleTaskSystem”,點(diǎn)擊“CREATE MY PROJECT”按鈕可以下載一個(gè)zip壓縮包,解壓后得到VS2013的解決方案,使用的.NET版本是 4.5.1。

ABP是什么

每個(gè)項(xiàng)目里引用了Abp組件和其他第三方組件,需要從Nuget下載。

ABP是什么

黃色感嘆號(hào)圖標(biāo),表示這個(gè)組件在本地文件夾中不存在,需要從Nuget上還原。操作如下:

ABP是什么

ABP是什么

要讓項(xiàng)目運(yùn)行起來(lái),還得創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)。這個(gè)模板假設(shè)你正在使用SQL2008或者更新的版本。當(dāng)然也可以很方便地?fù)Q成其他的關(guān)系型數(shù)據(jù)庫(kù)。

打開(kāi)Web.Config文件可以查看和配置鏈接字符串:

<add name="Default" connectionString="Server=localhost; Database=SimpleTaskSystemDb; Trusted_Connection=True;" />

(在后面用到EF的Code first數(shù)據(jù)遷移時(shí),會(huì)自動(dòng)在SQL Server數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)名為SimpleTaskSystemDb的數(shù)據(jù)庫(kù)。)

就這樣,項(xiàng)目已經(jīng)準(zhǔn)備好運(yùn)行了!打開(kāi)VS2013并且按F5:

ABP是什么

下面將逐步實(shí)現(xiàn)這個(gè)簡(jiǎn)單的任務(wù)系統(tǒng)程序

創(chuàng)建實(shí)體

把實(shí)體類寫在Core項(xiàng)目中,因?yàn)閷?shí)體是領(lǐng)域?qū)拥囊徊糠帧?/p>

一個(gè)簡(jiǎn)單的應(yīng)用場(chǎng)景:創(chuàng)建一些任務(wù)(tasks)并分配給人。 我們需要Task和Person這兩個(gè)實(shí)體。

Task實(shí)體有幾個(gè)屬性:描述(Description)、創(chuàng)建時(shí)間(CreationTime)、任務(wù)狀態(tài)(State),還有可選的導(dǎo)航屬性(AssignedPerson)來(lái)引用Person。

public class Task : Entity<long>
{
 [ForeignKey("AssignedPersonId")]
 public virtual Person AssignedPerson { get; set; }

 public virtual int? AssignedPersonId { get; set; }

 public virtual string Description { get; set; }

 public virtual DateTime CreationTime { get; set; }

 public virtual TaskState State { get; set; }

 public Task()
 {
  CreationTime = DateTime.Now;
  State = TaskState.Active;
 }
}

Person實(shí)體更簡(jiǎn)單,只定義了一個(gè)Name屬性:

public class Person : Entity
{
 public virtual string Name { get; set; }
}

在ABP框架中,有一個(gè)Entity基類,它有一個(gè)Id屬性。因?yàn)門ask類繼承自Entity<long>,所以它有一個(gè)long類型的Id。Person類有一個(gè)int類型的Id,因?yàn)閕nt類型是Entity基類Id的默認(rèn)類型,沒(méi)有特別指定類型時(shí),實(shí)體的Id就是int類型。

創(chuàng)建DbContext

使用EntityFramework需要先定義DbContext類,ABP的模板已經(jīng)創(chuàng)建了DbContext文件,我們只需要把Task和Person類添加到IDbSet,請(qǐng)看代碼:

public class SimpleTaskSystemDbContext : AbpDbContext
{
 public virtual IDbSet<Task> Tasks { get; set; }

 public virtual IDbSet<Person> People { get; set; }

 public SimpleTaskSystemDbContext()
  : base("Default")
 {

 }

 public SimpleTaskSystemDbContext(string nameOrConnectionString)
  : base(nameOrConnectionString)
 {
   
 }
}

通過(guò)Database Migrations創(chuàng)建數(shù)據(jù)庫(kù)表

我們使用EntityFramework的Code First模式創(chuàng)建數(shù)據(jù)庫(kù)架構(gòu)。ABP模板生成的項(xiàng)目已經(jīng)默認(rèn)開(kāi)啟了數(shù)據(jù)遷移功能,我們修改SimpleTaskSystem.EntityFramework項(xiàng)目下Migrations文件夾下的Configuration.cs文件:

internal sealed class Configuration : DbMigrationsConfiguration<SimpleTaskSystem.EntityFramework.SimpleTaskSystemDbContext>
{
 public Configuration()
 {
  AutomaticMigrationsEnabled = false;
 }

 protected override void Seed(SimpleTaskSystem.EntityFramework.SimpleTaskSystemDbContext context)
 {
  context.People.AddOrUpdate(
   p => p.Name,
   new Person {Name = "Isaac Asimov"},
   new Person {Name = "Thomas More"},
   new Person {Name = "George Orwell"},
   new Person {Name = "Douglas Adams"}
   );
 }
}

在VS2013底部的“程序包管理器控制臺(tái)”窗口中,選擇默認(rèn)項(xiàng)目并執(zhí)行命令“Add-Migration InitialCreate”

ABP是什么

會(huì)在Migrations文件夾下生成一個(gè)xxxx-InitialCreate.cs文件,內(nèi)容如下:

public partial class InitialCreate : DbMigration
{
 public override void Up()
 {
  CreateTable(
   "dbo.StsPeople",
   c => new
    {
     Id = c.Int(nullable: false, identity: true),
     Name = c.String(),
    })
   .PrimaryKey(t => t.Id);
   
  CreateTable(
   "dbo.StsTasks",
   c => new
    {
     Id = c.Long(nullable: false, identity: true),
     AssignedPersonId = c.Int(),
     Description = c.String(),
     CreationTime = c.DateTime(nullable: false),
     State = c.Byte(nullable: false),
    })
   .PrimaryKey(t => t.Id)
   .ForeignKey("dbo.StsPeople", t => t.AssignedPersonId)
   .Index(t => t.AssignedPersonId);   
 }
  
 public override void Down()
 {
  DropForeignKey("dbo.StsTasks", "AssignedPersonId", "dbo.StsPeople");
  DropIndex("dbo.StsTasks", new[] { "AssignedPersonId" });
  DropTable("dbo.StsTasks");
  DropTable("dbo.StsPeople");
 }
}

然后繼續(xù)在“程序包管理器控制臺(tái)”執(zhí)行“Update-Database”,會(huì)自動(dòng)在數(shù)據(jù)庫(kù)創(chuàng)建相應(yīng)的數(shù)據(jù)表:

PM> Update-Database

數(shù)據(jù)庫(kù)顯示如下:

ABP是什么

(以后修改了實(shí)體,可以再次執(zhí)行Add-Migration和Update-Database,就能很輕松的讓數(shù)據(jù)庫(kù)結(jié)構(gòu)與實(shí)體類的同步)

定義倉(cāng)儲(chǔ)接口

通過(guò)倉(cāng)儲(chǔ)模式,可以更好把業(yè)務(wù)代碼與數(shù)據(jù)庫(kù)操作代碼更好的分離,可以針對(duì)不同的數(shù)據(jù)庫(kù)有不同的實(shí)現(xiàn)類,而業(yè)務(wù)代碼不需要修改。

定義倉(cāng)儲(chǔ)接口的代碼寫到Core項(xiàng)目中,因?yàn)閭}(cāng)儲(chǔ)接口是領(lǐng)域?qū)拥囊徊糠帧?/p>

我們先定義Task的倉(cāng)儲(chǔ)接口:

public interface ITaskRepository : IRepository<Task, long>
{

它繼承自ABP框架中的IRepository泛型接口。

在IRepository中已經(jīng)定義了常用的增刪改查方法:

ABP是什么

所以ITaskRepository默認(rèn)就有了上面那些方法??梢栽偌由纤?dú)有的方法GetAllWithPeople(...)。

不需要為Person類創(chuàng)建一個(gè)倉(cāng)儲(chǔ)類,因?yàn)槟J(rèn)的方法已經(jīng)夠用了。ABP提供了一種注入通用倉(cāng)儲(chǔ)的方式,將在后面“創(chuàng)建應(yīng)用服務(wù)”一節(jié)的TaskAppService類中看到。

實(shí)現(xiàn)倉(cāng)儲(chǔ)類

我們將在EntityFramework項(xiàng)目中實(shí)現(xiàn)上面定義的ITaskRepository倉(cāng)儲(chǔ)接口。

通過(guò)模板建立的項(xiàng)目已經(jīng)定義了一個(gè)倉(cāng)儲(chǔ)基類:SimpleTaskSystemRepositoryBase(這是一種比較好的實(shí)踐,因?yàn)橐院罂梢栽谶@個(gè)基類中添加通用的方法)。

public class TaskRepository : SimpleTaskSystemRepositoryBase<Task, long>, ITaskRepository
{
  public List<Task> GetAllWithPeople(int? assignedPersonId, TaskState? state)
  {
    //在倉(cāng)儲(chǔ)方法中,不用處理數(shù)據(jù)庫(kù)連接、DbContext和數(shù)據(jù)事務(wù),ABP框架會(huì)自動(dòng)處理。
      
    var query = GetAll(); //GetAll() 返回一個(gè) IQueryable<T>接口類型
      
    //添加一些Where條件

    if (assignedPersonId.HasValue)
    {
      query = query.Where(task => task.AssignedPerson.Id == assignedPersonId.Value);
    }

    if (state.HasValue)
    {
      query = query.Where(task => task.State == state);
    }

    return query
      .OrderByDescending(task => task.CreationTime)
      .Include(task => task.AssignedPerson)
      .ToList();
  }
}

TaskRepository繼承自SimpleTaskSystemRepositoryBase并且實(shí)現(xiàn)了上面定義的ITaskRepository接口。

創(chuàng)建應(yīng)用服務(wù)(Application Services)

Application項(xiàng)目中定義應(yīng)用服務(wù)。首先定義Task的應(yīng)用服務(wù)層的接口:

public interface ITaskAppService : IApplicationService
{
  GetTasksOutput GetTasks(GetTasksInput input);
  void UpdateTask(UpdateTaskInput input);
  void CreateTask(CreateTaskInput input);
}

ITaskAppService繼承自IApplicationService,ABP自動(dòng)為這個(gè)類提供一些功能特性(比如依賴注入和參數(shù)有效性驗(yàn)證)。

然后,我們寫TaskAppService類來(lái)實(shí)現(xiàn)ITaskAppService接口:

public class TaskAppService : ApplicationService, ITaskAppService
{
  private readonly ITaskRepository _taskRepository;
  private readonly IRepository<Person> _personRepository;
    
  /// <summary>
  /// 構(gòu)造函數(shù)自動(dòng)注入我們所需要的類或接口
  /// </summary>
  public TaskAppService(ITaskRepository taskRepository, IRepository<Person> personRepository)
  {
    _taskRepository = taskRepository;
    _personRepository = personRepository;
  }
    
  public GetTasksOutput GetTasks(GetTasksInput input)
  {
    //調(diào)用Task倉(cāng)儲(chǔ)的特定方法GetAllWithPeople
    var tasks = _taskRepository.GetAllWithPeople(input.AssignedPersonId, input.State);

    //用AutoMapper自動(dòng)將List<Task>轉(zhuǎn)換成List<TaskDto>
    return new GetTasksOutput
        {
          Tasks = Mapper.Map<List<TaskDto>>(tasks)
        };
  }
    
  public void UpdateTask(UpdateTaskInput input)
  {
    //可以直接Logger,它在ApplicationService基類中定義的
    Logger.Info("Updating a task for input: " + input);

    //通過(guò)倉(cāng)儲(chǔ)基類的通用方法Get,獲取指定Id的Task實(shí)體對(duì)象
    var task = _taskRepository.Get(input.TaskId);

    //修改task實(shí)體的屬性值
    if (input.State.HasValue)
    {
      task.State = input.State.Value;
    }

    if (input.AssignedPersonId.HasValue)
    {
      task.AssignedPerson = _personRepository.Load(input.AssignedPersonId.Value);
    }

    //我們都不需要調(diào)用Update方法
    //因?yàn)閼?yīng)用服務(wù)層的方法默認(rèn)開(kāi)啟了工作單元模式(Unit of Work)
    //ABP框架會(huì)工作單元完成時(shí)自動(dòng)保存對(duì)實(shí)體的所有更改,除非有異常拋出。有異常時(shí)會(huì)自動(dòng)回滾,因?yàn)楣ぷ鲉卧J(rèn)開(kāi)啟數(shù)據(jù)庫(kù)事務(wù)。
  }

  public void CreateTask(CreateTaskInput input)
  {
    Logger.Info("Creating a task for input: " + input);

    //通過(guò)輸入?yún)?shù),創(chuàng)建一個(gè)新的Task實(shí)體
    var task = new Task { Description = input.Description };

    if (input.AssignedPersonId.HasValue)
    {
      task.AssignedPersonId = input.AssignedPersonId.Value;
    }

    //調(diào)用倉(cāng)儲(chǔ)基類的Insert方法把實(shí)體保存到數(shù)據(jù)庫(kù)中
    _taskRepository.Insert(task);
  }
}

TaskAppService使用倉(cāng)儲(chǔ)進(jìn)行數(shù)據(jù)庫(kù)操作,它通往構(gòu)造函數(shù)注入倉(cāng)儲(chǔ)對(duì)象的引用。

數(shù)據(jù)驗(yàn)證

如果應(yīng)用服務(wù)(Application Service)方法的參數(shù)對(duì)象實(shí)現(xiàn)了IInputDto或IValidate接口,ABP會(huì)自動(dòng)進(jìn)行參數(shù)有效性驗(yàn)證。

CreateTask方法有一個(gè)CreateTaskInput參數(shù),定義如下:

public class CreateTaskInput : IInputDto
{
  public int? AssignedPersonId { get; set; }

  [Required]
  public string Description { get; set; }
}

Description屬性通過(guò)注解指定它是必填項(xiàng)。也可以使用其他 Data Annotation 特性。

如果你想使用自定義驗(yàn)證,你可以實(shí)現(xiàn)ICustomValidate 接口:

public class UpdateTaskInput : IInputDto, ICustomValidate
{
  [Range(1, long.MaxValue)]
  public long TaskId { get; set; }

  public int? AssignedPersonId { get; set; }

  public TaskState? State { get; set; }

  public void AddValidationErrors(List<ValidationResult> results)
  {
    if (AssignedPersonId == null && State == null)
    {
      results.Add(new ValidationResult("AssignedPersonId和State不能同時(shí)為空!", new[] { "AssignedPersonId", "State" }));
    }
  }
}

你可以在AddValidationErrors方法中寫自定義驗(yàn)證的代碼。

創(chuàng)建Web Api服務(wù)

ABP可以非常輕松地把Application Service的public方法發(fā)布成Web Api接口,可以供客戶端通過(guò)ajax調(diào)用。

DynamicApiControllerBuilder
  .ForAll<IApplicationService>(Assembly.GetAssembly(typeof (SimpleTaskSystemApplicationModule)), "tasksystem")
  .Build();

SimpleTaskSystemApplicationModule這個(gè)程序集中所有繼承了IApplicationService接口的類,都會(huì)自動(dòng)創(chuàng)建相應(yīng)的ApiController,其中的公開(kāi)方法,就會(huì)轉(zhuǎn)換成WebApi接口方法。

可以通過(guò)http://xxx/api/services/tasksystem/Task/GetTasks這樣的路由地址進(jìn)行調(diào)用。

通過(guò)上面的案例,大致介紹了領(lǐng)域?qū)?、基礎(chǔ)設(shè)施層、應(yīng)用服務(wù)層的用法。

現(xiàn)在,可以在ASP.NET MVC的Controller的Action方法中直接調(diào)用Application Service的方法了。

如果用SPA單頁(yè)編程,可以直接在客戶端通過(guò)ajax調(diào)用相應(yīng)的Application Service的方法了(通過(guò)創(chuàng)建了動(dòng)態(tài)Web Api)。

感謝各位的閱讀!關(guān)于“ABP是什么”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

文章標(biāo)題:ABP是什么-創(chuàng)新互聯(lián)
文章源于:http://jinyejixie.com/article42/dpdoec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、自適應(yīng)網(wǎng)站、微信公眾號(hào)、外貿(mào)網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站營(yíng)銷

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)
永城市| 滦南县| 那曲县| 花莲县| 淅川县| 海伦市| 汶川县| 仁布县| 额济纳旗| 泸溪县| 阿克苏市| 新民市| 镶黄旗| 伊宁县| 平凉市| 陇西县| 筠连县| 孝昌县| 天门市| 宿州市| 饶阳县| 宣汉县| 汝州市| 格尔木市| 融水| 双柏县| 常山县| 博白县| 梅河口市| 错那县| 阳曲县| 平乐县| 嘉义市| 伊金霍洛旗| 花莲县| 轮台县| 建平县| 运城市| 通州市| 武安市| 赤城县|