簡體   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