Home > Blockchain >  Asp.Net Core Getting a 500 status when submitting a form through Ajax. Works perfectly without Ajax
Asp.Net Core Getting a 500 status when submitting a form through Ajax. Works perfectly without Ajax

Time:03-28

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" >
    <div  style="margin-left:-1rem">
        <select  style="width: 7.4em;" id="EmpId">
            <option disabled selected>Dispatcher</option>
            @foreach (var item in Model.Employees)
            {
                <option  value="@item.Id">@item.DisplayName</option>
            }
        </select>
    </div>

    <div >
        <select  style="width: 7.3em" id="EmployeePosition">
            <option disabled selected>Position</option>
            @foreach (var item in Model.Positions)
            {
                <option  value="@item.Id">@item.PositionName</option>
            }
        </select>
    </div>
    <button type="button"  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

CodePudding user response:

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.

CodePudding user response:

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)

CodePudding user response:

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 });   
    }             
}
  • Related