0

I have the following server side code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using AutoMapper;
using myProject.Models;
using System.Web.Http;
using MyProject.Dtos;

using System.Web.Mvc;
using System.Linq.Dynamic;
using System.Data.Entity;
public class MembersController: Controller 
{
     public MembersController()
        {
            _context = new ApplicationDbContext();

        }

public ActionResult GetMembers(string query = null)
        {
            try
            {
                //Creating instance of DatabaseContext class  
                using (_context)
                {
                    var draw = Request.Form.GetValues("draw").FirstOrDefault();
                    var start = Request.Form.GetValues("start").FirstOrDefault();
                    var length = Request.Form.GetValues("length").FirstOrDefault();



                    //Paging Size (10,20,50,100)    
                    int pageSize = length != null ? Convert.ToInt32(length) : 0;
                    int skip = start != null ? Convert.ToInt32(start) : 0;
                    int recordsTotal = 0;

                    // Getting all member data    
                    var membersQuery = _context.Members.ToList();



                    //total number of rows count     
                    recordsTotal = membersQuery.Count();
                    //Paging     
                    var data = membersQuery.Skip(skip).Take(pageSize).ToList();
                    ////Returning Json Data    
                    return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data });


                }
            }
            catch (Exception)
            {
                throw;
            }

        }

}

Here's my view:

var table = $("#members").DataTable({
        "processing": true, // for show progress bar  
        "serverSide": true,
        "pageLength":5,

        ajax: {
            url: "/api/members",
            dataSrc: "",
            "type": "POST",
            "datatype": "json" 

        },

        columns: [
            {
                data: "cardNumber"
            },
            {
                data: "registrationDate",

            },
            {
                data: "fullName",

            },
            {
                data: "address"
            },
            {
                data: "phoneNumber"
            },
            {
                data: "email"
            }             
        ]
    });

I am getting the following compile errors:

Error CS1061 'HttpRequestMessage' does not contain a definition for 'Form' and no accessible extension method 'Form' accepting a first argument of type 'HttpRequestMessage' could be found (are you missing a using directive or an assembly reference?)

Error CS0029 Cannot implicitly convert type 'System.Web.Http.Results.JsonResult< data>>' to 'System.Web.Mvc.ActionResult'

I am following this tutorial for guidance.

Will appreciate your help

mcfred
  • 1,183
  • 2
  • 29
  • 68

1 Answers1

0

Both exception messages are related each other, and seem originated from this using statement which was suspicious:

using System.Web.Http;

And this url setting which implies that you want to call Web API controller from DataTable's AJAX callback:

url: "/api/members", // points to Web API controller

The first exception occurred because you're using Request property which not originated from HttpContext.Request that returns HttpRequest, instead it came from another Request property in System.Web.Http namespace which returns HttpRequestMessage.

The second exception occurred because return type of the controller action is System.Web.Mvc.ActionResult, while your Json() method might return System.Web.Http.Results.JsonResult which is part of Web API.

Judging from your AJAX URL and controller action, you have 2 options:

1) If you're using MVC controller, remove System.Web.Http namespace and make sure you're using Request from HttpContext.Current like example below:

var draw = HttpContext.Current.Request.Form.GetValues("draw").FirstOrDefault();
var start = HttpContext.Current.Request.Form.GetValues("start").FirstOrDefault();
var length = HttpContext.Current.Request.Form.GetValues("length").FirstOrDefault();

Then you need to replace AJAX call in DataTable to call the action name like this:

ajax: {
    url: '@Url.Action("GetMember", "Members")',
    data: ..., // set your data here
    type: "POST",
    dataType: "json" 
},

2) If you're using Web API controller, replace System.Web.Mvc.Controller inheritance with System.Web.Http.ApiController, then use proper way to return JSON string from Web API controller:

public class MembersController: ApiController 
{
    // ctor
    public MembersController()
    {
        _context = new ApplicationDbContext();

    }

    public IHttpActionResult GetMembers([FromBody] ViewModel model)
    {
        try
        {
            //Creating instance of DatabaseContext class  
            using (_context)
            {
                var draw = model.Draw;
                var start = model.Start;
                var length = model.Length;

                // skipped for brevity

                return Ok(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data });
            }
            catch (Exception)
            {
                // error handling
            }
        }
    }
}

If you choose this approach, you can leave the URL /api/Members as is but the AJAX call's data/dataSrc parameter from DataTable should be modified to pass the viewmodel object because Request property from Web API doesn't have Form property as its member.

Related issues:

POST throws HttpRequestMessage does not contain a definition for Form

Cannot implicitly convert Web.Http.Results.JsonResult to Web.Mvc.JsonResult

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
  • Hi @Tetsuya, thanks for your insights. I opted for option 1 (MVC Controller) and when I started to debug, I got the following exception on the very first line where it tries to read the value of "draw". This is what I got: Value cannot be null. Parameter name: source – mcfred Mar 27 '19 at 16:35