'Page not found' 我的 NET Core Web 控制器出现错误 API
'Page not found' error on my controller for my NET Core Web API
我在 Visual Studio 2019 年用 C# 编写代码,我正在使用 2019 款 MacBook。我的应用程序是 NET Core Web API 2.2。我的控制器是一个 API 控制器,其操作使用 Entity Framework.
我 运行 我的应用程序在我开始这个项目之前运行良好,我已经连接到我的 sql 服务器,进行了迁移并更新了我的数据库。当我 运行 应用程序没有调试时,它对值控制器工作正常(https://localhost:5001/api/values), but when I type in the name of my 'Loan controller' (https://localhost:5001/api/loan) it gets the HTTP error 'This localhost page can’t be found No web page was found for the web address: https://localhost:5001/api/loan'
这是 LoanController.cs 文件的代码
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using WebAPI.Models;
namespace WebAPI.Controllers
{
public class LoanController : Controller
{
private readonly LoanContext _context;
public LoanController(LoanContext context)
{
_context = context;
}
// GET: Loan
public async Task<IActionResult> Index()
{
return View(await _context.Loans.ToListAsync());
}
// GET: Loan/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var loan = await _context.Loans
.FirstOrDefaultAsync(m => m.LoanCode == id);
if (loan == null)
{
return NotFound();
}
return View(loan);
}
// GET: Loan/Create
public IActionResult Create()
{
return View();
}
// POST: Loan/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("LoanCode,LoanID,BorrowerName,FundingAmount,RepaymentAmount")] Loan loan)
{
if (ModelState.IsValid)
{
_context.Add(loan);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(loan);
}
// GET: Loan/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var loan = await _context.Loans.FindAsync(id);
if (loan == null)
{
return NotFound();
}
return View(loan);
}
// POST: Loan/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("LoanCode,LoanID,BorrowerName,FundingAmount,RepaymentAmount")] Loan loan)
{
if (id != loan.LoanCode)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(loan);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!LoanExists(loan.LoanCode))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(loan);
}
// GET: Loan/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var loan = await _context.Loans
.FirstOrDefaultAsync(m => m.LoanCode == id);
if (loan == null)
{
return NotFound();
}
return View(loan);
}
// POST: Loan/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var loan = await _context.Loans.FindAsync(id);
_context.Loans.Remove(loan);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool LoanExists(int id)
{
return _context.Loans.Any(e => e.LoanCode == id);
}
}
}
这是 ValuesController.cs 文件
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace WebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}
// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
Startup.cs 文件
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Google.Protobuf.WellKnownTypes;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using WebAPI.Models;
namespace WebAPI
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<LoanContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DevConnection")));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
}
}
Launchsetting.JSON 文件
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:41196",
"sslPort": 44395
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WebAPI": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}
您需要添加
[Route("api/[controller]")]
以上
public class LoanController : Controller
这样就可以定位到Loan路由了。这已经适用于您的 ValuesController。
见Microsoft docs - Token replacement in route templates
[controller] 替换为您的控制器的名称 ('Loan'),因为设置了路由,因此这与路由 'api/loan'.
匹配
我在 Visual Studio 2019 年用 C# 编写代码,我正在使用 2019 款 MacBook。我的应用程序是 NET Core Web API 2.2。我的控制器是一个 API 控制器,其操作使用 Entity Framework.
我 运行 我的应用程序在我开始这个项目之前运行良好,我已经连接到我的 sql 服务器,进行了迁移并更新了我的数据库。当我 运行 应用程序没有调试时,它对值控制器工作正常(https://localhost:5001/api/values), but when I type in the name of my 'Loan controller' (https://localhost:5001/api/loan) it gets the HTTP error 'This localhost page can’t be found No web page was found for the web address: https://localhost:5001/api/loan'
这是 LoanController.cs 文件的代码
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using WebAPI.Models;
namespace WebAPI.Controllers
{
public class LoanController : Controller
{
private readonly LoanContext _context;
public LoanController(LoanContext context)
{
_context = context;
}
// GET: Loan
public async Task<IActionResult> Index()
{
return View(await _context.Loans.ToListAsync());
}
// GET: Loan/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var loan = await _context.Loans
.FirstOrDefaultAsync(m => m.LoanCode == id);
if (loan == null)
{
return NotFound();
}
return View(loan);
}
// GET: Loan/Create
public IActionResult Create()
{
return View();
}
// POST: Loan/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("LoanCode,LoanID,BorrowerName,FundingAmount,RepaymentAmount")] Loan loan)
{
if (ModelState.IsValid)
{
_context.Add(loan);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(loan);
}
// GET: Loan/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var loan = await _context.Loans.FindAsync(id);
if (loan == null)
{
return NotFound();
}
return View(loan);
}
// POST: Loan/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("LoanCode,LoanID,BorrowerName,FundingAmount,RepaymentAmount")] Loan loan)
{
if (id != loan.LoanCode)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(loan);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!LoanExists(loan.LoanCode))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(loan);
}
// GET: Loan/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var loan = await _context.Loans
.FirstOrDefaultAsync(m => m.LoanCode == id);
if (loan == null)
{
return NotFound();
}
return View(loan);
}
// POST: Loan/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var loan = await _context.Loans.FindAsync(id);
_context.Loans.Remove(loan);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool LoanExists(int id)
{
return _context.Loans.Any(e => e.LoanCode == id);
}
}
}
这是 ValuesController.cs 文件
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace WebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}
// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
Startup.cs 文件
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Google.Protobuf.WellKnownTypes;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using WebAPI.Models;
namespace WebAPI
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<LoanContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DevConnection")));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
}
}
Launchsetting.JSON 文件
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:41196",
"sslPort": 44395
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WebAPI": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}
您需要添加
[Route("api/[controller]")]
以上
public class LoanController : Controller
这样就可以定位到Loan路由了。这已经适用于您的 ValuesController。
见Microsoft docs - Token replacement in route templates
[controller] 替换为您的控制器的名称 ('Loan'),因为设置了路由,因此这与路由 'api/loan'.
匹配