【问题标题】:Razor pages and webapi in the same project同一项目中的 Razor 页面和 webapi
【发布时间】:2019-10-11 09:56:23
【问题描述】:

我在 .net core 3.0 中创建了一个 Web 应用程序(剃须刀页面)。然后我向它添加了一个 api 控制器(都来自模板,只需点击几下)。当我运行应用程序时,剃须刀页面可以正常工作,但 api 调用返回 404。问题出在哪里,如何使其正常工作?

【问题讨论】:

标签: c# asp.net-core


【解决方案1】:

您需要配置您的启动以支持 web api 和属性路由。

services.AddControllers() 添加了对控制器和 API 相关功能的支持,但不支持视图或页面。参考MVC service registration

如果应用使用属性路由,请添加 endpoints.MapControllers。参考Migrate MVC controllers

结合 razor pages 和 api like:

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();
        });
    }

【讨论】:

    【解决方案2】:

    除了the answer of @Ryan,我还必须添加一个带有控制器/动作模式的默认路由。否则无法访问控制器,直到我在其上设置了 [Route("example")] 装饰器。由于我更喜欢​​在 MVC 中生成基于模式的路由,因此我在 Startup.Configure 中定义了默认路由,如下所示:

    app.UseEndpoints(endpoints => {
        endpoints.MapRazorPages();
        endpoints.MapControllerRoute("default", "api/{controller=Home}/{action=Index}/{id?}");
        endpoints.MapControllers();
    });
    

    拥有一个名为CommunityController 的控制器,您现在可以在/api/community/index 处访问索引操作,或者只需使用短格式/api/community,因为索引 被定义为路由中的默认操作。

    另外,还需要在ConfigureServices方法中添加控制器组件,如@Ryan所示:

    public void ConfigureServices(IServiceCollection services) {
        services.AddRazorPages();
        services.AddControllers();
        // ...
    }
    

    使用 ASP.NET Core 3.1 Razor 页面进行测试。

    【讨论】:

      【解决方案3】:

      将 WebApi 添加到您现有的 dot net core 2 razor pages 应用程序并配置身份验证方案。 如果您计划在您的 .net Web 应用程序中添加 webapi,那么您将需要为您的应用程序配置两种身份验证方案,例如 JWT Token auth 以保护 webapi 和 cookie auth 网页。

      要添加 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);
          }
      }
      }
      

      启动配置: 首先你必须在 Startup.cs 中添加身份验证方案配置 您必须同时添加 cookie 和 jwt 令牌配置,但您可以选择其中任何一个作为默认方案,在这种情况下,我们必须选择 cookie 方案作为默认方案,这将应用于所有没有明确指定的方案,要在 webapi 上使用 jwt 方案,我们必须明确指定。

      添加身份

      services.AddIdentity<ApplicationUser, IdentityRole>()
                  .AddEntityFrameworkStores<ProductContext>()
                  .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"));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 2021-05-31
        • 2022-01-10
        • 2022-06-16
        • 1970-01-01
        • 2021-02-24
        • 1970-01-01
        相关资源
        最近更新 更多