为什么Visual Studio会自动创建具有所有异步方法的ApiController?如何创建包含同步方法的 ApiC



我创建了一个名为StudentsController的 asp.net 核心webapi控制器.cs使用Visual Studio提供的功能,Visual Studio是带有操作的API控制器,使用实体框架。它实现了所有返回类型async Task<ActionResult<>>的控制器方法,这是异步方法实现,它是由Visual Studio自动生成

的问题是为什么它自己异步创建所有方法,以及如何使用Visual Studio的相同自动生成功能同步创建所有方法?

控制器的异步示例

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Students.Models;
namespace Students.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class StudentsController : ControllerBase
{
private readonly StudentContext _context;
public StudentsController(StudentContext context)
{
_context = context;
}
// GET: api/Students
[HttpGet]
public async Task<ActionResult<IEnumerable<Student>>> GetStudents()
{
return await _context.Students.Include(d => d.Department).ToListAsync();
}
// GET: api/Students/5
[HttpGet("{id}")]
public async Task<ActionResult<Student>> GetStudent(int id)
{
var student = await _context.Students.Include(d => d.Department).FirstOrDefaultAsync(i => i.SId == id);
if (student == null)
{
return NotFound();
}
return student;
}
// PUT: api/Students/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPut("{id}")]
public async Task<IActionResult> PutStudent(int id, Student student)
{
if (id != student.SId)
{
return BadRequest();
}
_context.Departments.Update(student.Department);
await _context.SaveChangesAsync();
_context.Entry(student).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!StudentExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return Ok();
}
//[HttpPut]
//public async Task<IActionResult> PutStudent(Student student)
//{
//    _context.Departments.Update(student.Department);
//    await _context.SaveChangesAsync();
//    _context.Entry(student).State = EntityState.Modified;
//    try
//    {
//        await _context.SaveChangesAsync();
//    }
//    catch (DbUpdateConcurrencyException)
//    {
//        if (!StudentExists(student.SId))
//        {
//            return NotFound();
//        }
//        else
//        {
//            throw;
//        }
//    }
//    return Ok();
//}
// POST: api/Students
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPost]
public async Task<ActionResult<Student>> PostStudent(Student student)
{
_context.Students.Add(student);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudent", new { id = student.SId }, student);
}

[HttpPost]
[Route("StudentList")]
public async Task<ActionResult<Student>> PostStudentList([FromBody] List<Student> student)
{
try
{
foreach (Student s in student)
{
_context.Students.Add(s);
}
_context.SaveChanges();
return CreatedAtAction("GetStudents", student, _context.Students.Include(d => d.Department));
}
catch(Exception ex)
{
return BadRequest();
}
}
// DELETE: api/Students/5
[HttpDelete("{id}")]
public async Task<ActionResult<Student>> DeleteStudent(int id)
{
var student = await _context.Students.FindAsync(id);
if (student == null)
{
return NotFound();
}
_context.Students.Remove(student);
await _context.SaveChangesAsync();
return student;
}
private bool StudentExists(int id)
{
return _context.Students.Any(e => e.SId == id);
}
}
}

控制器同步示例

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CourseCRUD.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace CourseCRUD.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SubjectController : Controller
{
private readonly CourseContext _context;
public SubjectController(CourseContext context)
{
_context = context;
}
[HttpGet]
// GET:api/subject
public IActionResult GetSubjects()
{
try
{
var subjects = _context.subjects.ToList();
return Ok(subjects);
}
catch
{
return BadRequest();
}
}
[HttpPost]
public IActionResult AddSubject([FromBody]Subject subject)
{
try
{
_context.subjects.Add(subject);
_context.SaveChanges();
return CreatedAtAction("GetSubjets", subject);
}
catch
{
return BadRequest();
}
}
[HttpGet("{id}")]
public IActionResult GetSuject(int id)
{
try
{
var subject = _context.subjects.Find(id);
return Ok(subject);
}
catch
{
return BadRequest();
}
}
[HttpPut("id")]
[HttpPut("{id}")]
public IActionResult UpdateSubject(int id, Subject subject)
{
if (id != subject.SubjectId)
{
return BadRequest();
}
_context.Entry(subject).State = EntityState.Modified;
try
{
_context.SaveChanges();
return Ok(subject);
}
catch (DbUpdateConcurrencyException)
{
if (!SubjectDetailExist(id))
{
return NotFound();
}
else
{
throw;
}
}
}
private bool SubjectDetailExist(int id)
{
throw new NotImplementedException();
}
[HttpDelete("{id}")]
public IActionResult DeleteSubject(int id)
{
var result = _context.subjects.Find(id);
if (result == null)
{
return NotFound();
}
_context.subjects.Remove(result);
try
{
_context.SaveChanges();
return Ok(result);
}
catch
{
return BadRequest();
}
}
}
}```

我已经很久没有用 t4 模板做任何事情了,所以有点生疏,但你也许应该从这里开始

https://learn.microsoft.com/en-us/visualstudio/modeling/code-generation-and-t4-text-templates?view=vs-2019

您可以在文本文件中指定模板,并使用规则生成所需的代码。

<#@ output extension=".cs" #>
<#@ assembly name="System.Xml" #>
<#
System.Xml.XmlDocument configurationData = ...; // Read a data file here.
#>
namespace Fabrikam.<#= configurationData.SelectSingleNode("jobName").Value #>
{
... // More code here.
}

根据 XML 文件中的值,生成的.cs文件将类似于以下内容:

namespace Fabrikam.FirstJob
{
... // More code here.
}

我不知道控制器脚手架是否使用 t4 模板,但它不会让我感到惊讶.. 或类似的东西。

async动作由脚手架模板生成,该模板位于类似于C:ProgramFilesdotnetsdkNuGetFallbackFoldermicrosoft.visualstudio.web.codegenerators.mvc2.0.3Templates的路径中

您可以手动更改模板。指 https://stackoverflow.com/a/39503291/10158551

最新更新