Asp.Net Core 通过 Ajax 提交表单时获得 500 状态。无需 Ajax 即可完美运行

发布于 2025-01-17 06:02:56 字数 4285 浏览 0 评论 0原文

我有一个非常简单的表单 - 只有三个字段,其中只有两个字段由用户通过下拉菜单填写。第三个自动标记为 DateTime.Now。我使用了来自其他表单的一些脚手架的表单提交代码。当我将该代码放入 Home 控制器中(显然是在更改了一些代码之后)并构建了表单时,一切都提交得很好。所以我知道我的人脉和道路都很好。

但是,提交后,它会刷新整个页面。我不能这样。它只需要刷新页面上的特定 div 即可。所以,我必须通过 Ajax 来运行它。这就是我失去一半头发的地方......

当我记录通过 Ajax 传入的值时,获得了正确的值,但随后我收到了“Home/CreateBreak”的 500 错误,这是就在控制器中的位置。以下是所有代码和控制台在 Chrome 中的外观的屏幕截图。预先感谢您的帮助。

Home Controller:(创建条目时仅填写 TimeEntered、EmployeeId 和 EmpPosition)。

     //Create//
    [HttpPost]
    public async Task<IActionResult> CreateBreak([Bind("Id,TimeEntered,TimeCleared,EmpSent,EmployeeId,EmpPosition,RlfPosition")] Break newBreak)
    {
        if (ModelState.IsValid)
        {
            newBreak.TimeEntered = DateTime.Now;
            _context.Add(newBreak);
            await _context.SaveChangesAsync();
            return Json(new { success = true, });
        }
           
        else
        {
            return Json(new { success = false });
        }                
    }

Ajax:

//Add Break
$(document).on("click", "#break_submit", function () {
    var model = {};
    model.EmployeeId = Number($("#EmpId").val());
    model.EmpPosition = Number($("#EmployeePosition").val());
    console.log("model", model);
    $.ajax({
        type: "Post",
        url: "/Home/CreateBreak",
        dataType: 'json',
        data: JSON.stringify(model),
        success: function (data) {
            if (data.success)
            {
                $(" #headerRefresh ").load(window.location.href + " #headerRefresh ");
                $(" .dthRefresh ").load(window.location.href + " .dthRefresh ");
            }
            else
                alert("Error: Please enter your name AND position");
        },
        error: function () {
            alert("Error: Please enter your name AND position");
        }
    });
});

表单:

@model Seating.ViewModels.ListsVM

<form id="ajax_submit" class="DthdropdownGroup ml-3">
    <div class="btn-group" style="margin-left:-1rem">
        <select class="form-group dropdownStyling btn-sm dropdown-toggle d-inline-block btn-outline-light" style="width: 7.4em;" id="EmpId">
            <option disabled selected>Dispatcher</option>
            @foreach (var item in Model.Employees)
            {
                <option class="dropdown-item pr-1 form-control" value="@item.Id">@item.DisplayName</option>
            }
        </select>
    </div>

    <div class="btn-group">
        <select class="form-group dropdownStyling btn-sm dropdown-toggle d-inline-block btn-outline-light" style="width: 7.3em" id="EmployeePosition">
            <option disabled selected>Position</option>
            @foreach (var item in Model.Positions)
            {
                <option class="dropdown-item pr-1" value="@item.Id">@item.PositionName</option>
            }
        </select>
    </div>
    <button type="button" class="btn btn-sm btn-block dropdownStyling" id="break_submit" style="margin-left: -1rem; width:15rem;">Submit</button>
</form>

填充下拉列表的虚拟机(适用于所有表单 - 不仅仅是这个):

namespace Seating.ViewModels
{
    public class ListsVM
    {
        public ListsVM()
        {
            Employees = new List<Employee>();
            Positions = new List<Position>();
        }
        public IEnumerable<Dth> Dths { get; set; }
        public IEnumerable<Break> Breaks { get; set; }
        public IEnumerable<Lunch> Lunches { get; set; }
        public IEnumerable<Employee> Employees { get; set; }
        public IEnumerable<Position> Positions { get; set; }

        public int EmployeeId { get; set; }
        public int EmpPosition { get; set; }
        public bool EmpSent { get; set; }
        public bool LunchTime { get; set; }
        public bool LongerLunch { get; set; }
        public bool DblLunch { get; set; }
    }
}

以及屏幕截图。您可以看到日志显示员工 ID 3 和职位 3 - 这是完美的。但随后它会感到困惑,无法弄清楚从那里该去哪里——尽管我准确地告诉了它该去哪里。

输入图片此处描述

再次感谢

I have a very simple form - just three fields and only two of them are filled in by the user via dropdowns. The third is automatically stamped with DateTime.Now. I used the form submit code from some scaffolding I already had in place for other forms. When I put that code into the Home controller (after changing some of the code, obviously) and built the form, everything submits great. So I know my connections and paths are all good.

