i use from kendo grid but my grid dont fill with values and when show page grid dont load.
i use kendo 2014 and asp.net 2012.
my api controller code :
public class ValuesControllerApi : ApiController
{
public List<File> Get()
{
GuaranteeEntities ef = new GuaranteeEntities();
var file = ef.Files.Where(c => c.UpdaterUserInfo == "Guarantee").ToList();
return file;
}
}
and my html Code is :
<div id="employeesGrid">
<script>
$(function () {
$("#employeesGrid").kendoGrid({
dataSource: new kendo.data.DataSource({
transport: {
read: "/api/ValuesControllerApi"
}
})
});
});
$(function () {
$("#employeesGrid").kendoGrid({
columns: [
{ field: "Name" , title:"test" },
{ field: "Family", title: "test test" }
],
dataSource: new kendo.data.DataSource({
transport: {
read: "/api/ValuesControllerApi"
}
}),
sortable: true
});
});
</script>
</div>
Try testing your API in the browser alone.
localhost:12345/api/ValuesControllerApi (change your debugging url as required)
Does that work? Chances are, it doesn't. The reason is because WebApi uses a default pattern for finding the controller end point. You can find more info here.
But to spare you the time, take note of this line:
To find the controller, Web API adds "Controller" to the value of the {controller} variable.
What this means is by default, WebApi assumes all controller classes end in "Controller" when trying to route to an endpoint. In your case, you have named your API ValuesControllerApi which ends in "Api". Remove the "Api" from the class name and it should work.
So, your class name should look like this: ValuesController : ApiController
and you call it like this: api/Values
I think that your controller action won't give Kendo Grid the results in the format it expects. You need to send it a DataSourceRequest. There is a simple example here you may check.
Also this documentation article should shed some light on the issue too.
Hope it helps!
Related
I inherited some code and I am trying to figure the right url to a webapi controller but my knowledge of mvc web api is lacking.
I have inline script that is making an ajax post like this:
$('#saveNewEducation').on('click', function () {
var educationAdd = {
'educationId': $('#newEducation').val(),
'startDate': $('#newEducationDate').val(),
'identificationId': $('#identificationId').val(),
'educationNote': $('#newEducationNote').val(),
'examinerId': $('#newExaminer').val()
};
$.post('#Url.HttpRouteUrl("DefaultApi", new { controller = "EmployeeApi", educationName = "educationCreate" })', educationAdd)
.done(function (data, textStatus, jqXhr) {
if (jqXhr.status == 200) {
$('#save-education').modal('show');
} else {
$('#fail-save-employee').modal('show');
}
})
.fail(function (jqXhr) {
var education = $("#new-education");
if (jqXhr.status == 409) {
$('#future-save-employee').modal('show');
} else {
if (jqXhr.status == 400) {
clearErrors(education);
var validationErrors = $.parseJSON(jqXhr.responseText);
$.each(validationErrors.ModelState, function (i, ival) {
remoteErrors(education, i, ival);
});
} else {
$('fail-save-employee').modal('show');
}
}
});
I don't like inline script and I have created a seperate js file where I want to make this call from.
I need help with
I need help figuring out the right url to the api controller so that i can use it in the script file.
I tried
Reading this article I tried the following:
$.post('/DefaultApi/EmployeeApi', educationAdd)
This gave me a
404 not found error.
in the inline script the url is like this:
$.post('#Url.HttpRouteUrl("DefaultApi", new { controller = "EmployeeApi", educationName = "educationCreate" })', educationAdd)
WebApiConfig.cs file:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
method I am trying to access in EmployeeApi controller:
public IHttpActionResult EducationPost(EmployeeEducation model, string educationName){}
How can I do this?
Resolving the URL
Generally in MVC applications, you would resolve this by using the Url.Action() helper to resolve the proper URL provided its Controller, Action and RouteValues:
// Supply the Action, Controller and any route values that you need
$.post('#Url.Action("EducationPost","EmployeeApi", new { educationName = "educationCreate"})', function(){
// Do something here
});
However, Web API also features the Url.Link() helper that might be useful as well and works in a similar manner except based on the route itself :
$.post('#Url.Link("DefaultApi", new { controller = "EmployeeApi", action = "EductationPost", educationName = "educationCreate" })', function(){
// Do something here
});
When using External Javascript Files
As you would imagine, these techniques won't work when using external Javascript files. What I generally recommend in these situations is to consider using a data-* attribute in HTML to store the URL and then reference that within your event handler that will trigger the AJAX call :
<button id='call-ajax' data-post-url='#Url.Action(...)' />
<script>
$(function(){
$('#call-ajax').click(function(e){
// Read the attribute and use it
$.post($(this).attr('data-post-url'), function(){
// All done
});
});
});
</script>
You could obviously accomplish this same basic idea through the use of variables or hidden elements, but the same idea basically holds true as far as actually accessing it goes.
Have a look at this answer:
How to send razor created Url to js file
This user offers 3 possible solutions.
global js variable
custom "data-" attribute
hidden input
I know this sounds like a daft question but is there a way to 'mimic' WebAPI routing style (i.e maybe using the [HttpPost] decoration etc) for a MVC Controller. The gist of my problem is I have a 'container' MVC site. This contain in PreLoad loads up other MVC sites within the areas folder and incorporates them into itself. So it basically acts as a Plugin system. This all works great however I need to add in an API for this site which I thought would be a lot easier just if I made the API as another plugin.
I am using Ninject in my site which again works great getting the dependancies from the plugins all perfectly. The issue is that Ninject automatically detects the MVC Controllers but not the WebAPI ones and I've found out you can't have one project doing both WebAPI and MVC with Nijnect. So my next option is to try and mimic WebAPI within MVC (after all, they are based upon the same thing really.)
I initially thought this would be really easy, default the action name to 'Index' in the routing and them just put the 'AcceptVerbs' decoration on each method. Of course it didn't work.
Does anyone know how I would go about or an alternative to creating something like a RestAPI using only the MVC side (not switching to WebAPI)?
In your RouteConfig.cs file, you can specify which HTTP verb goes to which action by passing an HttpMethodContraint:
routes.MapRoute(
"route that matches only GETs for your url",
"your url",
new { controller = "some controller", action = "some action" },
new { httpMethod = new HttpMethodConstraint("GET") });
This will allow you to define routes to your controller that will mimic WebAPI.
You can use Controllers like usual and have them return the JsonResult. I use this approach for some of my views that need dynamic lists through lookup but don't need to be going to the web api. Along with attribute routing I was able to get web api-like functionality from my MVC
Example scenario is I have a form that fills some fields based on a value selected form a combo box. When a user selects an option I use JQuery to make a call to the WebAPI-like action in my controller.
[RoutePrefix("Pickup")]
[Route("{action=Create}")]
public class PickupController : FrontOfficeAuthorizedController {
[HttpPost]
public JsonResult GetSenderAddress(Guid? addressId) {
if(addreddId != null) {
//Do something to get an address
if(address != null) {
//Only send required info over the wire
return Json(new {
success = true,
address = new {
Address1 = address.Address1,
Address2 = address.Address2,
AddressType = address.AddressType,
CompanyOrName = address.CompanyOrName,
Contact = address.Contact,
Country = address.Country,
PostalCode = address.PostalCode,
Telephone = address.Telephone,
TownCity = address.TownCity,
}
});
}
}
return Json(new { success = false });
}
}
Here is a snippet of the javascript on the client side. Note I'm using Knockout along with JQuery
//Shipfrom properties
self.ShipFromaddressid = ko.observable();
//Update shipfrom address based on id
self.ShipFromaddressid.subscribe(function () { getAddress(); });
var getAddress = function () {
var selectedAddressId = { addressId: self.ShipFromaddressid() };
$.ajax({
url: '#(Url.Action<PickupController>(c=>c.GetSenderAddress(null)))',
type: 'Post',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify(selectedAddressId),
success: handleResponse
});
};
var handleResponse = function (data) {
if (data.success) {
//console.log(data.address);
self.ShipFromCompanyOrName((data.address.CompanyOrName) ? data.address.CompanyOrName : "");
self.ShipFromContact((data.address.Contact) ? data.address.Contact : "");
self.ShipFromTelephone((data.address.Telephone) ? data.address.Telephone : "");
self.ShipFromAddress1((data.address.Address1) ? data.address.Address1 : "");
self.ShipFromAddress2((data.address.Address2) ? data.address.Address2 : "");
self.shipfromtowncity((data.address.TownCity) ? data.address.TownCity : "");
self.ShipFromPostalCode((data.address.PostalCode) ? data.address.PostalCode : "");
self.ShipFromCountry((data.address.Country) ? data.address.Country : "");
self.ShipFromAddressType((data.address.AddressType) ? data.address.AddressType : "");
}
};
So basically I'm trying to show some Profile Data in my MVC Application.
Right now, everytime I click on a date on my Telerik Kendo Calendar, I can refresh the whole page and update the data I want.
However, instead of refreshing the whole I just want to refresh the partial views that shows only the data that updates after selecting the date.
Index.cshtml
<!--CODE-->
#Html.Partial("_WorkingTimeData")
<!--CODE-->
_WorkingTimeData.cshtml
var workedTime = ViewData["WorkedTimeToday"];
var hoursPerDay = ViewData["HoursPerDayContract"];
<p>You worked #workedTime hours</p>
<p>Hours Per Day (Contract) #hoursPerDay Hours</p>
Yes, right now I'm ViewDatas and it works.
This is the ajax code in Index.cshtml
$.ajax({ url: '/Profile/Index',
dataType: "json",
type: "POST",
data: JSON.stringify(10),
success: function(returl){
alert('It worked');
location.href=returl.Url;
},
error: function(jqXHR,responseText,textStatus){ alert(jqXHR.responseText) } });
Controller
[HttpPost]
public ActionResult Index(string number){
//THINGS TO DO
var redirectUrl = new UrlHelper(Request.RequestContext).Action("Index", "Profile");
return Json(new { Url = redirectUrl });
}
Well I'm very new to this, and I've been doing my research. However I still have some questions:
- Do I need to create a post method for _WorkingTimeData instead of Index like I have?
- Do I need to create a ViewModel for the Partial View?
Thanks
EDIT NUMBER 2 FOR VISHAL:
This didn't work at all, not even an alert, because, strangely, it doesn't recognise the calendar...
$("#calendar").kendoCalendar({
change : function() {
$.ajax({
url: "/Profile/WorkingTimeData",
type: "get"
}).done(function(data) {
$("#profile-timeline").html(data);
});
}});
It says $("#calendar").kendoCalendar is not a function (Telerik says that it's this way)
As for this, it reached the controller but didn't update anything:
function change() {
alert("Escolheste outro dia");
var calendar = $("#calendar").data("kendoCalendar");
var current = calendar.current();
alert(current);
$.ajax({
url: "/Profile/WorkingTimeData",
type: "get"
}).done(function(data) {
$("#profile-timeline").html(data);
});
}
I think it's because of the profile-timeline... It's a div in my view
Do I need to create a post method for _WorkingTimeData?
Yes, you need to create. But, Get would be fine too.
Do I need to create a ViewModel for the Partial View?
Not needed. If required you can create.
But, by looking at your partial view you are just using ViewData[""]. So, you need not to create any ViewModel.
Just create a method in Controller returning _WorkingTimeData PartialView.
And call that method by JQuery ajax on your DatePicker change event and replace the contents of the Div.
For example.
Controller
public PartialViewResult WorkingTimeData()
{
ViewData["WorkedTimeToday"]="NEW VALUE";
ViewData["HoursPerDayContract"] = "NEW VALUE";
return this.PartialView("_WorkingTimeData");
}
JavaScript
$("DATEPICKERELEMENT").change(function() {
$.ajax({
url: "/CONTROLLER/WorkingTimeData",
type: "get"
}).done(function(data) {
alert(data);
$("#divisionIdContainingPartialView").html(data);
}).fail(function() {
alert('error');
});
});
I wrote a post that details why you need to break the logic of thinking about partial views client-side. If you're interested you can find it here.
The TL;DR version is simply, all you have client-side is HTML. There's no knowledge about what was or was not rendered to the response via a partial view. As a result, the real question is "How do I change a portion of my HTML page based on an AJAX response?". In the simplest form, you simply select some element on the page and then alter its inner HTML. You can do that with some custom HTML created client-side or you can actually pass back an HTML document as your AJAX response and then insert that.
I have a question regarding the calling method from view.
Basically on my view I have 2 links:
1 link : When I click on it, some method should be called and executed, but nothing should change on webpage, so no postback.
2 link: When I click on it, some method should happen and postback can happen, on the same page
In controller I have:
public ActionResult FirstMethod(){ return View();}
public ActionResult SecondMethod(){ return View();}
In view:
#Html.ActionLink("Action 1", "FirstMethod", "Controller");
#Html.ActionLink("Action 2", "SecondMethod", "Controller");
So when I click on both action happens but then i get an error saying cannot find FirstMethod.chtml ..
So is this possible to have one method with postback and another one without? And how to return to the same page ... and not try to get FirstMethod.chtml ..
Following solution is based on AJAX -
Controller -
public class DemoController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult CallMe()
{
return new ContentResult() { Content = "This is Demo " };
}
}
Index.cshtml -
<h2>Index</h2>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
$(function () {
$("#Click").click(function () {
$.ajax({
url: "/Demo/CallMe",
type: "GET",
error: function (response) {
alert(response);
},
success: function (response) {
alert(response);
}
});
});
})
</script>
<input type="button" value="Click" id="Click" />
First navigate to /demo/Index, that will display the page with above markup with a button in the page. And when we click on the Click button, we have -
The #Html.ActionLink method basically just forwards you to the specified controller-action, you cannot change this, since this is the purpose of the method.
You have to handle the click client-side, and bind a specific action to it (post some data to a url, and do nothing afterwards). One fairly easy way to do this, is to use jQuery.Post
Example from the above jquery link.
Example: Request the test.php page, but ignore the return results.
$.post("test.php");
Actually, there is no postback concept in asp.net mvc. all interactions with server should via the controller/action.
#Html.ActionLink() method just generate a link(tag a in html) and do nothing. everything happens after you send a request(such as click the link) to controller/action, if you want do nothing when click the link, you'd better use AJAX method like this
#Html.ActionLink("Action 1", "FirstMethod", "Controller", null/*routeValues*/, new { id = "link1Id" });
<script type="text/javascript">
$(function () {
$("#link1Id").click(function () {
$.get("/Contoller/FirstMethod", function () {
//do nothing or alert(something)
});
return false;
});
})
</script>
You can simply return another view after you've done what you wanted in your controller action:
public ActionResult SecondMethod()
{
//do something
return View("FirstMethod");
}
After you've seen this you will most probably be disgusted by the use of magic strings to reference views or controllers and that disgust is completely understandable :)
Then you should look whether something like T4MVC could fit your needs.
I have a controller class that I get data from database and return it in a function, Now I want to call this function in a js and set the data in variables to show in a page:
My code looks like: exampleController.cs
namespace iSee.WebApiHse.Controllers
{
public class expController : StandardController
{
public expController(
first myService,
ISystemSettings systemSettings,
IService myExpService)
{
_myService = MyService;
_systemSettings = systemSettings;
_myExpService = myExpService;
}
// GET data
public ActionResult Myexample(int id)
{
var elementIds = _systemSettings.ExpIds;
var myElements = CacheService.AllVisibleElements
.Where(x => elementIds.Contains(x.Id)).ToList();
var container = _kpiContainerService.Find(id);
var result = _myService.MonthByContainer(myElements, container);
return AsJson(result);
}
}
}
This works and I get the data. Now I have myExp.js that I need to use these data in it. How can I do that?
Thanks
You need to execute $ajax(..) (jquery syntax) request to your controller to pass and get compute information from the server.
For this your controller method, that you're going to call, has to be exposed for HTTP access.
More details on :
How to call controller method from javascript
Do you want work with your controller in View by JavaScript? It isn't good idea. You should pass Model to View and work with it or ajax and recieve json-data
An example that uses jQuery-ajax to call your C# method:
// javascript
var id = 987;
$.ajax({
url : '/expController/Myexample/',
type : 'GET',
data { id : id },
dataType : 'json', // <-- tell jQuery to decode the JSON automatically
success : function(response){
console.log(response);
}
});
This would call your method, passing in the value of id, then it would decode the JSON into the response object.
For plain Javascript ajax (no jQuery) see MDN Ajax.
You need to make a request to the Action Myexample. Usually this is done via AJAX:
In your view you could have:
function makeAJaxCall(idToSend) {
$.ajax({
url: '#Url.Action("exp", "Myexample")',
data: { id : idToSend },
type: "POST",
success: function(data) {
$("#HTMLElement").val(data.YourData);
}
});
}
Your response will come back in the data variable if the AJAX call succeeds. I have provided an example to show you how to change the value of an HTML element with the ID HTMLElement.
To invoke the function you can do:
makeAjaxCall(100);
You may load the JSON data in a var and pass it to the function in expjs.js, as:
var data = data_from_ajax();
exp_js_function(data);
data_from_ajax() would receive JSON data from your controller and action method.
Please consider this as a starting point and not as a copy-paste solution