Grid does not call action method to fill data in IE - asp.net-mvc

Can someone help me to resolve the issue of filling Kendo UI Grid in mvc on IE platform?
The following are technologies used:
1) Telerik Kendo UI version 2015.1.408.545
2) MVC 5.0, razor view
3) .Net Framework 4.5
In Chrome whenever MVC View page loads it calls read action method twice. First call is for getting scema to be bind to the Kendo UI Grid. Second time is for getting data to fill Kendo UI Grid. All this requests from Controller to View and vice versa works fine in Chrome.
But when I run this application in IE (11.0), then first time it displays all the data properly. But when the request posted for another data it does not call the action method twice. Therefore the previous data is being displayed on Grid. Thats the issue.
View
#model CustomReportResultsViewModel
#(Html.Phoenix().Grid<DataTable, DataTable>()
.DataSourceReadController("CustomReport", "Reports")
.KeyName("ID")
.RecordName(Model.RecordName)
.CacheEditorTemplate(false)
.Columns(columns => { foreach (DataColumn c in Model.DataTable.Columns) { }})
)
Controller
public ActionResult ResultsGrid(int id, string recordName) {
return PartialView("ResultsGrid", new CustomReportResultsViewModel { DataTable = GetData(id, true), RecordName = recordName });
}
// List
public JsonResult Read([DataSourceRequest] DataSourceRequest request)
{
var table = GetData();
var result = table.ToDataSourceResult(request);
return Json(result, JsonRequestBehavior.AllowGet, 3);
}
private string GetDataSource(StringBuilder columnSchema, StringBuilder aggregates, StringBuilder group, string primaryKey, string read) {
var dataSource = new StringBuilder();
dataSource.Append("{transport:{"); dataSource.Append("read:{type:\"GET\",url:\"" + read + "\"}"); dataSource.Append("},");
dataSource.Append("type:\"aspnetmvc-ajax\",");
}

