locked
Razor RedirectToPage 400 Error RRS feed

  • Question

  • User-1104215994 posted

    Hi guys,

    I am trying to redirect to a page in the controller action in my localhost, but I am getting 400 errors. (Stock.cshtml is under Views-StockSales.) Any ideas on how can I fix this?

    public async Task<ActionResult<IList<Coupon>>> Stock(int quantity, string game)
            {
                
                try
                {
                    var coupons = new List<Coupon>();
                    var games = new StockSales { Product = game, Quantity = quantity };
    
                    var content = await games.CallGameAsync("Test", "12345", game, quantity);
                    var json = JObject.Parse(content);
                    coupons = JsonConvert.DeserializeObject<List<Coupon>>(json["coupons"]?.ToString() ?? string.Empty);
    
                    return RedirectToPage("/StockSales/Stock", coupons);
                }
                catch (Exception e)
                {
    
                    //NLOG
                    NLog(logger2, "Stock Sales " + e.Message);
    
                   
                }
            }

    Thanks.

    Saturday, May 22, 2021 2:07 PM

Answers

  • User475983607 posted

    The AJAX function expects JSON

    dataType: 'json',

    but the Action returns an entire HTML page.  The Action should return a partial.  

    return RedirectToAction("Stock");
     //return View("Stock", coupons);
    public IActionResult Stock()
    {
        var coupons = JsonConvert.DeserializeObject<List<Coupon>>(TempData["coupons"].ToString());
        return View(coupons);
    }

    Also, the DataTable expects a JSON data source.  The design needs to be updated to handle AJAX effectively.  

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, May 25, 2021 10:07 AM