However, after it submits, it refreshes the whole page. I can't have that. It needs to just refresh specific divs on the page. So, I have to run it through Ajax. Here's where I've lost half the hair on my head...

When I log the values being passed in through Ajax, the correct values are being obtained but then I'm getting a 500 error for "Home/CreateBreak", which is right where it is in the controller. Here's all the code and a screenshot of how the console looks in Chrome. Thank you in advance for any help.

Home Controller: (Only the TimeEntered, EmployeeId and EmpPosition are filled when the entry is created).

     //Create//
    [HttpPost]
    public async Task<IActionResult> CreateBreak([Bind("Id,TimeEntered,TimeCleared,EmpSent,EmployeeId,EmpPosition,RlfPosition")] Break newBreak)
    {
        if (ModelState.IsValid)
        {
            newBreak.TimeEntered = DateTime.Now;
            _context.Add(newBreak);
            await _context.SaveChangesAsync();
            return Json(new { success = true, });
        }
           
        else
        {
            return Json(new { success = false });
        }                
    }

Ajax:

//Add Break
$(document).on("click", "#break_submit", function () {
    var model = {};
    model.EmployeeId = Number($("#EmpId").val());
    model.EmpPosition = Number($("#EmployeePosition").val());
    console.log("model", model);
    $.ajax({
        type: "Post",
        url: "/Home/CreateBreak",
        dataType: 'json',
        data: JSON.stringify(model),
        success: function (data) {
            if (data.success)
            {
                $(" #headerRefresh ").load(window.location.href + " #headerRefresh ");
                $(" .dthRefresh ").load(window.location.href + " .dthRefresh ");
            }
            else
                alert("Error: Please enter your name AND position");
        },
        error: function () {
            alert("Error: Please enter your name AND position");
        }
    });
});

Form:

@model Seating.ViewModels.ListsVM

<form id="ajax_submit" class="DthdropdownGroup ml-3">
    <div class="btn-group" style="margin-left:-1rem">
        <select class="form-group dropdownStyling btn-sm dropdown-toggle d-inline-block btn-outline-light" style="width: 7.4em;" id="EmpId">
            <option disabled selected>Dispatcher</option>
            @foreach (var item in Model.Employees)
            {
                <option class="dropdown-item pr-1 form-control" value="@item.Id">@item.DisplayName</option>
            }
        </select>
    </div>

    <div class="btn-group">
        <select class="form-group dropdownStyling btn-sm dropdown-toggle d-inline-block btn-outline-light" style="width: 7.3em" id="EmployeePosition">
            <option disabled selected>Position</option>
            @foreach (var item in Model.Positions)
            {
                <option class="dropdown-item pr-1" value="@item.Id">@item.PositionName</option>
            }
        </select>
    </div>
    <button type="button" class="btn btn-sm btn-block dropdownStyling" id="break_submit" style="margin-left: -1rem; width:15rem;">Submit</button>
</form>

VM that fills the dropdowns (for all the forms - not just this one):

namespace Seating.ViewModels
{
    public class ListsVM
    {
        public ListsVM()
        {
            Employees = new List<Employee>();
            Positions = new List<Position>();
        }
        public IEnumerable<Dth> Dths { get; set; }
        public IEnumerable<Break> Breaks { get; set; }
        public IEnumerable<Lunch> Lunches { get; set; }
        public IEnumerable<Employee> Employees { get; set; }
        public IEnumerable<Position> Positions { get; set; }

        public int EmployeeId { get; set; }
        public int EmpPosition { get; set; }
        public bool EmpSent { get; set; }
        public bool LunchTime { get; set; }
        public bool LongerLunch { get; set; }
        public bool DblLunch { get; set; }
    }
}

And, the screenshot. You can see the logs are showing Employee Id 3 and Position 3 - which is perfect. But then it gets confused and can't figure out where to go from there - even though I told it exactly where to go.

enter image description here

Thanks again

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧人九事 2025-01-24 06:02:56

恕我直言,您使用 Model 结构不必要地使 Controller 方法上的事情变得复杂。由于您只需将 EmployeeIdEmpPosition 变量发送到 Controller 方法,

//Add Break
$(document).on("click", "#break_submit", function () {
    var EmployeeId = Number($("#EmpId").val());
    var EmpPosition = Number($("#EmployeePosition").val());
    var json = {
            EmployeeId: EmployeeId,
            EmpPosition: EmpPosition
        };
    console.log("Model", json);
    $.ajax({
        type: "post",
        //url: "/Home/CreateBreak",
        url: "@Url.Action("CreateBreak", "Home")",
        dataType: "json",
        data: {"json": JSON.stringify(json)},
        success: function (data) {
            if (data.success)
            {
                $(" #headerRefresh ").load(window.location.href + " #headerRefresh ");
                $(" .dthRefresh ").load(window.location.href + " .dthRefresh ");
            }
            else
                alert("Error: Please enter your name AND position");
        },
        error: function () {
            alert("Error: Please enter your name AND position");
        }
    });
});