How do you request the data? AJAX call? Would be better if you added the grid datasource code / controller methods. Narrow the question, please.
This grid/controller signatures always worked for me on IE.
Controller:
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult GetData([DataSourceRequest] DataSourceRequest request)
{
//whatever it takes to get that data, like
var data = repository.GetAll<Model>();
return Json(data.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
View:
#using Entites.Model
#(Html.Kendo().Grid<Model>()
.Name("grid")
.DataSource(dataSource =>
{
dataSource
.Ajax()
.PageSize(20)
.Read(read => read.Action("GetData", "Home"));
})
)

Thanks for your quick reply.
We are following the below code:
public ActionResult ResultsGrid(int id, string recordName)
{
return PartialView("ResultsGrid", new CustomReportResultsViewModel { DataTable = GetData(id, true), RecordName = recordName });
}
// List
public JsonResult Read([DataSourceRequest] DataSourceRequest request)
{
var table = GetData();
var result = table.ToDataSourceResult(request);
return Json(result, JsonRequestBehavior.AllowGet, 3);
}
private string GetDataSource(StringBuilder columnSchema, StringBuilder aggregates, StringBuilder group, string primaryKey, string read)
{
var dataSource = new StringBuilder();
dataSource.Append("{transport:{");
dataSource.Append("read:{type:\"GET\",url:\"" + read + "\"}");
dataSource.Append("},");
dataSource.Append("type:\"aspnetmvc-ajax\",");
}

Related

Want to Implement Pagination in my ASP.NET MVC TestProject Application

I want to implement Pagination in my ASP.NET MVC project.When i put #model PagedList.IPagedList<TestProject.Models.Test> in my Index page then the following error appears.
Compiler Error Message: CS1061: 'IPagedList' does not contain a definition for 'FName' and no extension method 'FName' accepting a first argument of type 'IPagedList' could be found
And When I put #model IEnumerable<TestProject.Models.Test> then it gives following error:
Argument 2: cannot convert from 'System.Collections.Generic.IEnumerable<TestProject.Models.Test>' to 'PagedList.IPagedList'
#Html.PagedListPager(Model, pageNumber => Url.Action("Index", new { pageNumber })
My Home Controller returns the following:
public ActionResult Index(int? pageNumber)
{
TestHandle testHandle = new TestHandle();
ModelState.Clear();
return View(testHandle.GetAll().ToList().ToPagedList(pageNumber ?? 1, 3));
}
My GetAll function retruns list:
public List<Test> GetAll()
{
clsUtilities cUtils = new clsUtilities();
DataSet ds;
List<Test> studentlist = new List<Test>();
string sSQL;
sSQL = "exec AllPhone";
ds=cUtils.GetDataSet(sSQL);
DataTable dt = ds.Tables[0];
foreach (DataRow dr in dt.Rows)
{
studentlist.Add(
new Test
{
Id = Convert.ToInt32(dr["Id"]),
FName = Convert.ToString(dr["FName"]),
LName = Convert.ToString(dr["LName"]),
Address = Convert.ToString(dr["Address"])
});
}
return studentlist;
}
Please guide me. I did so much of research but no luck. So I am posting this error. Please suggest me where i am going wrong. Any help is highly appreciated.
DisplayNameFor() only accepts IEnumerable<T> when using it for a collection property. If your model is IPagedList<T>, then you can use
#Html.DisplayNameFor(m => m.FirstOrDefault().FName)
Note this will work even if the collection is empty.
As a side note, calling ModelState.Clear(); in your GET method is pointless and can be removed.

An item with the same key has already been added when loading Kendo MVC Grid

I am trying to populate a Kendo mvcGrid and I keep getting the error An item with the same key has already been added.
I have seen elsewhere that duplicate model properties is the likeliest source of the problem but I have no duplicate properties in my model. I've even simplified everything to just a basic mock up to eliminate as many possible variables as possible..and I cant get the grid to load data.
I've tried it as a Html.Partial where its not loaded initially because of a empty model and then loading it through jquery...Ive tried with passing in am empty model so that the grid will load initially without data and then doing a datasource refresh...no luck there either. Basically as soon as I try to add content to the grid with a populated model I get the error and no data is loaded.
Been fighting this issue for 2 days now and had no luck. Ill post my code here maybe someone else can see what I'm missing.
One variable that cant change is the grid resides on a partial view with a model different from its parent view.
in the parent view I have tried both
<div id ="columnkgrid">#{Html.RenderPartial("Columns", new TestFieldIssue.Models.FieldListModel());}</div>
and
<div id="columnkgrid">#Html.Partial("Columns", new TestFieldIssue.Models.FieldListModel())</div>
either way will succeed in posting a grid with no data..it has no data yet because its populated by the selection of a value in a dropdown list.
so as to not over complicate the sample I've just set a hard coded value in the jquery function I have been using to refresh the grid.
function loadgrid() {
var grid = $("#grid").data("kendoGrid");
var val = 1;
grid.dataSource.read({ table_pk: val });
grid.refresh();
}
the grid code in the partial once again kept it simple without any bells and whistles just to test.
#(Html.Kendo().Grid(Model.fields)
.DataSource(data => data
.Ajax()
.Model(model => model.Id(m => m.field_pk))
.Read(r => r.Action("Columns","Home"))
)
.Name("grid")
.Columns(c =>
{
c.Bound(m => m.field_name).Title("Field Name").Width(100);
})
)
and the controller methods loading some mock data
public ActionResult Columns(int? table_pk)
{
FieldListModel model;
if (table_pk == null)
{
model = GetEmptyColumns();
}
else
{
model = GetColumns();
}
return PartialView("Columns", model);
}
public FieldListModel GetColumns()
{
FieldListModel model = new FieldListModel();
model.fields = new List<FieldModel>();
model.fields.Add(new FieldModel { field_name = "field1", field_pk = 1 });
model.fields.Add(new FieldModel { field_name = "field2", field_pk = 2 });
model.fields.Add(new FieldModel { field_name = "field3", field_pk = 3 });
return model;
}
public FieldListModel GetEmptyColumns()
{
FieldListModel model = new FieldListModel();
model.fields = new List<FieldModel>();
model.fields.Add(new FieldModel { field_name = "", field_pk = 0 });
return model;
}
and a very simple Model
public class FieldListModel
{
public List<FieldModel> fields { get; set; }
}
public class FieldModel
{
public int field_pk { get; set; }
public string field_name { get; set; }
}
I made few changes to run your code (correct version of Kendo and JQuery). May be those related to setup at my machine. I was able to reproduce the problem.
Then I changed the action code and was able to see the values populated in Grid:
public ActionResult Columns(int? table_pk, [DataSourceRequest] DataSourceRequest request)
{
FieldListModel model;
if (table_pk == null)
{
model = GetEmptyColumns();
}
else
{
model = GetColumns();
}
return Json(model.fields.ToDataSourceResult(request));
}
The change is accepting an additional parameter in action method of type DataSourceRequest. The Kendo grid wraps request in this object to specify sorting and paging information. The grid itself gets updated with data wrapped under DataSourceRequest object (note in return statement). More information here.