All replies

  • User475983607 posted

    The RedirectToPage a route parameter not a List<T>.  Please see the openly published RedirectToPage reference documentation.  The reference documenation explains each overload and the parameters.

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.razorpages.pagebase.redirecttopage?view=aspnetcore-5.0

    Saturday, May 22, 2021 2:17 PM
  • User-1104215994 posted

    I changed to this;

    return View("Stock", coupons);

    But the page is not opened, it is on the popup window.

    popup window

    Saturday, May 22, 2021 4:47 PM
  • User475983607 posted

    You did not shared any relevant code.  Try basic debugging.  

    Saturday, May 22, 2021 5:21 PM
  • User-1104215994 posted

    Here is the relevant code as you requested;

     public async Task<ActionResult<IList<Coupon>>> StockAsyncTask(int quantity, string game)
            {
                
                try
                {
                    var coupons = new List<Coupon>();
                    var games = new StockSales { Product = game, Quantity = quantity };
    
                    var content = await games.CallGameAsync("Test", "12345", game, quantity);
                    var json = JObject.Parse(content);
                    coupons = JsonConvert.DeserializeObject<List<Coupon>>(json["coupons"]?.ToString() ?? string.Empty);
    
                 
                  return View("Stock", coupons);
                }
                catch (Exception e)
                {
    
                    //NLOG
                    NLog(logger2, "Stock Sales " + e.Message);
    
                    return StatusCode(500, e.Message);
    
    
                }
            }

    Stock.cshtml

    @model IEnumerable<Coupon>
    
    
    @{
        ViewData["Title"] = "Stock";
    }
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <h2 class="font-weight-bolder">Stock</h2>
    
    <table class="table hover" id="test">
        <thead>
            <tr>
    
                <th>
                    @Html.DisplayNameFor(model => model.Pin)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Serial)
                </th>
             
               
                    <th>
                        @Html.DisplayNameFor(model => model.expiryDate)
                    </th>
           
    
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>
    
                    <td>
                        @Html.DisplayFor(modelItem => item.Pin)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Serial)
                    </td>
                  
                    <td>
                        @Html.DisplayFor(modelItem => item.expiryDate)
                    </td>
                   
    
                
                </tr>
            }
        </tbody>
    </table>
    
    @section scripts {
    
        <script src="~/lib/jquery/jquery.js"></script>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
        <script type="text/javascript" src="https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.10.18/b-1.5.6/b-colvis-1.5.6/b-html5-1.5.6/b-print-1.5.6/r-2.2.2/sc-2.0.0/sl-1.3.0/datatables.min.js"></script>
        <script>
            $(document).ready(function () {
                $('#test').DataTable({
                    "processing": true,
                    dom: 'Bfrtip',
                    columnDefs: [
                        {
                            targets: 4,
                            className: 'noVis'
                        }
                    ],
                    buttons: [
    
                        {
                            extend: 'excelHtml5',
                            exportOptions: {
                                columns: [0, 1, 2, 3]
                            }
                        },
                        {
                            extend: 'pdfHtml5',
                            exportOptions: {
                                columns: [0, 1, 2, 3]
                            }
                        },
                        {
                            extend: 'colvis',
                            columns: ':not(.noVis)'
                        }
                    ]
    
                });
            });
        </script>
    }
    
    

    Saturday, May 22, 2021 6:52 PM
  • User-1104215994 posted

    Any ideas why the page opens on a popup?

    Sunday, May 23, 2021 6:31 PM
  • User475983607 posted

    Any ideas why the page opens on a popup?

    This thread is hard hard to follow and it seems your requirements changed.  Can you share the code that opens the popup?

    Sunday, May 23, 2021 6:55 PM
  • User-1104215994 posted

    When I hit the purchase button on the StockSales.cshtml, the StockAsyncTask action triggered in the controller.

    @{
        ViewData["Title"] = "Stock Sales";
    }
    
    <h2 class="text-center font-weight-bolder mb-2" style="margin-bottom: 3.5rem !important">Stock Sales</h2>
    <!DOCTYPE html>
    
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Stock Sales</title>
    
        <script src="~/lib/jquery/jquery.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
        <script src="~/lib/bootstrap/js/bootstrap.js"></script>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" />
        <link href="~/lib/bootstrap/css/bootstrap.css" rel="stylesheet" />
    
    </head>
    <style>
        div.hidden {
            display: none
        }
    </style>
    
    <form class="needs-validation" novalidate>
        <div id="spinner-map-right-click" class="d-flex justify-content-center hidden">
            <div class="spinner-border hidden" role="status">
                <span class="sr-only">Loading...</span>
            </div>
        </div>
    
        <div class="container-fluid">
    
    
    
            <div class="row">
    
    
                <div class="col-md-5">
    
                    <div class="row">
    
                        <div class="col-md-4">
    
                        </div>
    
                        <div class="form-group col-md-5 input-group">
                            <select class="custom-select" id="validationCustom04" required>
                                <option selected disabled value="">Choose...</option>
                                <option value="111111110000">Sales Test</option>
                               
                                <option value="000000001706">9000 ZA</option>
                                <option value="0187021">5 TL Razer Gold Pin</option>
                                                          
                               
                            </select>
                            <div class="invalid-feedback">
                                Please select a game.
                            </div>
    
    
                        </div>
    
    
                    </div>
    
                    <div class="row">
    
                        <div class="col-md-4">
    
                        </div>
    
                        <div class="form-group col-md-5 input-group">
    
                            <div class="input-group-prepend">
                                <span class="input-group-text" id="basic-addon1">Quantity</span>
                            </div>
                            <input type="number" class="form-control " id="quantity" name="Quantity" value="1" aria-describedby="basic-addon1" min="1" max="500" />
    
                        </div>
    
                    </div>
    
                    
                    <div class="row">
    
                        <div class="col-md-4">
    
                        </div>
    
                        <div class="form-group col-md-5">
    
                            <button id="btn_add" type="submit" class="btn btn-info">Purchase</button>
                            <input id="btn_clear" type="button" value="Clear" class="btn btn-warning" />
    
                        </div>
    
                    </div>
    
                </div>
    
                
            </div>
        </div>
    
    </form>
    
    
    <script>
    
    
        // Example starter JavaScript for disabling form submissions if there are invalid fields
        (function () {
            'use strict';
            window.addEventListener('load', function () {
                // Fetch all the forms we want to apply custom Bootstrap validation styles to
                var forms = document.getElementsByClassName('needs-validation');
    
    
                // Loop over them and prevent submission
                var validation = Array.prototype.filter.call(forms, function (form) {
    
                    form.addEventListener('submit', function (event) {
                        if (form.checkValidity() === false) {
                            event.preventDefault();
                            event.stopPropagation();
                        } else {
                            event.preventDefault();
                            $("#btn_add").html(
                                '<span class="spinner-border spinner-border-sm" role="status" id="spinner" aria-hidden="true"></span> Loading...'
                            );
                            var selText = $("#validationCustom04").val();
                            var gameName = $("#validationCustom04 option:selected").text();
                            var quantity = $("#quantity").val();
                           
                           
    
                            var serviceUrl = '/StockSales/StockAsyncTask?quantity=' + quantity + '&game=' + selText;
                            $.ajax({
                                type: "GET",
                                url: serviceUrl,
                                dataType: 'json',
                                success: function (data) {
                                    //alert(JSON.stringify(data));
                                    ShowResult(data);
                                    $("#spinner").remove();
                                    $("#btn_add").html('Add');
    
                                }, error: function (xhr, status, error) {
                                    $("#spinner").remove();
                                    $("#btn_add").html('Add');
    
                                    var errorMessage = xhr.responseText;
    
                                    alert('Error - ' + errorMessage);
                                }
    
                            });
                        }
                        form.classList.add('was-validated');
                    }, false);
                });
            }, false);
    
        })();
    
        
        $("#btn_clear").click(function () {
            $("#quantity").val(1);
            $("#validationCustom04").val("");
           
        });
        
    
       
    </script>
    

    Controller:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using GameMonitor.Models;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using NLog;
    
    namespace GameMonitor.Controllers
    {
        public class StockSalesController : Controller
        {
            private static readonly Logger logger = LogManager.GetLogger("excel");
            private static readonly Logger logger2 = LogManager.GetLogger("exceptionFile");
            private readonly GameContext _context;
    
            public StockSalesController(GameContext context)
            {
                _context = context;
            }
            public IActionResult StockSales()
            {
                return View();
            }
    
            
            public IActionResult Stock()
            {
                var coupons = JsonConvert.DeserializeObject<List<Coupon>>(TempData["coupons"].ToString());
                return View(coupons);
            }
           
            public async Task<ActionResult<IList<Coupon>>> StockAsyncTask(int quantity, string game)
            {
                
                try
                {
                    var coupons = new List<Coupon>();
                    var games = new StockSales { Product = game, Quantity = quantity };
    
                    var content = await games.CallGameAsync("Test", "12345", game, quantity);
                    var json = JObject.Parse(content);
                    coupons = JsonConvert.DeserializeObject<List<Coupon>>(json["coupons"]?.ToString() ?? string.Empty);
    
                 
                    //NLOG
                    NLogPin(logger, User.Identity.Name, DateTime.Now);
                    TempData["coupons"] = JsonConvert.SerializeObject(coupons);
                   
                    return RedirectToAction("Stock");
                    //return View("Stock", coupons);
                }
                catch (Exception e)
                {
    
                    //NLOG
                    NLog(logger2, "Stock Sales " + e.Message, DateTime.UtcNow, 0);
    
                    return StatusCode(500, e.Message);
    
    
                }
            }
    
           
           
        }
    }

    And finally, I am expecting to open Stock.cshtml but somehow it is opening on the popup!

    @model IEnumerable<Coupon>
    
    
    @{
        ViewData["Title"] = "Stock";
    }
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <h2 class="font-weight-bolder">Stock</h2>
    
    <table class="table hover" id="test">
        <thead>
            <tr>
    
                <th>
                    @Html.DisplayNameFor(model => model.Pin)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Serial)
                </th>
             
               
                    <th>
                        @Html.DisplayNameFor(model => model.expiryDate)
                    </th>
           
    
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>
    
                    <td>
                        @Html.DisplayFor(modelItem => item.Pin)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Serial)
                    </td>
                  
                    <td>
                        @Html.DisplayFor(modelItem => item.expiryDate)
                    </td>
                   
    
                
                </tr>
            }
        </tbody>
    </table>
    
    @section scripts {
    
        <script src="~/lib/jquery/jquery.js"></script>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
        <script type="text/javascript" src="https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.10.18/b-1.5.6/b-colvis-1.5.6/b-html5-1.5.6/b-print-1.5.6/r-2.2.2/sc-2.0.0/sl-1.3.0/datatables.min.js"></script>
        <script>
            $(document).ready(function () {
                $('#test').DataTable({
                    "processing": true,
                    dom: 'Bfrtip',
                    columnDefs: [
                        {
                            targets: 4,
                            className: 'noVis'
                        }
                    ],
                    buttons: [
    
                        {
                            extend: 'excelHtml5',
                            exportOptions: {
                                columns: [0, 1, 2, 3]
                            }
                        },
                        {
                            extend: 'pdfHtml5',
                            exportOptions: {
                                columns: [0, 1, 2, 3]
                            }
                        },
                        {
                            extend: 'colvis',
                            columns: ':not(.noVis)'
                        }
                    ]
    
                });
            });
        </script>
    }
    
    

    Monday, May 24, 2021 5:31 AM
  • User-1104215994 posted

    Hi,

    I debugged the js in the page StockSales and it seems I am getting this error.

    columnNumber: 19
    fileName: "http://localhost:51916/lib/jquery/jquery.js"
    lineNumber: 9013
    message: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"

    The problem occurs in the ajax portion of the StockSales.cshtml. Why it gets the error, any ideas?

    var serviceUrl = '/StockSales/StockAsyncTask?quantity=' + quantity + '&game=' + selText;
                            $.ajax({
                                type: "GET",
                                url: serviceUrl,
                                dataType: 'json',
                                success: function (data) {
                                    
                                    
                                    $("#spinner").remove();
                                    $("#btn_add").html('Add');
    
                                }, error: function (xhr, status, error) {
                                    $("#spinner").remove();
                                    $("#btn_add").html('Add');
    
                                    var errorMessage = xhr.responseText;
    
                                    
                                }
    
                            });

    Tuesday, May 25, 2021 9:44 AM
  • User475983607 posted

    The AJAX function expects JSON

    dataType: 'json',

    but the Action returns an entire HTML page.  The Action should return a partial.  

    return RedirectToAction("Stock");
     //return View("Stock", coupons);
    public IActionResult Stock()
    {
        var coupons = JsonConvert.DeserializeObject<List<Coupon>>(TempData["coupons"].ToString());
        return View(coupons);
    }

    Also, the DataTable expects a JSON data source.  The design needs to be updated to handle AJAX effectively.  

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, May 25, 2021 10:07 AM
  • User-1104215994 posted

    Problem solved, thank you.

    var serviceUrl = '/StockSales/StockAsyncTask?quantity=' + quantity + '&game=' + selText;
                            $.ajax({
                                type: "POST",
                                url: serviceUrl,
                                error: function (xhr) {
                                    alert(xhr.responseText);
                                }
                            }).done(function (data) {
                                //alert(data.newUrl);
                                window.location.replace(data.newUrl);
                            });
    
    
    [Authorize]
            public IActionResult Stock()
            {
                var coupons = JsonConvert.DeserializeObject<List<Coupon>>(TempData["coupons"].ToString());
                return View(coupons);
            }
    
            [HttpPost]
            public async Task<ActionResult<IList<Coupon>>> StockAsyncTask(int quantity, string game)
            {
                
                try
                {
                    var coupons = new List<Coupon>();
                    var games = new StockSales { Product = game, Quantity = quantity };
    
                    var content = await games.CallGameAsync("Test", "12345", game, quantity);
                    var json = JObject.Parse(content);
                    coupons = JsonConvert.DeserializeObject<List<Coupon>>(json["coupons"]?.ToString() ?? string.Empty);
    
                
                    
                    TempData["coupons"] = JsonConvert.SerializeObject(coupons);
                    
                    return Json(new
                        {
                            newUrl = Url.Action("Stock")
                        }
                    );
                }
                catch (Exception e)
                {
    
                    //NLOG
                    NLog(logger2, "Stock Sales " + e.Message, DateTime.UtcNow, 0);
    
                    return StatusCode(500, e.Message);
    
    
                }
            }
    
    

    Tuesday, May 25, 2021 5:44 PM