I have tried all possible ways to get the JSON data from my webservice. I can see the JSON data in fiddler. Everything is fine except the data is not binding with the grid. here is my code.
Webservice (Mywebservice.asmx)
[WebService(Namespace = "http://myServiceLink.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class SmartlinkService : System.Web.Services.WebService
{
[WebMethod(CacheDuration = AppConsts.NONE)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false, XmlSerializeString = false)]
public List<SampleClass> GetTasks()
{
List<SampleClass> listSampleClass = new List<SampleClass>(){
new SampleClass{TaskId="1",TaskName="task1"},
new SampleClass{TaskId="2",TaskName="task2"},
new SampleClass{TaskId="3",TaskName="task3"},
new SampleClass{TaskId="4",TaskName="task4"}
};
return listSampleClass;
}
[Serializable]
public class SampleClass
{
public string TaskId { get; set; }
public string TaskName { get; set; }
}
}
User Control (UserControl.ascx)
<link href="Resources/extJS/resources/css/ext-all-debug.css" />
<script src="Resources/extJS/ext-all-debug.js" language="JavaScript" />
<script src="Resources/extJS/Ext.ux.AspWebAjaxProxy.js" ResourceType="JavaScript" />
<div class="section" runat="server" id="senchaGrid">
<h1 class="mhdr">
Project Tasks
</h1>
<div class="content">
<div class="swrap">
<%--sencha grid area--%>
<div id="topic-grid">
</div>
</div>
</div>
ExtJS Script Code
<script type="text/javascript" language="javascript">
/**********************************Sencha Grid Code START***********************************/
Ext.Loader.setConfig({ enabled: true });
Ext.Loader.setPath('Ext.ux', '../Resources/extjs/examples/ux');
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.panel.*',
'Ext.util.*',
'Ext.toolbar.Paging',
'Ext.ux.PreviewPlugin',
'Ext.ModelManager',
'Ext.layout.container.Border',
'Ext.tip.QuickTipManager'
]);
Ext.onReady(function () {
Ext.QuickTips.init();
// setup the state provider, all state information will be saved to a cookie
Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));
Ext.namespace('EXT');
Ext.define('myModel', {
extend: 'Ext.data.Model',
fields: ['TaskId', 'TaskName'],
id: 'TaskId'
});
var storeData = new Ext.data.Store(
{
autoLoad: true,
proxy: new Ext.ux.AspWebAjaxProxy({
url: '/ProjectManagement/Mywebservice.asmx/GetTasks',
actionMethods: {
read: 'POST'
},
reader: {
type: 'json',
model: 'myModel',
root: 'd'
},
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
})
});
//var pluginExpanded = true;
debugger;
var myGrid = Ext.create('Ext.grid.Panel', {
width: 1115, height: 500,
//title: 'Manage tasks',
store: storeData,
//disableSelection: true,
//stateful: true,
//stateId: 'stateGrid',
loadMask: true,
// grid columns
columns: [
{ text: 'TaskId', dataIndex: 'TaskId', header: 'Row #' },
{ text: 'TaskName', dataIndex: 'TaskName', header: 'Task Name' }
],
// paging bar on the bottom
bbar: Ext.create('Ext.PagingToolbar', {
store: storeData,
displayInfo: true,
displayMsg: 'Displaying tasks {0} - {1} of {2}',
emptyMsg: "No topics to display"
}),
renderTo: 'topic-grid'
});
// trigger the data store load
//store.load();
});
/**************************Sencha Grid Code END******************************/
Ext.ux.AspWebAjaxProxy.js
/// <reference path="/Scripts/ext-all-debug.js" />
Ext.define('Ext.ux.AspWebAjaxProxy', {
extend: 'Ext.data.proxy.Ajax',
require: 'Ext.data',
buildRequest: function (operation) {
var params = Ext.applyIf(operation.params || {}, this.extraParams || {}),
request;
params = Ext.applyIf(params, this.getParams(params, operation));
if (operation.id && !params.id) {
params.id = operation.id;
}
params = Ext.JSON.encode(params);
request = Ext.create('Ext.data.Request', {
params: params,
action: operation.action,
records: operation.records,
operation: operation,
url: operation.url
});
request.url = this.buildUrl(request);
operation.request = request;
return request;
}
});
The JSON data which I get from server (Inspected in Fiddler)
{"d":[{"__type":"Mywebservice+SampleClass","TaskId":"1","TaskName":"task1"},{"__type":"Mywebservice+SampleClass","TaskId":"2","TaskName":"task2"},{"__type":"Mywebservice+SampleClass","TaskId":"3","TaskName":"task3"},{"__type":"Mywebservice+SampleClass","TaskId":"4","TaskName":"task4"}]}
I do not get any exception anywhere in browser. All seems perfect but still I do not understand why it is not binding the grid with data. It only shows an empty grid with column headers and paging tool bar.
Can anyone tell me what I am missing here?
Taking a look at your store, I see you have a proxy/reader defined - but your model config is on the wrong object.
model should be on the store - not the reader:
var storeData = new Ext.data.Store(
{
autoLoad: true,
model: 'myModel',
proxy: new Ext.ux.AspWebAjaxProxy({
url: '/ProjectManagement/Mywebservice.asmx/GetTasks',
actionMethods: {
read: 'POST'
},
reader: {
type: 'json',
root: 'd'
},
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
})
});
Related
I am currently trying to pass data from a controller to a view to display a pie Chart. But instead of a Pie Chart the webpage is only displaying the string as shown below. How can I get this to show the Pie Chart and not the string
Controller Code
c#
public ActionResult Index()
{
return Json(Result(), "text/plain",JsonRequestBehavior.AllowGet);
}
View Code
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/x-www-form-urlencoded;charset=utf-8; charset = utf - 8",
cache: false,
url: '#Url.Action("Index", "Home")',
success: function (result) {
console.log(result);
google.charts.load('current', {
'packages': ['corechart']
});
google.charts.setOnLoadCallback(function () {
drawChart(result);
});
}
});
});
function drawChart(result) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Marks Obtained');
var dataArray = [];
$.each(result, function (i, obj) {
dataArray.push([obj.stdName, obj.marksObtained]);
});
data.addRows(dataArray);
var columnChartOptions = {
title: "Students Performance",
width: 1000,
height: 400,
bar: { groupWidth: "20%" },
};
var columnChart = new google.visualization.PieChart(document
.getElementById('piechart_div'));
columnChart.draw(data, columnChartOptions);
}
</script>
</head>
<body>
<div id="piechart_div"></div>
The strange thing is that I downloaded an example, which works fine, and I set up a new MCV project and added the code exactly the same, but my project shows the string, while the project I downloaded will display the pie chart with no problems. I am really confused as to why this is happening
I am working on Kendo UI jQuery grid CRUD. I can get data display in the grid, but not adding new records.
When I click the update button to add a record after filling up columns in the pop-up window, nothing is posted to the server side as every property has a null value.
The picture shows what I got when the button is pressed.
Controller:
[HttpPost]
public JsonResult AddLostProperty(LostPropertyViewModel lostProperty)
{
try
{
using (var dbContext = new DBEntities())
{
if (lostProperty != null)
{
var newLostProperty = new sz_LostProperty()
{
Name = lostProperty.PropertyName,
CategoryId = dbContext.sz_PropertyCategory.Where(x => x.Name == lostProperty.CategoryName).Select(c => c.Id).FirstOrDefault(),
Description = lostProperty.PropertyDescription,
FoundDate = lostProperty.FoundDate,
FoundLocation = lostProperty.FoundLocation,
CratedDate = DateTime.UtcNow.Date,
CratedBy = ""
};
dbContext.sz_LostProperty.Add(newLostProperty);
dbContext.SaveChanges();
return Json(new { Success = true, Message = "The Property has been added." });
}
else
{
return Json(new { Success = false, Message = "No lost property added." });
}
}
}
catch (Exception e)
{
return Json(new { Success = false, Message = "Error: " + e });
}
}
JavaScript:
<script>
$(document).ready(function () {
var serviceBaseUrl = "#Request.Url.ToString()",
lostPropertyDataSource = new kendo.data.DataSource({
transport: {
create: {
url: serviceBaseUrl + "/AddLostProperty",
type: "POST",
dataType: "json",
complete: function (e) {
$('#manageLostPropertiesGrid').data('kendoGrid').dataSource.read();
}
},
read: {
url: serviceBaseUrl + "/GetLostProperties",
type: "GET",
dataType: "json"
},
update: {
url: serviceBaseUrl + "/UpdateLostProperty",
type: "PUT",
dataType: "json"
},
destroy: {
url: serviceBaseUrl + "/DeleteLostProperty",
type: "DELETE",
dataType: "json"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
pageSize: 20,
schema: {
model: {
id: "PropertyId",
fields: {
PropertyId: { editable: false, nullable: true, type: "number" },
PropertyName: { type: "string", editable: true, validation: { required: true } },
CategoryId: { type: "number", editable: true, validation: { required: true } },
PropertyDescription: { validation: { required: false } },
Image: { validation: { required: false } },
FoundDate: { type: "Date" },
FoundLocation: { editable: true, validation: { required: false } }
}
}
}
});
$("#manageLostPropertiesGrid").kendoGrid({
dataSource: lostPropertyDataSource,
pageable: true,
height: 550,
toolbar: ["create"],
columns: [
{ field: "PropertyName", title: "Property Name", width: "150px" },
{ field: "CategoryName", title: "Category", editor: propertyCategoryList,/* template: "#=CategoryName#", */width: "150px"},
{ field: "PropertyDescription", title: "Description", width: "200px" },
{ field: "FoundDate", title: "Found Date", template: "#= kendo.toString(kendo.parseDate(FoundDate, 'dd-MM-yyyy'), 'dd-MM-yyyy') #", width: "130px" },
{ field: "FoundLocation", title: "Found Location", width: "120px" },
{ command: ["edit", "destroy"], title: " ", width: "250px" }],
editable: "popup"
}).data("kendoGrid");
});
From the browser, I can see the object sent to the server below:
What am I doing wrong?
I believe that in this case is problem in your parameter type at server side.
You have enabled batch: true editing which is useful if you want make many changes in your grid but send only one request with changed models in the end. It is very useful for example in case of inCell edit mode, when you would see many many requests and so decrease them is something you want, but in case of popup edit, I personally do not see any reason to use batch editing, but yes, I know Telerik has this in their demo.
So, because batch editing is enabled, there is called parameterMap before request is executed. (note: parameterMap is called only if you have batch edit enabled, otherwise it's ignored). That parameterMap wraps all your models into json string array and send that array with request to the server. In your case, there is always one record edited, but it doesn't matter - it will be sent as an array (in json string format).
Because it is sent as serialized string, you can
1) Change parameter of your AddLostProperty method to string models and then deserialize into array which allows you to work with it as you are used to
public ActionResult AddLostProperty(string models)
{
...
var data = JsonConvert.DeserializeObject<IEnumerable<LostPropertyViewModel>>(models);
...
}
2) If we will follow Telerik demo, you can use such implementation
public ActionResult AddLostProperty()
{
var products = this.DeserializeObject<IEnumerable<LostPropertyViewModel>>("models");
if (products != null)
{
//logic
}
return this.Jsonp(products);
}
3) And this is solution I would prefer
Just remove batch: true and parameterMap (since without batch it's useless) - and it should start send single object to your server method.
I click "ok" and in console error :
I'm new to programming and I need help. I need to use json to form a datatable from several data structures. At this point, I'm stuck on this error. Help please understand
The function in the controller is json.
[HttpGet]
public JsonResult Lowx()
{
var query = db.Infos.
Include(x => x.Profile).
Include(x => x.Cars).
ToList();
return Json(new { data = query });
}
table and ajax
<table class= "table" id="example" >
<thead>
<tr >
<th>first name</th>
<th>last name</th>
<th>middle name</th>
<th>birthday</th>
<th>carname</th>
<th>carnumber</th>
</tr>
</thead>
<tbody></tbody>
</table>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/DataTables/jquery.dataTables.min.js"></script>
<script type="text/javascript">
$(document).ready(function (data) {
$("#example").DataTable({
ajax: {
url: '#Url.Action("Lowx")',
type: 'GET',
dataSrc: ""
},
columns: [
{ data: "FirstName", name: "FirstName" },
{ data: "LastName", name: "LastName" },
{ data: "MiddleName", name: "MiddleName" },
{ data: "BirthDate", name: "BirthDate" },
{ data: "CarName", name: "CarName" },
{ data: "CarNumber", name: "CarNumber" }
]
});
Console: Failed to load resource: the server responded with a status of 500 (Internal Server Error).
SCREENSHOTS FOR ALFRED AND ALL)
Screenshot copy-paste
Try copy-pasting this example in your view file. When it works fine, change the url to parse your own data and it should work. Note that the action is a POST, not a GET.
[HttpPost]
public JsonResult Lowx()
{
var query = db.Infos.Include(x => x.Profile).Include(x => x.Cars).ToList();
return Json(new { data = query });
}
http://jsfiddle.net/bababalcksheep/ntcwust8/
$(document).ready(function () {
var url = 'http://www.json-generator.com/api/json/get/cbEfqLwFaq?indent=2';
var table = $('#example').DataTable({
'processing': true,
'serverSide': true,
'ajax': {
'type': 'POST',
'url': url,
'data': function (d) {
return JSON.stringify( d );
}
}
});
$('#reload').click(function (e) {
table.ajax.reload();
});
$('.toggleCols').click(function (e) {
e.preventDefault();
var column = table.column( $(this).attr('data-column') );
column.visible( ! column.visible() );
});
});
Please declare the DataTable as follows:
$('#example').DataTable({
"ajax": {
"url": '#Url.Action("Lowx")',
"dataSrc": ""
},
"columns": [
{ "FirstName", "data.Profile.FirstName" },
{ "LastName", "data.Profile.LastName" },
{ "MiddleName", "data.Profile.MiddleName" },
{ "BirthDate", "data.Profile.BirthDate" },
{ "CarName", "data.Cars.CarName" },
{ "CarNumber", "data.Cars.CarNumber" }
]
});
In Chrome, look at the Network tab to see if the Ajax call was formed properly. In Visual Studio, put a Breakppoint at the beginning of Lowx() to see if you reach the code. Please share your findings.
I'm developing a web application with Telerik Kendo in Razor. Here is my problem:
I have a variable that I set as a type List<class>.
#{
ViewBag.Title = "Home Page";
var dpdminst = new DB();
var data = dpdminst.getdata();}
I want to be able to use this variable (data) to set my DataSource in my Javascript:
<script>
var displaydata = #data
$(document).ready(function () {
$("#grid").kendoGrid({
height: 550,
groupable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
dataSource: {
data:displaydata,
schema: {
model: {
fields: {
amount: { type: "string" },
}
}
},
columns:["amount"]
}
});
});
</script>
Does anyone know if this can be done?
Here is my JsonResult:
public JsonResult GetJsonData()
{
var DBinst = new DB();
var TradeData = DBinst.tradedata();
var json = JsonConvert.SerializeObject(TradeData);
var result = new JsonResult()
{
Data = json
};
return result;
}
Have an action method which returns the data you want in JSON format. in your document.ready event, make an ajax call to get this data and then you can set it as your data source.
public ActionResult GetJsonData()
{
var dpdminst = new DB();
var data = dpdminst.getdata();
return Json(data,JsonRequestBehaviour.AllowGet);
}
and in your view use the getJSON method to get data from this action method and use that as needed. You may format the incoming json as per your UI requirements
$(document).ready(function () {
$.getJSON("#Url.Action("GetJsonData","YourControllerName")",function(data){
// you have your json data in the "data" variable.
// now you may use it to set the data source of your grid library
});
});
If you dont want to deal with ajax/json, then I would try to achieve what you want as follows:
<script>
var displaydata = [
#foreach (var record in dpdminst.getdata())
{
#: { amount: '#record' },
}
];
$(document).ready(function () {
$("#grid").kendoGrid({
height: 550,
groupable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
dataSource: {
data:displaydata,
schema: {
model: {
fields: {
amount: { type: "string" },
}
}
},
},
columns:["amount"]
});
});
</script>
Also please notice that you had columns:["amount"] in a wrong place, also this code has to be in your cshtml for razor syntax to work properly.
Using knockout, I want to be able to call a different Ajax method and update my HTML. I have one button on my screen, it calls a different method (just for show).
For now I'm trying to do this with one method: "GetPopularChannelResult" However, when I try this and combine it with the mapping plugin, I noticed that data is returned, but my model does not update. This is on page load.
I also want this to work in asynchronously.
I found some articles on loading ajax: http://www.knockmeout.net/2011/06/lazy-loading-observable-in-knockoutjs.html
https://github.com/knockout/knockout/wiki/Asynchronous-Dependent-Observables
HTML
<button class="btn btn-sm" data-bind="click: toggleChannelButton(), text: btnText()"></button>
<div class="row">
<div class="col-md-9">
<img src="~/Content/Images/ajax-loader.gif" id="spinner" class="ajax-loader" alt="ajax loader" />
#* TODO: link to a video page *#
<section id="channelResult" class="hide" data-bind="foreach: channel.data.records">
<p data-bind="text: username"></p>
<video width="400" height="400" controls>
<source data-bind="attr: { src: videoUrl }" type="video/mp4" />
</video>
<p data-bind="text: description"></p>
</section>
</div>
</div>
JS
$(function() {
var channelIdFromUrl = $.url().param('channelId');
var pageFromUrl = $.url().param('page');
// The ViewModel
my.vm = function () {
var channel = {
code: ko.observable('waiting for data'),
data: [
{
count: ko.observable(0),
records: [
{
liked: ko.observable('0'),
foursquareVenueId: ko.observable(null),
userId: ko.observable(0),
private: ko.observable(0),
likes: ko.observableArray([{}]),
thumbnailUrl: ko.observable('waiting for data'),
explicitContent: ko.observable(0),
vanityUrls: ko.observableArray([{}]),
verified: ko.observable(1),
avatarUrl: ko.observable('waiting for data'),
comments: ko.observableArray([{}]),
entities: ko.observableArray([{}]),
videoLowURL: ko.observable('waiting for data'),
permalinkUrl: ko.observable('waiting for data'),
username: ko.observable('waiting for data'),
description: ko.observable('waiting for data'),
tags: ko.observableArray([{}]),
postId: ko.observable(0),
videoUrl: ko.observable('waiting for data'),
created: ko.observable('waiting for data'),
shareUrl: ko.observable('waiting for data'),
myRepostId: ko.observable(0),
promoted: ko.observable(0),
reposts: ko.observableArray([{}])
}
],
nextPage: ko.observable('0'),
size: ko.observable('0'),
anchorStr: ko.observable('waiting for data'),
previousPage: ko.observable(null),
anchor: ko.observable('waiting for data')
}
],
success: ko.observable('waiting for data'),
error: ko.observable('waiting for data')
},
getRecords = function () {
// It returns undefined first round, until json returns...
return my.vm.channel.data.records;
},
channelData = {
ChannelId: ko.observable(channelIdFromUrl),
Page: ko.observable(pageFromUrl)
},
// TODO: work on this toggle later
//isPopular = ko.observable(true),
//toggleChannelButton = function() {
// if (this.IsPopular()) {
// this.IsPopular(false);
// self.btnText('Get Popular');
// } else {
// this.IsPopular(true);
// self.btnText('Get Recent');
// }
//},
//btnText = ko.observable('Get Recent'),
loadChannelPopularCallback = function (json) {
var parsedJson = $.parseJSON(json);
ko.mapper.fromJS(parsedJson, {}, my.vm.channel);
},
loadPopularChannel = function() {
my.VineDataService.getVineItems(my.vm.loadChannelPopularCallback, channelData, "GetPopularChannelResult");
};
return {
channel: channel,
channelData: channelData,
loadChannelPopularCallback: loadChannelPopularCallback,
getRecords: getRecords,
loadPopularChannel: loadPopularChannel
//IsPopular: isPopular,
//toggleChannelButton: toggleChannelButton,
//btnText: btnText
};
}();
my.vm.loadPopularChannel();
ko.applyBindings(my.vm);
});
JS dataservice.js
// Depends on scripts:
// ajaxservice.js
(function (my) {
"use strict";
my.VineDataService = {
getVineItems : function (callback, channelData, method) {
my.ajaxService.ajaxGetJson(method, channelData, callback);
}
};
}(my));
ajax service
// ajaxService
// Depends on scripts:
// jQuery
(function (my) {
var serviceBase = '/Home/',
getSvcUrl = function (method) { return serviceBase + method; };
my.ajaxService = (function () {
var ajaxGetJson = function (method, jsonIn, callback) {
$.ajax({
url: getSvcUrl(method),
type: 'GET',
data: ko.toJS(jsonIn),
dataType: 'JSON',
contentType: 'application/json; charset=utf-8',
success: function (json) {
callback(json);
}
});
},
ajaxPostJson = function (method, jsonIn, callback) {
$.ajax({
url: getSvcUrl(method),
type: "POST",
data: ko.toJSON(jsonIn),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (json) {
callback(json);
}
});
};
return {
ajaxGetJson: ajaxGetJson,
ajaxPostJson: ajaxPostJson
};
})();
}(my));
My Namespace
var my = my || {}; //my namespace
Like the previous post mentions, just call one method and handle the logic using a boolean observable to call a different method and toggle it on each call:
Markup:
<div data-bind="text:results"></div>
<input type="button" data-bind="click: getResults, value:btnText()" />
JS:
var ViewModel = function() {
var self = this;
self.getPopular = ko.observable(true);
self.results = ko.observable('displaying POPULAR results...');
self.btnText = ko.observable('Get Recent');
self.getResults = function () {
if(self.getPopular())
{
self.getPopular(false);
self.results('displaying RECENT results...')
self.btnText('Get Popular');
}
else
{
self.getPopular(true);
self.results('displaying POPULAR results...')
self.btnText('Get Recent');
}
}
};
ko.applyBindings(new ViewModel());
Working example JSFiddle
You don't have to change the data-bind. Instead you can manage the toggle inside the click handler you bind to your element. Keep a flag that you toggle, and use it to decide which method to call.