Kendo Grid has correct JSON but data not showing up

I'm trying to use Teleric's Kendo Grid in ASP.NET MVC 5. I'm following the example here, but the grid is not populating with data. The columns show up, but it says "No items to display".
http://docs.telerik.com/kendo-ui/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/ajax-binding
This is my Words/Read function:
public ActionResult Read([DataSourceRequest] DataSourceRequest request)
{
var items = db.Words.Take(1).ToList();
//this code was necessary to get the correct JSON result
JsonSerializerSettings jsSettings = new JsonSerializerSettings();
jsSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var converted = JsonConvert.SerializeObject(items, null, jsSettings);
return Content(converted);
}
I got the following JSON result from Words/Read:
[{"WordId":1,"Rank":1,"PartOfSpeech":"article","Image":"Upload/29/1/Capture1.PNG","FrequencyNumber":"22038615","Article":null,"ClarificationText":null,"WordName":"the | article","MasterId":0,"SoundFileUrl":"/UploadSound/7fd752a6-97ef-4a99-b324-a160295b8ac4/1/sixty_vocab_click_button.mp3","LangId":1,"CatId":null,"IsActive":false}]
Finally, my view page:
#(Html.Kendo().Grid<NextGen.Models.Word>
()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(15)
.Read(read => read.Action("Read", "Words"))
)
.Columns(columns =>
{
columns.Bound(c => c.WordName);
columns.Bound(c => c.PartOfSpeech);
})
.Pageable()
.Sortable()
)
I've seen some similar questions to this one, but most are using Javascript rather than Html helpers. Am I doing something dumb?
I found an alternative way to get around the circular reference problem I was having. Basically, the answer is here: A circular reference was detected while serializing an object of type 'SubSonic.Schema .DatabaseColumn'.
For people with the same problem: I took the two properties I needed - WordName and PartOfSpeech, and passed only those attributes to the toDataSource function Kendo provides.
My new read function looks like this:
public ActionResult Read([DataSourceRequest] DataSourceRequest request)
{
var items = db.Words.Select(w => new WordL{
WordName = w.WordName,
PartOfSpeech = w.PartOfSpeech
});
return Json(items.ToDataSourceResult(request));
}
where WordL is a model with just PartOfSpeech and WordName attributes, rather than all the attributes of my class.
It is probably because you are not using 2 methods in your controller. While your page view is first ActionResult you should use second one as in the grid as you did in your example. I hope it is obvious.
public ActionResult ReadPage()
{
return View();
}
public ActionResult Read([DataSourceRequest] DataSourceRequest request)
{
var items = db.Words.Take(1).ToList();
//this code was necessary to get the correct JSON result
JsonSerializerSettings jsSettings = new JsonSerializerSettings();
jsSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var converted = JsonConvert.SerializeObject(items, null, jsSettings);
return Content(converted);
}

