繁体   English   中英

为什么 Visual Studio 会使用所有异步方法自动创建 ApiController? 如何创建带有同步方法的 ApiController?

[英]Why Visual Studio automatically creates ApiController with all async methods? How to create ApiController with sync methods in it?

使用 Entity Framework 使用Visual Studio 提供的功能创建了一个名为StudentsController.cs的 asp.net 核心 webapi 控制器,该功能是带有操作的 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://docs.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:\\ProgramFiles\\dotnet\\sdk\\NuGetFallbackFolder\\microsoft.visualstudio.web.codegenerators.mvc\\2.0.3\\Templates路径中

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM