[{"data":1,"prerenderedAt":466},["ShallowReactive",2],{"note-\u002Fnotes\u002Fsync\u002Fcsharp-resoucehub-resourcescontroller-cs":3},{"id":4,"title":5,"body":6,"category":452,"date":453,"description":454,"draft":455,"extension":456,"meta":457,"navigation":50,"path":458,"seo":459,"sourcePath":460,"stem":461,"tags":462,"__hash__":465},"notes\u002Fnotes\u002Fsync\u002Fcsharp-開發-resoucehub-resourcescontroller-cs.md","ResourcesController.cs",{"type":7,"value":8,"toc":443},"minimark",[9,224,236,247,262,265,296,305,340,346,357,366,387,393,398,404,410,415,430,439],[10,11,16],"pre",{"className":12,"code":13,"language":14,"meta":15,"style":15},"language-csharp shiki shiki-themes github-light github-dark","using Microsoft.EntityFrameworkCore;\nusing Microsoft.AspNetCore.Mvc;\nusing ResourceHub.Data;\nusing ResourceHub.Models;\n\nnamespace ResourceHub.Controllers\n{\n\n    [Route(\"api\u002F[controller]\")]\n    [ApiController]\n    public class ResourcesController(AppDbContext context) : ControllerBase\n    {\n\n        [HttpGet]\n        public async Task\u003CActionResult\u003CIEnumerable\u003CResource>>> GetResources()\n        {\n            return await context.Resources.ToListAsync();\n        }\n\n        [HttpPost]\n        public async Task\u003CActionResult\u003CResource>> PostResource(Resource resource)\n        {\n\n            \u002F\u002F 2. 直接使用 context\n            context.Resources.Add(resource);\n\n            await context.SaveChangesAsync();\n\n            return CreatedAtAction(\n                nameof(GetResources), \n                new { id = resource.Id }, resource\n            );\n        }\n    }\n}\n\n","csharp","",[17,18,19,27,33,39,45,52,58,64,69,75,81,87,93,98,104,110,116,122,128,133,139,145,150,155,161,167,172,178,183,189,195,201,207,212,218],"code",{"__ignoreMap":15},[20,21,24],"span",{"class":22,"line":23},"line",1,[20,25,26],{},"using Microsoft.EntityFrameworkCore;\n",[20,28,30],{"class":22,"line":29},2,[20,31,32],{},"using Microsoft.AspNetCore.Mvc;\n",[20,34,36],{"class":22,"line":35},3,[20,37,38],{},"using ResourceHub.Data;\n",[20,40,42],{"class":22,"line":41},4,[20,43,44],{},"using ResourceHub.Models;\n",[20,46,48],{"class":22,"line":47},5,[20,49,51],{"emptyLinePlaceholder":50},true,"\n",[20,53,55],{"class":22,"line":54},6,[20,56,57],{},"namespace ResourceHub.Controllers\n",[20,59,61],{"class":22,"line":60},7,[20,62,63],{},"{\n",[20,65,67],{"class":22,"line":66},8,[20,68,51],{"emptyLinePlaceholder":50},[20,70,72],{"class":22,"line":71},9,[20,73,74],{},"    [Route(\"api\u002F[controller]\")]\n",[20,76,78],{"class":22,"line":77},10,[20,79,80],{},"    [ApiController]\n",[20,82,84],{"class":22,"line":83},11,[20,85,86],{},"    public class ResourcesController(AppDbContext context) : ControllerBase\n",[20,88,90],{"class":22,"line":89},12,[20,91,92],{},"    {\n",[20,94,96],{"class":22,"line":95},13,[20,97,51],{"emptyLinePlaceholder":50},[20,99,101],{"class":22,"line":100},14,[20,102,103],{},"        [HttpGet]\n",[20,105,107],{"class":22,"line":106},15,[20,108,109],{},"        public async Task\u003CActionResult\u003CIEnumerable\u003CResource>>> GetResources()\n",[20,111,113],{"class":22,"line":112},16,[20,114,115],{},"        {\n",[20,117,119],{"class":22,"line":118},17,[20,120,121],{},"            return await context.Resources.ToListAsync();\n",[20,123,125],{"class":22,"line":124},18,[20,126,127],{},"        }\n",[20,129,131],{"class":22,"line":130},19,[20,132,51],{"emptyLinePlaceholder":50},[20,134,136],{"class":22,"line":135},20,[20,137,138],{},"        [HttpPost]\n",[20,140,142],{"class":22,"line":141},21,[20,143,144],{},"        public async Task\u003CActionResult\u003CResource>> PostResource(Resource resource)\n",[20,146,148],{"class":22,"line":147},22,[20,149,115],{},[20,151,153],{"class":22,"line":152},23,[20,154,51],{"emptyLinePlaceholder":50},[20,156,158],{"class":22,"line":157},24,[20,159,160],{},"            \u002F\u002F 2. 直接使用 context\n",[20,162,164],{"class":22,"line":163},25,[20,165,166],{},"            context.Resources.Add(resource);\n",[20,168,170],{"class":22,"line":169},26,[20,171,51],{"emptyLinePlaceholder":50},[20,173,175],{"class":22,"line":174},27,[20,176,177],{},"            await context.SaveChangesAsync();\n",[20,179,181],{"class":22,"line":180},28,[20,182,51],{"emptyLinePlaceholder":50},[20,184,186],{"class":22,"line":185},29,[20,187,188],{},"            return CreatedAtAction(\n",[20,190,192],{"class":22,"line":191},30,[20,193,194],{},"                nameof(GetResources), \n",[20,196,198],{"class":22,"line":197},31,[20,199,200],{},"                new { id = resource.Id }, resource\n",[20,202,204],{"class":22,"line":203},32,[20,205,206],{},"            );\n",[20,208,210],{"class":22,"line":209},33,[20,211,127],{},[20,213,215],{"class":22,"line":214},34,[20,216,217],{},"    }\n",[20,219,221],{"class":22,"line":220},35,[20,222,223],{},"}\n",[225,226,228,231,232,235],"h3",{"id":227},"route-與-apicontroller-是什麼",[17,229,230],{},"[Route]"," 與 ",[17,233,234],{},"[ApiController]"," 是什麼？",[237,238,239],"blockquote",{},[240,241,242,243],"p",{},"在 C# 中稱為 ",[244,245,246],"strong",{},"「特性 (Attribute)」",[240,248,249,250,253,254,257,258,261],{},"對應到 JavaScript \u002F TypeScript \u002F Angular 的世界，它就完完全全是 ",[244,251,252],{},"「裝飾器 (Decorator)」","（例如 Angular 的 ",[17,255,256],{},"@Component"," 或 NestJS 的 ",[17,259,260],{},"@Controller","）。",[240,263,264],{},"做底層的自動化設定：",[266,267,268,276],"ul",{},[269,270,271,275],"li",{},[244,272,273],{},[17,274,234],{},"：告訴 .NET 說「這是一個 API 控制器，不是用來回傳 HTML 網頁的」。加上它之後，.NET 會自動幫你做很多事，例如：當前端傳來的 JSON 格式不對時，它會自動攔截並回傳 HTTP 400 (Bad Request)，你連檢查的程式碼都不用寫。",[269,277,278,283,284,287,288,291,292,295],{},[244,279,280],{},[17,281,282],{},"[Route(\"api\u002F[controller]\")]","：設定這支 API 的網址路徑。裡面的 ",[17,285,286],{},"[controller]"," 是一個動態變數，.NET 會自動抓取這個類別的名稱（去掉 \"Controller\" 字尾）。因為你的類別叫 ",[17,289,290],{},"ResourcesController","，所以這支 API 的路由就會自動變成 ",[17,293,294],{},"api\u002FResources","。",[225,297,299,231,302],{"id":298},"controllerbase-與-aspnetcoremvc",[17,300,301],{},"ControllerBase",[17,303,304],{},"AspNetCore.Mvc",[266,306,307,313],{},[269,308,309,312],{},[17,310,311],{},"ResourcesController : ControllerBase"," 代表繼承。",[269,314,315,317,318],{},[17,316,301],{}," 是微軟寫好的基礎類別，裡面包含了所有寫 API 需要用到的工具。例如\n",[266,319,320,325,330,335],{},[269,321,322],{},[17,323,324],{},"CreatedAtAction()",[269,326,327],{},[17,328,329],{},"Ok()",[269,331,332],{},[17,333,334],{},"NotFound()",[269,336,337],{},[17,338,339],{},"BadRequest()",[225,341,343],{"id":342},"task",[17,344,345],{},"Task",[237,347,348],{},[240,349,350,351,353,354],{},"C# 裡的 ",[17,352,345],{},"，完完全全就等於 JS 裡的 ",[17,355,356],{},"Promise",[240,358,359,360,363,364,295],{},"在 C# 裡只要你的方法使用了 ",[17,361,362],{},"async","，它的回傳型別就必須是 ",[17,365,345],{},[266,367,368,378],{},[269,369,370,371,374,375,377],{},"JS 的 ",[17,372,373],{},"Promise\u003Cvoid>"," 👉 C# 的 ",[17,376,345],{},"（沒有回傳值，只等它做完）",[269,379,370,380,374,383,386],{},[17,381,382],{},"Promise\u003CT>",[17,384,385],{},"Task\u003CT>","（有回傳值）",[225,388,390],{"id":389},"actionresult",[17,391,392],{},"ActionResult",[237,394,395],{},[240,396,397],{},"HTTP 回應包裝盒",[240,399,400,401,295],{},"ASP.NET Core 提供的一個特殊型別，它允許這個方法",[244,402,403],{},"不只能回傳資料，還能回傳 HTTP 狀態碼",[225,405,407],{"id":406},"ienumerable",[17,408,409],{},"IEnumerable",[237,411,412],{},[240,413,414],{},"可疊代的集合",[240,416,417,418,423,424,295,427,429],{},"在 C# 裡，只要看到大寫的 ",[244,419,420],{},[17,421,422],{},"I"," 開頭，就代表它是一個 ",[244,425,426],{},"介面 (Interface)",[17,428,409],{}," 的意思是「這是一個可以被逐一讀取 (列舉\u002F疊代) 的集合」。",[240,431,432,435,436,438],{},[244,433,434],{},"為什麼不用 List 或 Array？"," 因為 ",[17,437,409],{}," 是一種「抽象」的保證。它告訴呼叫端：「我會給你一包 Resource，你可以用迴圈 (foreach) 把裡面的東西拿出來，但你不需要管我底層是用陣列還是清單實作的。」這種寫法在 C# 中被認為是耦合度最低、最優雅的標準寫法。",[440,441,442],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":15,"searchDepth":29,"depth":29,"links":444},[445,447,449,450,451],{"id":227,"depth":35,"text":446},"[Route] 與 [ApiController] 是什麼？",{"id":298,"depth":35,"text":448},"ControllerBase 與 AspNetCore.Mvc",{"id":342,"depth":35,"text":345},{"id":389,"depth":35,"text":392},{"id":406,"depth":35,"text":409},"backend","2026-08-09","using Microsoft.EntityFrameworkCore;",false,"md",{},"\u002Fnotes\u002Fsync\u002Fcsharp-resoucehub-resourcescontroller-cs",{"title":5,"description":454},"C#\u002F開發\u002FResouceHub\u002FResourcesController.cs.md","notes\u002Fsync\u002Fcsharp-開發-resoucehub-resourcescontroller-cs",[463,464],"C#","Practice","tdl1_J6pDRE4s1hTJ5xcr4uhRVP7P-65C_QM2fuaOtU",1788767747535]