C# 为什么VisualStudio会使用所有异步方法自动创建ApicController?如何创建包含同步方法的ApicController?
我已经使用Visual Studio提供的功能创建了一个名为StudentsController.cs的asp.net核心webapi控制器,该功能是API控制器和操作,使用实体框架。它使用返回类型C# 为什么VisualStudio会使用所有异步方法自动创建ApicController?如何创建包含同步方法的ApicController?,c#,asynchronous,asp.net-core-webapi,visual-studio-2019,synchronous,C#,Asynchronous,Asp.net Core Webapi,Visual Studio 2019,Synchronous,我已经使用Visual Studio提供的功能创建了一个名为StudentsController.cs的asp.net核心webapi控制器,该功能是API控制器和操作,使用实体框架。它使用返回类型async Task实现所有控制器方法,这是一种异步方法实现,由Visual Studio自动生成 问题是为什么它自己创建所有异步方法,以及如何使用Visual Studio的相同自动生成功能同步创建所有方法? 控制器的异步示例 using System.Collections.Generic; us
async Task
实现所有控制器方法,这是一种异步方法实现,由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模板做任何事情了,所以有点生疏,但你也许应该从这里开始 您可以在文本文件中指定模板,并使用规则生成所需的代码
<#@ 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.
}
我不知道控制器脚手架是否使用t4模板,但我不会感到惊讶。。或类似的操作。异步操作由脚手架模板生成,脚手架模板位于类似于
C:\ProgramFiles\dotnet\sdk\NuGetFallbackFolder\microsoft.visualstudio.web.codegenerators.mvc\2.0.3\templates的路径中。
您可以手动更改模板。请参阅
可能是因为大多数web应用程序都使用数据库调用、对其他服务的调用等。因此,如果使用异步调用,它允许服务器处理更多请求(因为在等待数据库响应时不会阻塞线程等)。那是我的猜测。为什么要使所有方法同步?请详细说明您的答案,并说明如何使用Visual Studio的相同自动代码生成功能同步控制器示例中给出的同步创建所有方法?**和**我想创建所有同步,因为此实现是我在一家公司接受培训的一部分,并且我被要求再次区分这两种类型的实现:我只是猜测为什么它们都是异步的。我不知道你怎么能做到这一点,我也不明白你为什么要这么做。“为什么它创建所有的异步方法”-因为它更好™如果您被赋予了区分两种类型控制器的任务,那么只需创建一个
aysnc
并创建一个副本,您就可以将其更改为sync
。。。。为什么你要为自己做更多的工作来两次创造一切?
namespace Fabrikam.FirstJob
{
... // More code here.
}