0

When I set a breakpoint on LoadReport, every parameter is null. For some reason the values are not binding to the parameters with the same name.

Javascript/AJAX

$('#savedCriteria').on('change', function () {
    var criteriaSelected = $('#savedCriteria option:selected').text();
    var data = { actionName: "Daily", reportInput: "ReportDaily", reportCriteria: criteriaSelected };
    //Ajax form post
    $.ajax({
        type: 'POST',
        data: data,
        contentType: "application/json; charset=utf-8",
        url: '@Url.Action("LoadReport", ViewContext.RouteData.Values["Controller"].ToString())',
        success: function (data) {
            if (data.success) {
                alert("Test");
            } else {
                alert("Test Not Successful");
            }
        }
    });
});

Controller

public void LoadReport(string actionName, string reportInput, string reportCriteria)
{
    var reportObject = Activator.CreateInstance(Type.GetType(reportInput));
    IEnumerable<Test.Reports.Utilities.ReportCriteria> reportList = getReportCriteria(reportInput);
    RedirectToAction(actionName, "Reports", reportList.Where(x => x.CriteriaName == reportCriteria));
}
sjohn285
  • 385
  • 5
  • 20
  • comma is missing after ``data`` – Mohammed Sajid Mar 05 '20 at 19:51
  • You don't need to stringify the data. You can assign the object to the data property directly. – AndrewR Mar 05 '20 at 19:55
  • @AndrewR do you mean creating an object like this? `{ actionName: "Daily", reportInput: "ReportDaily", reportCriteria: criteriaSelected }` – sjohn285 Mar 05 '20 at 19:57
  • @sjohn285 Yes, you can assign that directly to the data property instead of converting it to json. – AndrewR Mar 05 '20 at 19:58
  • @Sajid I've done an edit on the question to fix the comma, but the values are still not getting passed to the controller. – sjohn285 Mar 05 '20 at 19:58
  • @sjohn285, i add the comma and updated ``reportCriteria: "criteriaSelected"`` for test. it's wok. can you add ``alert(criteriaSelected)`` to check the value returned – Mohammed Sajid Mar 05 '20 at 20:09
  • Have you tried with `JSON.stringify({actionName: "Daily", reportInput: "ReportDaily", reportCriteria: criteriaSelected })`? – David Donari Mar 05 '20 at 20:11
  • @DavidDonari that's what I had originally, but I changed it because of someone's suggestion to remove the json.stringify part. – sjohn285 Mar 05 '20 at 20:13
  • @Sajid I added `alert(criteriaSelected);` and the alert has the correct value of the option. Is your controller method that you are testing with also a "void"? – sjohn285 Mar 05 '20 at 20:15
  • @sjohn285 try my suggestion by the first code posted, with ``JSON.stringify({actionName: "Daily", reportInput: "ReportDaily", reportCriteria: "criteriaSelected" })`` and forced ``string`` for ``reportCriteria``, it's work for me, i just paste your code. – Mohammed Sajid Mar 05 '20 at 20:18

1 Answers1

3

Default method type is HttpGet, you need to set it to HttpPost.

[HttpPost]
public void LoadReport(string actionName, string reportInput, string reportCriteria)
{
    var reportObject = Activator.CreateInstance(Type.GetType(reportInput));
    IEnumerable<Test.Reports.Utilities.ReportCriteria> reportList = getReportCriteria(reportInput);
    RedirectToAction(actionName, "Reports", reportList.Where(x => x.CriteriaName == reportCriteria));
}

Also keep in mind that with your ajax call you can not use RedirectToAction. You need something like this:

[HttpPost]
public ActionResult  LoadReport(string actionName, string reportInput, string reportCriteria)
{
    var reportObject = Activator.CreateInstance(Type.GetType(reportInput));
    IEnumerable<Test.Reports.Utilities.ReportCriteria> reportList = getReportCriteria(reportInput);
    Return Json(Url.Action(actionName, "Reports", reportList.Where(x => x.CriteriaName == reportCriteria));
}

And in your ajax call:

success: function (data) {
   window.location.href = data;
   }

UPDATE: you also need to create a POCO object and add that to the HttpPost method as parameter instead of separate parameters. Also [FromBody] attribute is needed.

POCO:

public class Data
{
    public string actionName { get; set; }
    public string reportInput { get; set; }
    public string reportCriteria { get; set; }

}

Controller:

[HttpPost]
public JsonResult LoadReport([FromBody]Data data)
{
    var reportObject = Activator.CreateInstance(Type.GetType(data.reportInput));
    IEnumerable<Test.Reports.Utilities.ReportCriteria> reportList = getReportCriteria(data.reportInput);
    return Json(Url.Action(data.actionName, "Reports"));
}
zsolt
  • 1,233
  • 8
  • 18
  • The ``post`` is added in the ``ajax`` function – Mohammed Sajid Mar 05 '20 at 20:37
  • This solved my problem, thanks for the well-written answer! – sjohn285 Mar 05 '20 at 20:53
  • I am glad it's working for you but check out my updated answer too. – zsolt Mar 05 '20 at 21:40
  • What if you only want to add one string parameter. I am having the same problem but if I create a model with one property it will work. But why do I need to create a class just to pass one string parameter on a post? – RJohn Dec 06 '21 at 23:18
  • 1
    @RJohn That's how modelbinder works. See this Q and A: https://stackoverflow.com/questions/40853188/frombody-string-parameter-is-giving-null – zsolt Dec 07 '21 at 23:00