当我尝试在我的项目中上传 post 时遇到 405 错误

I'm encountering a 405 Error when I try to upload a post on my project

我在尝试上传 post 到我的开发博客时遇到问题。我正在尝试使用 MVC 框架上传 Post。我正在尝试遵循大量关于如何构建博客的指南。

这是Postclass

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace ProjectWebApp.Models
{
    public class Post
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int PostID { get; set; }
        [Required]
        public string Title { get; set; }
        [Required]
        public string Content { get; set; }
        public string Author { get; set; }
        public int Likes { get; set; }
        [Required]
        public DateTime DateCreated { get; set; }
        public DateTime? DateUpdated { get; set; }
        public ICollection<PostTag> PostTags { get; set; }
    }
}

这里是 BlogDBContext:


using Project.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ProjectBlogWebApp.Data
{
    public class BlogDbContext : DbContext
    {
        public BlogDbContext(DbContextOptions<BlogDbContext> options) : base(options)
        {
            Database.EnsureDeleted();
            if (Database.EnsureCreated() == true)
            {
                Database.EnsureCreated();
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<PostTag>().HasKey(p => new {p.PostID, p.TagID});
            modelBuilder.Entity<PostTag>().HasOne(pt => pt.Post).WithMany(p => p.PostTags)
                .HasForeignKey(pt => pt.PostID);
            modelBuilder.Entity<PostTag>().HasOne(pt => pt.Tag).WithMany(t => t.PostTags)
                .HasForeignKey(pt => pt.TagID);
        }



        public DbSet<Post> Posts { get; set; }

        public DbSet<Tag> Tags { get; set; }

        public DbSet<PostTag> PostTags { get; set; }
    }
}

这是Post控制器class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ProjectWebApp.Data;
using ProjectWebApp.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.EntityFrameworkCore;

namespace ProjectWebApp.Controllers
{
    public class PostController : Controller
    {
        private BlogDbContext _dbBlogContext;

        public PostController(BlogDbContext dbContext)
        {
            _dbBlogContext = dbContext;
        }

        public IActionResult Index()
        {
            var postList = _dbBlogContext.Posts.ToList();

            return View(postList);
        }
        [HttpGet, Route("Create")]
        public IActionResult Create()
        {
            return View(new Post());
        }

        [HttpGet, Route("Edit")]
        public IActionResult Edit()
        {
            
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> CreatePostAsync([Bind("Title", "Content")] Post post)
        {
            try 
            {
                post.Likes = 0;
                post.DateCreated = DateTime.Now;
                post.Author = "Leonard Morrison";
                _dbBlogContext.Add(post);
                await _dbBlogContext.SaveChangesAsync();

                
            }

            catch (DbUpdateException)
            {
                ModelState.TryAddModelError( "Error: Post was not added properly!", "Sorry, the Post was not added properly. Please let me know if this problem persists");
            }

            return View(post);
        }

        [HttpGet]
        public IActionResult Show(int ID)
        {
            var post = getPost(ID);
            return View(post);
        }

        [HttpGet]
        public IActionResult Edit(int ID)
        {
            var post = getPost(ID);
            return View(post);
        }
        [HttpPatch]
        public IActionResult Update(int id)
        {
            var post = _dbBlogContext.Posts.Find(id);
            _dbBlogContext.Posts.Update(post);
            return RedirectToAction("Index");
            
        }

        [HttpDelete]
        public IActionResult RemovePost(int id)
        {
            Post deletedPost = getPost(id);

            _dbBlogContext.Posts.Remove(deletedPost);

            _dbBlogContext.SaveChanges();

            return RedirectToAction("Index");
        }


        public Post getPost(int ID)
        {
            var post = _dbBlogContext.Posts.First(p => p.PostID == ID);

            return post;
        }

    }
}


最后,这是启动源代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ProjectWebApp.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Http;


namespace ProjectBlogWebApp
{
    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.AddControllersWithViews();


            services.AddDbContext<BlogDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddScoped<BlogDbContext, BlogDbContext>();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // 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.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            //The Main EndPoint Routes
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id}");
            });
            
            //The Post Endpoints Routes
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(name: "post",
                    pattern: "{controller=Post}/{action=Index}/{title?}");

            });
        }
    }
}


因为不知道具体错误在哪里。但是我需要知道这个 405 错误是从哪里来的。

谢谢。

检查您的创建视图 (Create.cshtml) 以确保在您的表单标记中 asp-action="CreatePostAsync"。

如果这不是问题,请同时包含您的查看代码。

在CreatePostAsync也打个断点,跟着往下看哪里出错了。可能没有触发操作。也就是说,你的断点也不会被触发。

很少有其他事情可以帮助解决问题 and/or 项目:

  • BlogDbContext: OnModelCreating(),那些代码是用来表示外键的?只要 属性 名称是 {TableName}Id,EF 就会自动 created/mapped 外键。您也可以通过使用 ForeignKey
  • 的 [ForeignKey] 属性来明确
  • 控制器:您可以组合方法和路由 [HttpGet("Create")]。我确定这不是问题,但只是想让您知道
  • Create():不需要将新的 Post 模型传递给 view(),因为您的视图已经有“@model Post”
  • CreatePostAsync():我建议创建一个具有必要属性和验证检查的 PostViewModel。使用 PostViewModel 作为参数。这也意味着您需要将创建视图从 @model Post 更新为 @model PostViewModel
  • CreatePostAsync():总是在 post 方法完成处理后将其重定向回 get。只有在出现错误时才应该 return View() 。否则,用户可以垃圾邮件刷新并创建多行数据。一旦您开始使用 Create,就亲自尝试一下

The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed response status code indicates that the request method is known by the server but is not supported by the target resource.

生成的Url是"localhost:5001/Create",只匹配Create Get方法,而form发送的是HttpPost Request,所以出现405错误。

1.You 可以在您的表单标签上添加 asp-action="CreatePost"

2.Or 只需在您的 CreatePost 操作中添加相同的路由属性

[HttpPost]
[Route("Create")]
public async Task<IActionResult> CreatePostAsync([Bind("Title", "Content")] Post post)