2016-10-05 43 views
1

我想在aspnetcore 1.0.1中實現一個基本的REST控制器(類似NancyFx的靈感),感覺這應該是可以用這樣的可組合框架實現的東西,然而,我只是不能正確地做對。谷歌foo今天顯然很弱!繼承來自抽象REST控制器的http動詞屬性

我有以下基本控制器(顯然還沒有完全實現)...

[Route("api/[controller]")] 
public abstract class RestApiController<T> : Controller 
{ 
    protected abstract Func<int, Task<T>> Get { get; } 
    protected abstract Func<Task<IEnumerable<T>>> List { get; } 

    [HttpGet()] 
    protected virtual async Task<IEnumerable<T>> OnList() 
    { 
     if (this.List == null) 
     { 
      this.NotFound(); 
     } 

     return await this.List.Invoke(); 
    } 

    [HttpGet("{id:int}")] 
    protected virtual async Task<T> OnGet(int id) 
    { 
     if (this.Get == null) 
     { 
      this.NotFound(); 
     } 

     return await this.Get.Invoke(id); 
    } 
} 

這是由實際控制人做的工作繼承...

public class ArticleSummariesController : RestApiController<ArticleExtension> 
{ 
    private readonly ArticleManager articleManager; 

    protected override Func<int, Task<ArticleExtension>> Get => null; 
    protected override Func<Task<IEnumerable<ArticleExtension>>> List => this.ListAll; 

    public ArticleSummariesController(ArticleManager articleManager) 
    { 
     this.articleManager = articleManager; 
    } 

    private async Task<IEnumerable<ArticleExtension>> ListAll() 
    { 
     return await this.articleManager.GetAllAsync(); 
    } 

} 

的想法是基地控制人員將負責處理實際的請求,但將責任委託給其子女提供和操作數據。這樣我們就可以確保REST在請求中一致,但將來自控制器的域邏輯鬆散地耦合到充當門面並採取存儲庫和應用業務邏輯的「管理者」。

到目前爲止,代碼的問題是基類上的HttpGet()屬性不會爲子類生成路由。雖然基類的控制器路由屬性被繼承(如docs所述)。

回答

0

再一次,答案是盯着我的臉!我有父方法聲明爲保護不公開,所以他們不認爲合格的行動!

閱讀更多關於應用模型here之後這一切變得清晰......

ActionModel - 表示控制器的動作。 這個類的實例是爲控制器上的每個符合條件的操作而創建的。有 是一個方法成爲一個行動的多個要求,如 是公開的,非抽象的,而不是從對象繼承。

因此,修改後的代碼下面的作品...

[Route("api/[controller]")] 
public abstract class RestApiController<T> : Controller 
{ 
    protected abstract Func<int, Task<T>> Get { get; } 
    protected abstract Func<Task<IEnumerable<T>>> List { get; } 

    [HttpGet()] 
    public virtual async Task<IEnumerable<T>> OnList() 
    { 
     if (this.List == null) 
     { 
      this.NotFound(); 
     } 

     return await this.List.Invoke(); 
    } 

    [HttpGet("{id:int}")] 
    public virtual async Task<T> OnGet(int id) 
    { 
     if (this.Get == null) 
     { 
      this.NotFound(); 
     } 

     return await this.Get.Invoke(id); 
    } 
} 

public class ArticleSummariesController : RestApiController<ArticleExtension> 
{ 
    private readonly ArticleManager articleManager; 

    protected override Func<int, Task<ArticleExtension>> Get => null; 
    protected override Func<Task<IEnumerable<ArticleExtension>>> List => this.ListAll; 

    public ArticleSummariesController(ArticleManager articleManager) 
    { 
     this.articleManager = articleManager; 
    } 

    private async Task<IEnumerable<ArticleExtension>> ListAll() 
    { 
     return await this.articleManager.GetAllAsync(); 
    } 

} 
0

我可能是錯的,但我立即假定您需要基類或子類上的RouteAttribute。例如:

[Route("api/[controller]")] 
public abstract class RestApiController<T> : Controller 
{ 
    protected abstract Func<int, Task<T>> Get { get; } 
    protected abstract Func<Task<IEnumerable<T>>> List { get; } 

    [HttpGet, Route("list")] 
    protected virtual async Task<IEnumerable<T>> OnList() 
    { 
     if (this.List == null) 
     { 
      this.NotFound(); 
     } 

     return await this.List.Invoke(); 
    } 

    [HttpGet, Route("get/{id:int}")] 
    protected virtual async Task<T> OnGet(int id) 
    { 
     if (this.Get == null) 
     { 
      this.NotFound(); 
     } 

     return await this.Get.Invoke(id); 
    } 
} 
+0

與路由屬性的問題是我就失去了REST像URL。例如。 GET api/articlesummaries而不是api/arriclesummaries/list。雖然路由屬性確實繼承了http動詞屬性,但它不會 –