Controller Returning Incorrect DateTime Format

When using the the Telerik DataSourceRequest within my controller any property with a DateTime data type is being returned as
{"Data":[{"EffectiveStart":"\/Date(1393660800000)\/"}
Instead of MM/dd/yy
The property on my Model is:
[DataType(DataType.DateTime)]
public DateTime EffectiveStart;
I have also included the js culture reference for Telerik in my file and initiated kendo.culture() with no luck. What am I missing?
As requested here is the controller:
public ActionResult Grid_Read([DataSourceRequest]DataSourceRequest request, int id)
{
try
{
using (var db = new MyEntities())
{
var query = from refA in db.Entity
join refB in db.Entity on refA.ID equals refB.ID
where refA.ID == id
select new ResultList
{
ResultId = refA.PayeeId,
EffectiveStart = refA.EffectiveStart,
};
List<ResultList> myvar = query.ToList();
DataSourceResult result = myvar.ToDataSourceResult(request);
return Json(result);
}
}
catch (Exception ex)
{
return Json(null);
}
}
One thing you could do is replace
return Json(result);
by
return Content(JsonConvert.SerializeObject(result));
BTW, you will need Newtonsoft.Json to use JsonConvert.
Thanks for all the responses. The resolution on this was to include some client side JavaScript which formats the field at runtime:
function toDate(value)
var dateRegExp = /^\/Date\((.*?)\)\/$/;
var date = dateRegExp.exec(value);
return new Date(parseInt(date[1]));
}
Then add a to the Telerik Grid column:
.ClientTemplate("#= kendo.toString( toDate(DateCreated), \"MM/dd/yyyy\" ) #")

Passing viewmodel from one method to another (post)

I have a wizardtype form where i would like to keep the model from the first step to the last.
This is how im doing it now, but i cant seem to keep the model from step 3 to 4.
[HttpPost]
public ActionResult Register(MemberViewModel model)
{
var mobile = model.Mobile;
var xml = MemberclubHelper.CreateVerificationTokenXML(mobile, "47");
MemberclubHelper.SendVerificationToken(xml);
return RedirectToAction("RegisterStep1", new { mobile = mobile });
}
public ActionResult RegisterStep1(string mobile)
{
var model = new MemberViewModel();
model.Mobile = mobile;
return View("Register/Step1", model);
}
[HttpPost]
public ActionResult RegisterStep1(MemberViewModel model)
{
var interests = (from interest in model.Interests where interest.isChecked select interest.value).ToList();
var passing = (from pass in model.Passing where pass.isChecked select pass.value).ToList();
var xml = MemberclubHelper.CreateMemberProfileXML(model.Mobile, model.FirstName, model.FirstName,
model.Email1, model.Zipcode, model.SelectedKid1, model.SelectedKid2, model.SelectedKid3,
model.Gender.ToString(), interests, passing);
model.XmlToSend = xml;
if (xml.Contains("error"))
{
model.ErrorMessage = xml;
return View("Register/Step1", model);
}
return View("Register/Step2", model);
}
[HttpPost]
public ActionResult RegisterStep2(MemberViewModel model)
{
var result = MemberclubHelper.SendCreateUser(model.XmlToSend, model.Password);
if (result.Contains("error"))
{
model.ErrorMessage = result;
return View("Register/Step2", model);
}
else
{
return View("Register/Finished");
}
}
I think you may be better served by creating a separate view model for each step (i.e., MemberViewModelStep1). To me this seems like only some of your MemberViewModel properties will will be set in each step unless you carry a lot of that state between steps via hidden inputs or some other mechanism.
Alternatively, have you considered using JavaScript to build up that state between across your steps and then submitting a single post with your fully populated MemberViewModel?

Resources