因此 您可以执行以下操作: code> 方法将如下所示:

 //Create//
[HttpPost]
public async Task<IActionResult> CreateBreak(string json)
{
    Break newBreak=new Break();
    int EmployeeId=0;
    int EmpPosition=0;
    
    if(!string.IsNullOrEmpty(json))
    {
        var jsonData = JsonConvert.DeserializeObject<dynamic>(json);
        EmployeeId = Convert.ToInt32(jsonData.EmployeeId);
        EmpPosition = Convert.ToInt32(jsonData.EmpPosition);
        
        newBreak.EmployeeId = EmployeeId;
        newBreak.EmpPosition = EmpPosition;
        
        if (ModelState.IsValid)
        {
            newBreak.TimeEntered = DateTime.Now;
            _context.Add(newBreak);
            await _context.SaveChangesAsync();
            return Json(new { success = true, });
        }
           
        else
        {
            return Json(new { success = false });           
        } 
    }
    else
    {
        return Json(new { success = false });   
    }             
}

IMHO, you are unnecessarily complicating things on your Controller method using a Model structure. Since you only need to send your EmployeeId and EmpPosition variables to your Controller method, you can do this:

//Add Break
$(document).on("click", "#break_submit", function () {
    var EmployeeId = Number($("#EmpId").val());
    var EmpPosition = Number($("#EmployeePosition").val());
    var json = {
            EmployeeId: EmployeeId,
            EmpPosition: EmpPosition
        };
    console.log("Model", json);
    $.ajax({
        type: "post",
        //url: "/Home/CreateBreak",
        url: "@Url.Action("CreateBreak", "Home")",
        dataType: "json",
        data: {"json": JSON.stringify(json)},
        success: function (data) {
            if (data.success)
            {
                $(" #headerRefresh ").load(window.location.href + " #headerRefresh ");
                $(" .dthRefresh ").load(window.location.href + " .dthRefresh ");
            }
            else
                alert("Error: Please enter your name AND position");
        },
        error: function () {
            alert("Error: Please enter your name AND position");
        }
    });
});

And your Controller method will look like this:

 //Create//
[HttpPost]
public async Task<IActionResult> CreateBreak(string json)
{
    Break newBreak=new Break();
    int EmployeeId=0;
    int EmpPosition=0;
    
    if(!string.IsNullOrEmpty(json))
    {
        var jsonData = JsonConvert.DeserializeObject<dynamic>(json);
        EmployeeId = Convert.ToInt32(jsonData.EmployeeId);
        EmpPosition = Convert.ToInt32(jsonData.EmpPosition);
        
        newBreak.EmployeeId = EmployeeId;
        newBreak.EmpPosition = EmpPosition;
        
        if (ModelState.IsValid)
        {
            newBreak.TimeEntered = DateTime.Now;
            _context.Add(newBreak);
            await _context.SaveChangesAsync();
            return Json(new { success = true, });
        }
           
        else
        {
            return Json(new { success = false });           
        } 
    }
    else
    {
        return Json(new { success = false });   
    }             
}
无戏配角 2025-01-24 06:02:56

来自 ASP.NET 的 500 可能意味着在处理请求时的某个时刻抛出了未处理的异常。
我建议你将调试器附加到网络服务器进程
如果您还仔细检查 URL 是否正确,将会有所帮助。

A 500 from ASP.NET probably means an unhandled exception was thrown at some point when serving the request.
I suggest you attach a debugger to the webserver process
It would help if you also double-checked that the URL is correct.

画▽骨i 2025-01-24 06:02:56

您有错误,因为您的操作输入参数为空。从 ajax 中删除 JSON.stringify(model)

$.ajax({
        type: "Post",
        url: "/Home/CreateBreak",
        dataType: 'json',
        data: model,
        success: function (data) {
         .....

或者如果您想使用 json,则添加 contentType: application/json

$.ajax({
        type: "Post",
        url: "/Home/CreateBreak",
        dataType: 'json',
        contentType: 'application/json; charset=utf-8',
        data: JSON.stringify(model),
        success: function (data) {
        ...

并将 [FromBody] 添加到操作

public async Task<IActionResult> CreateBreak([FromBody] Break newBreak)

you have an error, since your action input parameters are empty. Remove JSON.stringify(model) from ajax

$.ajax({
        type: "Post",
        url: "/Home/CreateBreak",
        dataType: 'json',
        data: model,
        success: function (data) {
         .....

or if you want to use json then add contentType: application/json

$.ajax({
        type: "Post",
        url: "/Home/CreateBreak",
        dataType: 'json',
        contentType: 'application/json; charset=utf-8',
        data: JSON.stringify(model),
        success: function (data) {
        ...

and add [FromBody] to an action

public async Task<IActionResult> CreateBreak([FromBody] Break newBreak)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文