views:

66

answers:

4

I'm using jqGrid to display some data on a page. Within the controller action, we're using an anonymous object to represent the data that the jqGrid needs. My question is, is there a way we can create a strongly typed object to represent the jqGrid data that we are sending with Json()?

Main reason for this is so that we can do unit testing with the objects that are being sent to it.

Thanks!

EDIT:

[AcceptVerbs(HttpVerbs.Post)]
        public JsonResult GridData(FormCollection form, string alias, string location, string state)
        {
            int pageSize = Convert.ToInt32(form["rows"]);
            int pageIndex = Convert.ToInt32(form["page"]) - 1;
            var deviceList = this._device.GetList(CreateFilter(location,alias,state),this._securityCache.GetSecurityContext(),pageSize,pageIndex);
            int totalResults = deviceList.TotalRecords;
            int totalPages = (int)Math.Ceiling((float)totalResults / (float)pageSize);
            var jsonData = new {
                total = totalPages,
                page = pageIndex + 1,
                records = totalResults,
                rows = (from device in deviceList.Data
                        select new {i = device.Alias,cell = new string[]{device.Alias,device.Location,device.RatePlan,device.State,device.DateCreated.ToString()}}).ToArray()
                }; 
return Json(jsonData);

This above here works, but we can't unit test the data that is being passed into the Json() method.

var newJsonData = new JsonJQGridReturnData(); 
                newJsonData.total = totalPages;
                newJsonData.page = pageIndex + 1;
                newJsonData.records = totalResults;
                List<JsonJQGridRow> list = new List<JsonJQGridRow>();
                foreach (var device in deviceList.Data)
                {
                    list.Add(new JsonJQGridRow(device.Alias, new string[] { device.Alias, device.Location, device.RatePlan, device.State, device.DateCreated.ToString() }));
                }
                newJsonData.rows = list.ToArray();      
                _cookieHelper.SaveCookie("DeviceListIndex", this._securityCache.GetSecurityContext().UserID.ToString(), COOKIE_PAGE_SIZE_KEY, pageSize.ToString());
                return Json(newJsonData);
            }

Here is my poor attempt at trying to wrap these into strongly typed objects. Unfortunately, running this gives me a "u is undefined" in the jqGrid file. I suspect that this is because the json being passed in is not correctly formatted. Here are the classes....

[DataContract]
    public class JsonJQGridReturnData
    {
        [DataMember]        
        public int total { get; set; }

        [DataMember]
        public int page { get; set; }

        [DataMember]
        public int records { get; set; }

        [DataMember]
        public JsonJQGridRow[] rows { get; set; }
    }

    [DataContract]
    public class JsonJQGridRow
    {
        public JsonJQGridRow(string i, string[] columns)
        {
            this.i = i;
            this.cells = columns;
        }

        [DataMember]
        public string i { get; set; }

        [DataMember]
        public string[] cells { get; set; }
    }
A: 

David,

Here's the kinda thing i use in an app i'm working on at the moment for this type of thing. I know it doesn't provide a strongly typed object as such, but the 'list' could be a part of the model that is then sent ToArray() at the end of the piece.

public JsonResult GridData(int id)
{
    // get our messages based on id
    var bookingmessagesList = _repository.Find(x => x.ID == id);
    var list = new ArrayList();
    foreach (var bookingmessage in bookingmessagesList) //populate data containers with read data
    {
        list.Add(new
                {
                    bookingmessage.ClassRowVersionDate,
                    bookingmessage.ID,
                    bookingmessage.BookingID,
                    bookingmessage.AssignedFrom,
                    bookingmessage.AssignedTo,
                    bookingmessage.AssignedDate,
                    bookingmessage.CompletedDate,
                    bookingmessage.MessageType,
                    bookingmessage.Notes
                });
    }
    int totalOjectCount = list.Count;
    return Json(new { dataitems = list.ToArray(), totalItems = totalOjectCount });
}

hope it gives you some ideas.. Will be interested to see the suggestions made.

jim
This is fairly close to what we're doing now. This works great, but doesn't provide use with an ability to do unit testing on the data.
DavidAndroidDev
no problem - hope you 'get there' in the end.. :)
jim
A: 

Here's a quick take on a strongly-typed JQGridResult.

public class JQGridResult<T> : JsonResult where T : class
{
    public T Model
    {
        get { return (T)this.Data; }
        set { this.Data = value; }
    }
}

Used as...

return new JQGridResult<JsonModel> {
     Model = new GridModel  { ... initialize model here ... }
});

where GridModel is basically a container class holding the strongly typed properties for the grid.

tvanfosson
+1  A: 

If I understand your question you can use Generics to do this:

Model:

// represents one row in the JQGrid
        class Customer
        {
            public string firstname { get; set; }
            public string lastname { get; set; }
        }

JQGrid class:

    class JQGridData<TModel>
            {
// add in whatever other properties you want for JQGrid
                public int responseTime {get; set; };
                public List<TModel> rows = new List<TModel>(); 
            }

Controller Action :

public JsonResult GridData(int page)
        {
            var gridData = new JQGridData<Customer>();

// Populate your data here, this is just an example: 
            gridData.rows.Add(new Customer()
            {
                firstname = "fred", lastname = "pharkas"
            });

// return the result
            return Json(gridData, JsonRequestBehavior.AllowGet); 
        }

Result:

{    
     responseTime: 0       
      rows: [         
            {
                firstname: "fred"
                lastname: "pharkas"
            }
      ]    
}

Is that what you were asking?

Francis Shanahan
A: 

I feel really silly. I had a misspelling in the GridRow that was causing jqGrid to blow up. After I fixed that, I was able to get the jqGrid to work with my strongly typed object...

Now in my unit tests, I can just do...

var result = controllerToTest.GridData(form, null, null, null) as JsonResult;
var data = result.Data as JsonJQGridReturnData;

and now I can access the fields :D

DavidAndroidDev
Well, after posting that...I suppose these aren't strongly typed. But it's more testable than it was before.
DavidAndroidDev