Search code examples
ajaxrazorentity-framework-coreasp.net-core-mvc.net-6.0

Cannot send TempData back to same view after Ajax Post action in .NET 6


Fair warning, I lack the fundamental understanding of how controllers work and reading about them for hours doesn't seem to help. This is probably terrible design. However, all I want to accomplish seems like it should be fairly simple, but I have not made any progress.

Setup is VS 2022 with basic ASP.NET Core 6 MVC web app and EF Core 6.

Every feature of this application will be on a single static page, using a single form.

What I need is the form to auto-populate readonly input fields on text update so the user has confirmation they scanned the right product into the app, these will also be submitted with the form's final post.

All functionality works up to the point where the user entered field sends value back to the home controller on update and the controller performs the query to find the correct values. It breaks when the http POST action tries to send this data back to the view.

I've tried many methods of getting value back, but cant get it to read client side. TempData appears to work so I can see it with C# code in the view, but not modify existing client markup.

Here are my relevant controller pieces

public IActionResult Index()
{
    return View();
}

[HttpPost]
public IActionResult GetItem(string value)
{
    //item is assigned single string value from db
    item = //dbquery

    TempData["Message"] = item;

    // Tried changing this to a few different return types but nothing seems to change
    return View("Index");
}

The models are all auto-generated files from scaffolding and work great

In the view, I temporarily have all the js logic that sends the data back. I am only using ajax because it was the only way I could find to get real time data back to the controller without using a form/button post. The ajax call does open the right controller action and sends the right data to it, but I cannot find a way to read the new TempData value from the controller back to the view:

<script type="text/javascript">
        function SendInput(sn) {   
                $.ajax({
                    type: "POST",
                    url: '@Url.Action("GetItem")',
                    data: { inputID: sn.target.value },
                    dataType: "text",
                });
                
                @{
                // tempval here does get assigned the proper item
                var tempval = TempData["Message"];
                if (tempval != null) 
                    {
                        //this code never generates or updates data on the view
                        @:var temp = @tempval.ToString();
                        @:$('#item').val(temp);
                    }
                }     
        }

        const serial = document.getElementById('InputID');
        serial.addEventListener('input', SendInput);         
</script>

Edit: adding the rest of the HTML

@using ScanForm.Models;
// temp table for form submission. This page will eventually read and write to many tables
@model InvItem


@{
    ViewData["Title"] = "Scan Form";
}

// Form submit controller not implemented yet
<div>
    <form method="POST" asp-controller="Home" asp-action="Add">
        <div class="row w-50 form-group">
            <div class="col mb-3">
                <label class="col-form-label" asp-for="InputID">Serial #</label>
                <input type="text" class="form-control" id="InputID" asp-for="InputID">
                <small id="" class="form-text text-muted"></small>
            </div>
            <div class="col mb-3">
                <label class="col-form-label" asp-for="Model">Item</label>
                <input type="text" class="form-control" id="item" readonly>
                <small id="" class="form-text text-muted"></small>
            </div>
            <div class="mb-3">
                <button type="submit" class="btn btn-primary">Submit</button>
            </div>
        </div>
    </form>
</div>

Solution

  • Try:

    [HttpPost]
    public IActionResult GetItem(string value)
    {
        //item is assigned single string value from db
        item = //dbquery
    
       return Json(item);
    }
    

    Then add success: function in your ajax code like:

     $.ajax({
                        type: "POST",
                        url: '@Url.Action("GetItem")',
                        data: { inputID: sn.target.value },
                        dataType: "text",
                        success: function (temp) {
                                 $('#item').val(temp);
                                 }
                    });