为什么当我使用 JQuery .ajax() 方法将用户凭据发布到 C# 控制器时出现 HTTP 400(错误请求)错误?(ASP.NET Mvc Kestrel)



介绍一下我有什么

你好,所以我想在c#中创建一个红隼web应用程序,根据用户的信息注册用户,他们通过在HTML页面中填写输入框提供的信息。

<<h3>重要文件/类/h3>页面位于名为"wwwroot"的文件夹中,该文件夹位于应用程序的根目录中。使用JQuery语法的文件内容如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="Design/registerStyle.css" />
<script src="https://code.jquery.com/jquery-3.6.1.js" 
integrity="sha256-3zlB5s2uwoUzrXK3BT7AX3FyvojsraNFxCc2vC/7pNI=" 
crossorigin="anonymous"></script>
<title>Register</title>
</head>
<body>
<form>
<div class="container">
<h1>Register</h1>
<p>Please fill in this form to create an account.</p>
<hr>
<label for="uname"><b>User Name</b></label>
<input type="text" placeholder="Enter Your User Name" name="uname" id="uname" required>

<hr>
<p>By creating an account you agree to our <a href="#">Terms & Privacy</a>.</p>
<button type="button" class="registerbtn" id="regbtn">Register</button>
</div>
<div class="container signin">
<p>Already have an account? <a href="login.html">Sign in</a>.</p>
</div>
</form>
<script>
$('#regbtn').click(function () {
let user_name = $('#uname').val();
let stringified_data = JSON.stringify(user_name);
$.ajax({
url: '/session/regist',
type: 'POST',
data: stringified_data,
success: function (response) {
console.log('Success', response);
},
fail: function (failed) {
console.log('Failed', failed);
}
});
});
</script>
</body>
</html>

这不是唯一的html页面…但我认为这在这个问题中并不重要。这只是一个样板寄存器窗口。

通过注册,我的意思是我想把这些凭证放入一个名为database.db的数据库文件中,就这么简单…下面是SQL语法,以便您了解结构:

CREATE TABLE User (
`UserID` INTEGER PRIMARY KEY AUTOINCREMENT
, `UserName` TEXT NOT NULL    
)

我只创建了两个单元格,因为我还不想处理太多的数据。该数据库文件位于一个名为database的文件夹中,该文件夹位于应用程序的根目录中。我需要使用Sqlite与EntityFramework,因为我的教授说,我们不能使用PHP和任何其他类似的。我正在使用"数据库浏览器SQLite"检查数据。

因此,我在一个名为Controllers的文件夹中创建了一个SessionController类,该文件夹位于应用程序的根目录中:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.Sqlite;
using System.ComponentModel;
namespace WebApplication3.Controllers
{
[ApiController]
public class SessionController : Controller
{
[HttpPost, Route("/session/regist")]
public IActionResult AddUserToDatabase([FromForm] string UserName)
{
try
{
/* Establish connection with database */
using var connection = new SqliteConnection("Data source=database.db");
connection.Open();
using var command = connection.CreateCommand();
command.CommandText = "insert into " +
"User " +
"( `UserName`) " +
"values " +
"(@username);";

/* Add parameters with value */
command.Parameters.AddWithValue("@username", UserName);
/* Execute the SQL command and close connection */
command.ExecuteNonQuery();
connection.Close();
}
catch(Exception ex) {
Console.WriteLine(ex.Message);
return  Redirect("/page/registerFailed.html");
}
return Redirect("/page/registerSuccess.html");
}
}
}

这个控制器很简单:建立连接,创建SQL命令,然后在打开的数据库上执行它,关闭数据库,然后将用户重定向到指定的HTML页面。

在这个文件夹中还有一个控制器类,叫做HomeController:

using Microsoft.AspNetCore.Mvc;
namespace WebApplication3.Controllers
{
public class HomeController : Controller
{
[HttpGet, Route("")]
public IActionResult Login()
{
return Redirect("/page/login.html");
}
}
}

当应用程序加载时,重定向到登录HTML页面。

关于启动应用程序的类…我有一个程序和一个启动类在一个单独的c#文件,在应用程序的根目录。Program类:

using Starting.Start;
namespace Starting.Prog
{
public class Program
{
/* Builds and runs the app with the help of the HostBoulder methods */
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
/* Builds the application using the Startup class */
public static IHostBuilder CreateHostBuilder(string[] args) => 
Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(web_builder =>
{
web_builder.UseStartup<Startup>();
});
}
}

该类构建应用程序,然后在中间件所在的Startup类的帮助下运行它。Startup类:

using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.FileProviders;
namespace Starting.Start
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddMvcOptions(options =>
{
options.RespectBrowserAcceptHeader= true;
options.InputFormatters.Add(new XmlSerializerInputFormatter(options));
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});
}

/* Configure the app middleware */
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

/* Gets the root directory */
string root_directory = Directory.GetCurrentDirectory();
/* Gets the directory where the html files are located */
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(root_directory, "wwwroot")),
RequestPath = "/page"
});
/* Enables routing */
app.UseRouting();

/* Specifying the endpoints */
app.UseEndpoints(endpoints =>
{
/* Starter page (login.html) */
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Login}"                  
);

/* Create the route for the registration method */
endpoints.MapControllerRoute(
name: "Session",
pattern: "/session/regist",
defaults: new { controller = "Session", action = "AddUserToDatabase" }
);
});

}
}
}

这样就加载了初始页面(也就是login.html)。

问题是,当我点击register.html上的注册按钮调用JQuery .ajax()方法,我得到一个HTTP 400(坏请求)错误。请看下面的截图:

输入图片描述

我试了什么?

所以我首先尝试传递用户在ajax方法中输入的基本值(我没有对输入数据进行字符串化),并且……我得到了同样的错误。然后,我在SessionController类中的AddUserToDatabase方法上方指定了一个属性标记,它告诉我们它所使用的数据类型:

[HttpPost, Route("/session/regist"), Consumes("application/json")]
public IActionResult AddUserToDatabase([FromForm] string UserName)
{      
Here is the user registration....
}

这给了我一个不同的错误…不支持的媒体类型(HTTP 415错误)。接下来我做的事……我在ajax方法中指定了数据和内容类型,只是在方法末尾添加:

dataType: "json",
contentType: "application/json"

还是同样的错误。

在这之后我卡住了,我不知道从这一点开始在网络上移动到哪里,或者我应该做什么。

你能告诉我哪些地方需要申报或做不同的,并提供一些提示或来源告诉我哪里做错了吗?提前感谢!

只需更改您发布的数据格式,如下所示:

$('#regbtn').click(function () {
let user_name = $('#uname').val();
let stringified_data = { UserName: user_name };  //change here....
$.ajax({
url: '/session/regist',
type: 'POST',
data: stringified_data,
success: function (response) {
console.log('Success', response);
},
fail: function (failed) {
console.log('Failed', failed);
}
});
});

后端代码应该保持如下:

[HttpPost, Route("/session/regist")]
public IActionResult AddUserToDatabase([FromForm] string UserName)
{ 
//...
}

顺便说一句,Ajax无法处理服务器端重定向,您需要在ajax.success()函数中使用window.location.href,如下所示:

$.ajax({
url: '/session/regist',
type: 'POST',
data: stringified_data,
success: function (response) {
window.location.href = response.url;   //add here...
},
fail: function (failed) {
console.log('Failed', failed);
}
});
后端代码应该如下所示:
[HttpPost, Route("/session/regist")]
public IActionResult AddUserToDatabase([FromForm] string UserName)
{     
//....
return Json(new { url= "/page/registerSuccess.html" });
}

相关内容

最新更新