Asp.net core Razor页面和webapi在同一个项目中
我在.NETCore3.0中创建了一个web应用程序(RazorPages)。然后我添加了一个api控制器(都来自模板,只需点击几下)。当我运行应用程序时,razor页面工作,但api调用返回404。问题出在哪里?我如何使其工作?您需要将启动配置为支持web api和属性路由Asp.net core Razor页面和webapi在同一个项目中,asp.net-core,Asp.net Core,我在.NETCore3.0中创建了一个web应用程序(RazorPages)。然后我添加了一个api控制器(都来自模板,只需点击几下)。当我运行应用程序时,razor页面工作,但api调用返回404。问题出在哪里?我如何使其工作?您需要将启动配置为支持web api和属性路由 services.AddControllers()增加了对控制器和API相关功能的支持,但不支持视图或页面。参考 如果应用程序使用属性路由,则添加endpoints.MapControllers。参考 结合razor页面和
services.AddControllers()
增加了对控制器和API相关功能的支持,但不支持视图或页面。参考
如果应用程序使用属性路由,则添加endpoints.MapControllers
。参考
结合razor页面和api,如:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
});
services.AddRazorPages()
.AddNewtonsoftJson();
services.AddControllers()
.AddNewtonsoftJson();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//other middlewares
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
}
public void配置服务(IServiceCollection服务)
{
配置(选项=>
{
//此lambda确定给定请求是否需要非必要cookie的用户同意。
options.checkApprovered=context=>true;
});
services.AddRazorPages()
.AddNewtonsoftJson();
services.AddControllers()
.AddNewtonsoftJson();
}
public void配置(IApplicationBuilder应用程序、IWebHostEnvironment环境)
{
//其他中间产品
app.UseEndpoints(端点=>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
}
将WebApi添加到现有的dot net core 2 razor pages应用程序中,并配置身份验证方案。
如果您计划在.net web应用程序中添加webapi,则需要为您的应用程序配置两种身份验证方案,例如用于保护webapi的JWT令牌身份验证和cookie身份验证网页
要添加Web api,请进入控制器部分,创建名为api的新文件夹和其中的新控制器,例如OrderController
添加控制器后,必须为所有api请求调用指定身份验证方案,例如JWT和路由路径前缀,例如“api/”
控制器代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ApplicationCore.Entities.OrderAggregate;
using Infrastructure.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
namespace WebRazorPages.Controllers.Api
{
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Produces("application/json")]
[Route("api/Orders")]
public class OrdersController : Controller
{
private readonly ProductContext _context;
public OrdersController(ProductContext context)
{
_context = context;
}
// GET: api/OrdersApi
[HttpGet]
public IEnumerable<Order> GetOrders()
{
return _context.Orders;
}
// GET: api/OrdersApi/5
[HttpGet("{id}")]
public async Task<IActionResult> GetOrder([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var order = await _context.Orders.SingleOrDefaultAsync(m => m.Id == id);
if (order == null)
{
return NotFound();
}
return Ok(order);
}
// PUT: api/OrdersApi/5
[HttpPut("{id}")]
public async Task<IActionResult> PutOrder([FromRoute] int id, [FromBody] Order order)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != order.Id)
{
return BadRequest();
}
_context.Entry(order).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!OrderExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/OrdersApi
[HttpPost]
public async Task<IActionResult> PostOrder([FromBody] Order order)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.Orders.Add(order);
await _context.SaveChangesAsync();
return CreatedAtAction("GetOrder", new { id = order.Id }, order);
}
// DELETE: api/OrdersApi/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteOrder([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var order = await _context.Orders.SingleOrDefaultAsync(m => m.Id == id);
if (order == null)
{
return NotFound();
}
_context.Orders.Remove(order);
await _context.SaveChangesAsync();
return Ok(order);
}
private bool OrderExists(int id)
{
return _context.Orders.Any(e => e.Id == id);
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Http;
使用Microsoft.AspNetCore.Mvc;
使用Microsoft.EntityFrameworkCore;
使用ApplicationCore.Entities.OrderAggregate;
使用基础设施。数据;
使用Microsoft.AspNetCore.Authorization;
使用Microsoft.AspNetCore.Authentication.JwtBearer;
命名空间WebRazorPages.Controllers.Api
{
[授权(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)]
[产生(“应用程序/json”)]
[路线(“api/订单”)]
公共类OrdersController:控制器
{
私有只读ProductContext\u上下文;
公共医嘱控制器(ProductContext上下文)
{
_上下文=上下文;
}
//获取:api/OrdersApi
[HttpGet]
公共IEnumerable GetOrders()
{
返回_context.Orders;
}
//获取:api/OrdersApi/5
[HttpGet(“{id}”)]
公共异步任务GetOrder([FromRoute]int id)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
var order=wait_context.Orders.SingleOrDefaultAsync(m=>m.Id==Id);
if(order==null)
{
返回NotFound();
}
返回Ok(订单);
}
//PUT:api/OrdersApi/5
[HttpPut(“{id}”)]
公共异步任务PutOrder([FromRoute]int id,[FromBody]Order)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
if(id!=order.id)
{
返回请求();
}
_context.Entry(order).State=EntityState.Modified;
尝试
{
wait_context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
如果(!OrderExists(id))
{
返回NotFound();
}
其他的
{
投掷;
}
}
返回NoContent();
}
//邮政编码:api/OrdersApi
[HttpPost]
公共异步任务PostOrder([FromBody]订单)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
_context.Orders.Add(订单);
wait_context.SaveChangesAsync();
返回CreateDataAction(“GetOrder”,新的{id=order.id},order);
}
//删除:api/OrdersApi/5
[HttpDelete(“{id}”)]
公共异步任务DeleteOrder([FromRoute]int id)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
var order=wait_context.Orders.SingleOrDefaultAsync(m=>m.Id==Id);
if(order==null)
{
返回NotFound();
}
_context.Orders.Remove(订单);
wait_context.SaveChangesAsync();
返回Ok(订单);
}
私有bool OrderExists(int-id)
{
返回_context.Orders.Any(e=>e.Id==Id);
}
}
}
启动配置:
首先,您必须在Startup.cs中添加身份验证方案配置
您必须添加cookie和jwt令牌配置,但您可以选择其中任何一个作为默认方案。在这种情况下,我们必须选择cookie方案作为默认方案,该方案将应用于所有应用程序,而无需显式指定。要在webapi上使用jwt方案,我们必须显式指定
添加标识
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ProductContext>()
.AddDefaultTokenProviders();
services.AddIdentity()
.AddEntityFrameworkStores()
.AddDefaultTokenProviders();
配置Cookie
services.ConfigureApplicationCookie(options =>
{
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromHours(1);
options.LoginPath = "/Account/Signin";
options.LogoutPath = "/Account/Signout";
});
services.AddAuthentication(
options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddJwtBearer(config =>
{
config.RequireHttpsMetadata = false;
config.SaveToken = true;
config.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = Configuration["jwt:issuer"],
ValidAudience = Configuration["jwt:issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["jwt:key"]))
};
});
services.Configure<JwtOptions>(Configuration.GetSection("jwt"));
services.configureApplicationOK(选项=>
{
options.Cookie.HttpOnly=true;
options.ExpireTimeSpan=TimeSpan.FromHours(1);
options.LoginPath=“/Account/Signin”;
options.LogoutPath=“/Account/Signout”;
});
services.AddAuthentication(
选项=>
{
options.DefaultScheme=CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme=CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
添加
app.UseEndpoints(endpoints => {
endpoints.MapRazorPages();
endpoints.MapControllerRoute("default", "api/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllers();
});
public void ConfigureServices(IServiceCollection services) {
services.AddRazorPages();
services.AddControllers();
// ...
}