昨天興高采烈地試著使用 Scaffolding 自動產生 Web API 控制器的動作方法,但是卻發生了如下圖所示的錯誤:
看來是將 Domain Model 與 DbContext 分開成兩個專案所造成的,解決的方法就是重改架構將這兩個專案合併成一個,否則就是自己動手寫。幾經思量之後決定修改架構,所以今天就來試看看怎麼改。
模仿是為了創新
動手開始改之前還是參考一下別人是怎麼做的,最後改成如下圖所示的架構:
將 Demae.Domain 與 Demae.Data 兩個專案,以一個 Demae.Core 取代,原先寫在 Demae.Domain 的檔案改成寫在 Entities 資料夾底下,而寫在 Demae.Data 的檔案改成寫在 Data 資料夾底下,其他的都一樣。在這裡就沒有一步一步地再示範如何寫了,建議讀者可以回朔參考先前的文章,順便也做個複習。
註:
阿源哥哥上課時,很喜歡跟學生講《模仿是為了創新》這句話,當不知道該如何做時,參考一下別人如何做的,多抄(模仿)幾次就會有自己的構想(創新)了。
阿源哥哥上課時,很喜歡跟學生講《模仿是為了創新》這句話,當不知道該如何做時,參考一下別人如何做的,多抄(模仿)幾次就會有自己的構想(創新)了。
新增控制器
接著如圖所示順序,使用選用【使用 Entity Framework 執行動作的 API 控制器】,讓開發工具為我們產生所有的程式碼:
成功了,產生一堆程式碼了:
[Produces("application/json")]
[Route("api/Addresses")]
public class AddressesController : Controller
{
private readonly DemaeContext _context;
public AddressesController(DemaeContext context)
{
_context = context;
}
// GET: api/Addresses
[HttpGet]
public IEnumerable<Address> GetAddresses()
{
return _context.Addresses;
}
// GET: api/Addresses/5
[HttpGet("{id}")]
public async Task<IActionResult> GetAddress([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var address = await _context.Addresses.SingleOrDefaultAsync(m => m.Id == id);
if (address == null)
{
return NotFound();
}
return Ok(address);
}
// PUT: api/Addresses/5
[HttpPut("{id}")]
public async Task<IActionResult> PutAddress([FromRoute] int id, [FromBody] Address address)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != address.Id)
{
return BadRequest();
}
_context.Entry(address).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!AddressExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/Addresses
[HttpPost]
public async Task<IActionResult> PostAddress([FromBody] Address address)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.Addresses.Add(address);
await _context.SaveChangesAsync();
return CreatedAtAction("GetAddress", new { id = address.Id }, address);
}
// DELETE: api/Addresses/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteAddress([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var address = await _context.Addresses.SingleOrDefaultAsync(m => m.Id == id);
if (address == null)
{
return NotFound();
}
_context.Addresses.Remove(address);
await _context.SaveChangesAsync();
return Ok(address);
}
private bool AddressExists(int id)
{
return _context.Addresses.Any(e => e.Id == id);
}
}
好吧!今天暫時先做到這裡,明天再來逐步分析這些程式碼,並實際測試新增、修改、刪除、查詢地址資料的動作。
註:
阿源哥哥向來是個能少打一些程式碼就盡量少打,如果有工具,有範本、有程式碼片段,可以幫助減少敲程式碼的次數的話,都會盡量使用。但是這些工具所產生出來的程式碼有時也不見得百分之百合用,所以徹底了解工具所產生的程式碼,有助於日後的改良。
阿源哥哥向來是個能少打一些程式碼就盡量少打,如果有工具,有範本、有程式碼片段,可以幫助減少敲程式碼的次數的話,都會盡量使用。但是這些工具所產生出來的程式碼有時也不見得百分之百合用,所以徹底了解工具所產生的程式碼,有助於日後的改良。