How to call a C# function from JavaScript? - javascript

I want to call CsharpFunction, a C# function in code-behind, from JavaScript. I tried the code below but whether the JavaScript condition is True or False, CsharpFunction was called regardless!
JavaScript code:
if (Javascriptcondition > 0) {
<%CsharpFunction();%>
}
C# code behind:
protected void CsharpFunction()
{
// Notification.show();
}
How do I call a C# function from JavaScript?

You can use a Web Method and Ajax:
<script type="text/javascript"> //Default.aspx
function DeleteKartItems() {
$.ajax({
type: "POST",
url: 'Default.aspx/DeleteItem',
data: "",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
$("#divResult").html("success");
},
error: function (e) {
$("#divResult").html("Something Wrong.");
}
});
}
</script>
[WebMethod] //Default.aspx.cs
public static void DeleteItem()
{
//Your Logic
}

.CS File
namespace Csharp
{
public void CsharpFunction()
{
//Code;
}
}
JS code:
function JSFunction() {
<%#ProjectName.Csharp.CsharpFunction()%> ;
}
Note :in JS Function when call your CS page function.... first name of project then name of name space of CS page then function name

A modern approach is to use ASP.NET Web API 2 (server-side) with jQuery Ajax (client-side).
Like page methods and ASMX web methods, Web API allows you to write C# code in ASP.NET which can be called from a browser or from anywhere, really!
Here is an example Web API controller, which exposes API methods allowing clients to retrieve details about 1 or all products (in the real world, products would likely be loaded from a database):
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
};
[Route("api/products")]
[HttpGet]
public IEnumerable<Product> GetAllProducts()
{
return products;
}
[Route("api/product/{id}")]
[HttpGet]
public IHttpActionResult GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
The controller uses this example model class:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
Example jQuery Ajax call to get and iterate over a list of products:
$(document).ready(function () {
// Send an AJAX request
$.getJSON("/api/products")
.done(function (data) {
// On success, 'data' contains a list of products.
$.each(data, function (key, item) {
// Add a list item for the product.
$('<li>', { text: formatItem(item) }).appendTo($('#products'));
});
});
});
Not only does this allow you to easily create a modern Web API, you can if you need to get really professional and document it too, using ASP.NET Web API Help Pages and/or Swashbuckle.
Web API can be retro-fitted (added) to an existing ASP.NET Web Forms project. In that case you will need to add routing instructions into the Application_Start method in the file Global.asax:
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
Documentation
Tutorial: Getting Started with ASP.NET Web API 2 (C#)
Tutorial for those with legacy sites: Using Web API with ASP.NET Web Forms
MSDN: ASP.NET Web API 2

Use Blazor
http://learn-blazor.com/architecture/interop/
Here's the C#:
namespace BlazorDemo.Client
{
public static class MyCSharpFunctions
{
public static void CsharpFunction()
{
// Notification.show();
}
}
}
Then the Javascript:
const CsharpFunction = Blazor.platform.findMethod(
"BlazorDemo.Client",
"BlazorDemo.Client",
"MyCSharpFunctions",
"CsharpFunction"
);
if (Javascriptcondition > 0) {
Blazor.platform.callMethod(CsharpFunction, null)
}

Server-side functions are on the server-side, client-side functions reside on the client.
What you can do is you have to set hidden form variable and submit the form, then on page use Page_Load handler you can access value of variable and call the server method.
More info can be found here
and here

If you're meaning to make a server call from the client, you should use Ajax - look at something like Jquery and use $.Ajax() or $.getJson() to call the server function, depending on what kind of return you're after or action you want to execute.

You can't. Javascript runs client side, C# runs server side.
In fact, your server will run all the C# code, generating Javascript. The Javascript then, is run in the browser. As said in the comments, the compiler doesn't know Javascript.
To call the functionality on your server, you'll have to use techniques such as AJAX, as said in the other answers.

Related

How to create a connection between Angular.js and PostgreSQL using a WEB API 2 controller?

I am trying to connect an Angularjs script with a PostgreSQL database (the resulting HTML has to be able to show the data extracted from the PostgreSQL database). The PostgreSQL database was created locally with the default settings (during installation). I am working in the visual studio environment.
I tried using a similar approach to this (albeit this is meant to connect with a SQL Server rather than to a PostgreSQL database): http://cybarlab.com/crud-operations-in-angularjs-and-web-api
Essentially you define a web.config file with a connection string, create an object class for your database table rows, use update-database command in the Package Manager Console to create the appropriate table in the PostgreSQL database (which worked fine), create a WEB API 2 controller based upon the previously created object class (to get the CRUD operations) and get the data using $http.get function in the angular.js script (also invoking the controller in the html file).
The problem is, I have no idea what to write in the html.get(url) url field. All of my attempts have not been successful, which together with the lack of information on Google for this problem, leads me to believe this approach for PostgreSQL simply doesn't work. So is there any way to make it work? Or is there another way to establish the connection? While the description of the task does not note that the $http.get command should be used, it does note that this should be done using the WEB API 2 controller for the CRUD operations.
The connection string (the update-database command worked so it should be correct):
<connectionStrings>
<add name="TestProjectContext" providerName="Npgsql" connectionString="Server=127.0.0.1;Port=5432;Database=TestProject;User Id=postgres;Password=NotTelling;" />
</connectionStrings>
The class object (a table with these attributes was generated in the PostgreSQL database after using the update-table command):
public class DataDestination
{
[Key]
public Guid Id { get; set; }
public string Server { get; set; }
public string Port { get; set; }
public string Database { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string SqlType { get; set; }
public string Owner { get; set; }
}
The output table in HTML:
<body data-ng-app="app" data-ng-controller="TestController">
<table style="width:100%" , border="1">
<tr>
<td>Id</td>
<td>Server</td>
<td>Port</td>
<td>Database</td>
<td>Username</td>
<td>Password</td>
<td>SqlType</td>
<td>Owner</td>
</tr>
<tr data-ng-repeat="std in DataDestinations">
<td>
{{std.Id}}
</td>
<td>
{{std.Server}}
</td>
<td>
{{std.Port}}
</td>
<td>
{{std.Database}}
</td>
<td>
{{std.Username}}
</td>
<td>
{{std.Password}}
</td>
<td>
{{std.SqlType}}
</td>
<td>
{{std.Owner}}
</td>
</tr>
</body>
{{error}}
Finally, the angular.js script statement I tried to use (the rest of the script seems to be running fine and the error message is also thrown successfully):
$http.get('http://localhost:5432/TestProject').success(function (data) {
$scope.DataDestinations = data;
})
.error(function () {
$scope.error = "An Error has occured while loading posts!";
});
EDIT: Thank you for your responses. the WEB API 2 controller was created using the Add -> Controller -> WEB API 2 Controller with actions, using Entity Framework -> Choose the previously created class and context. So basically it was generated based on the class. Here is the code:
public class TestController : ApiController
{
private TestProjectContext db = new TestProjectContext();
// GET: api/Test
public IQueryable<DataDestination> GetDataDestinations()
{
return db.DataDestinations;
}
// GET: api/Test/5
[ResponseType(typeof(DataDestination))]
public IHttpActionResult GetDataDestination(Guid id)
{
DataDestination dataDestination = db.DataDestinations.Find(id);
if (dataDestination == null)
{
return NotFound();
}
return Ok(dataDestination);
}
// PUT: api/Test/5
[ResponseType(typeof(void))]
public IHttpActionResult PutDataDestination(Guid id, DataDestination dataDestination)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != dataDestination.Id)
{
return BadRequest();
}
db.Entry(dataDestination).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!DataDestinationExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
// POST: api/Test
[ResponseType(typeof(DataDestination))]
public IHttpActionResult PostDataDestination(DataDestination dataDestination)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.DataDestinations.Add(dataDestination);
try
{
db.SaveChanges();
}
catch (DbUpdateException)
{
if (DataDestinationExists(dataDestination.Id))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtRoute("DefaultApi", new { id = dataDestination.Id }, dataDestination);
}
// DELETE: api/Test/5
[ResponseType(typeof(DataDestination))]
public IHttpActionResult DeleteDataDestination(Guid id)
{
DataDestination dataDestination = db.DataDestinations.Find(id);
if (dataDestination == null)
{
return NotFound();
}
db.DataDestinations.Remove(dataDestination);
db.SaveChanges();
return Ok(dataDestination);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool DataDestinationExists(Guid id)
{
return db.DataDestinations.Count(e => e.Id == id) > 0;
}
}
}
I will also post the context for the object just in case that is wrong:
namespace TestProject.Models
{
public class TestProjectContext : DbContext
{
public TestProjectContext()
{
Database.SetInitializer<DbContext>(null);
}
public DbSet<DataDestination> DataDestinations { get; set; }
}
}
EDIT2: Added the CORS package to the project and added it to the beginning of the already defined WEB API controller:
using TestProject.Models;
using System.Web.Http.Cors;
namespace TestProject.Controllers
{
[EnableCors(origins: "http://localhost", headers: "*", methods: "*")]
public class TestController : ApiController
{
private TestProjectContext db = new TestProjectContext();
code is the same as in previous WEB API
Didn't fix the problem in and of itself. The same self defined error is being output - "An Error has occured while loading posts!".
After heeding Henri Cavalcante's request to create a WEB API, I ended up searching for the easiest way to do so and found the PostgREST program. What it does is automatically create an REST server based on your selected PostgreSQL database in the 3000 port. After doing so I could get the data out of the database without much hassle.
If there is anybody in a similar situation, here is a link for the postgREST first usage example: http://postgrest.com/examples/start/
In addendum I would like to say, that I really miss JDBC.
My suggestion is create a WEB api to make a connection between the front-end and the database.
You could use solutions like:
http://restify.com/ or http://loopback.io/
Or build your own solution using:
http://expressjs.com/ or http://koajs.com/

Angularjs, JavaEE and http request with inherited objects?

I work on webapp and can't find solution or example of my problem.
I use AngularJS, RestServis and JavaEE . My problem is how to send inherited object with superObject
In java I have two classes:
public class User{
protected String userName;
protected String userSurename;
..
..
}
Second class is a subclass
public class Worker extends User{
protected int idWorker;
protected String position;
..
..
}
in Angular controller I have
$scope.user = {
userName : "jon" ,
userSurename :"dep" }
$scope.worker= {
idWorker: 88 ,
position: "seller" }
and I use http protocol to send data on server side like this
this.saveWorker = function(worker) {
return $http({
method:'post',
url:this.apiBasicUrl,
contentType: "application/json",
data: worker
});
};
How in Angular in data to put one object and on Java side get worker object with user data also ? Can I , object like in java , make in angular with inherited ?
On Angular side, I suggest using $resource for communication with REST API:
var Worker = $resource('/worker/:workerId', {workerId:'#id'});
//get
var worker = Worker.get({workerId:123}, function() {
worker.abc = true;
//save
worker.$save();
});
On server side you should have a REST endpoint that is supposed to pick up these objects:
#Path("/worker")
public class WorkerService {
#GET
#Path("{workerId}")
public Worker getWorker(#PathParm("workerId") Integer workerId) {
//implement
}
#POST
public void saveWorker(Worker worker) {
//implement
}
}
This might not work out of the box. You will most likely need Jackson provider to enable REST to "translate" JSON into Java objects.
See this example: http://www.mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson/

Invalid web service call, missing value for parameter with Backbone and Webservice webmethods

Is it possible for backbone to interface with asp.net soap webservice methods for saving and retrieving the data? because i got this error from the webmethod but actually the POST contains the parameters.
Server Side
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static Dummy SaveDummy(Dummy myDummy)
{
Dummy dumdum = myDummy;
HttpContext.Current.Session["data"] = dumdum;
return myDummy;
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
public static Dummy FetchDummy()
{
return (Dummy)HttpContext.Current.Session["data"];
}
public class Dummy
{
private string _name;
private string _script;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Script
{
get
{
return _script;
}
set { _script = value; }
}
}
Backbone Model
window["model"] = Backbone.Model.extend({
initialize: function () {
console.log("CREATED");
},
defaults:{
name:"Please enter your name",
script:"Hello World"
},
urlRoot: "index.aspx/SaveDummy",
validate: function (attrs) {
}
});
Application
$("document").ready(function () {
var myModel = new model({
name: "Stack Overflow",
script: "alert('Hi SO')"
});
var myView = new view({
model: myModel,
el: $("#placeholder")
});
console.log("SAVING");
myModel.save();
console.log("FETCHING");
myModel.fetch();
POST
{"name":"Stack Overflow","script":"alert('Hi SO')"}
Message
Invalid web service call, missing value for parameter: 'myDummy'.
Note
I did look into other posts with similar problem, which were solved by doing something like
{myDummy={"name":"Stack Overflow","script":"alert('Hi SO')"}} . How could this be generated using Backbone?
All of the server-side synchronization in Backbone is handled through Backbone.Sync which is designed for two things:
REST apis that work with JSON (not SOAP/XML)
Extensibility
So you will need to override the Backbone.Sync behavior to talk to your backend. It appears to be relatively straight-forward. Some guidance can be found in these links:
SO post about overriding Backbone.Sync
Blog post about consuming XML services in Backbone

Populating jqGrid with JSON -- Performance using WCF vs ASMX for the backend

I am using an ASMX back-end to populate a jqGrid client-side, including client-side paging of the grid so all rows of data are loaded at once. My question is whether this is the best approach performance and reliability wise? Also, if WCF would be better than ASMX is it fairly easy to convert this existing set up to WCF (I'm guessing I should use REST-style WebGet methods, but I'm not positive). Just want everything to be as fast and responsive as possible, little to no postbacks ideally.
Here is the ASMX code:
public class JQGrid
{
public class Row
{
public int id { get; set; }
public List<string> cell { get; set; }
public Row()
{
cell = new List<string>();
}
}
public int page { get; set; }
public int total { get; set; }
public int records { get; set; }
public List<Row> rows { get; set; }
public JQGrid()
{
rows = new List<Row>();
}
}
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.None)]
[ScriptService]
public class JQGridService : System.Web.Services.WebService
{
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public JQGrid GetJQGrid(int pageIndex, int pageSize, string sortIndex, string sortDirection)
{
DataTable dt = GetDataTable( // command string );
if (dt == null)
throw new Exception("Unable to retrieve data.");
JQGrid jqGrid = new JQGrid();
foreach (DataRow sourceRow in dt.Rows)
{
JQGrid.Row targetRow = new JQGrid.Row();
targetRow.id = Convert.ToInt32(sourceRow["ID"]);
targetRow.cell.Add(sourceRow["ID"].ToString());
targetRow.cell.Add(sourceRow["SomeColumn"].ToString());
jqGrid.rows.Add(targetRow);
}
jqGrid.page = pageIndex;
jqGrid.records = jqGrid.rows.Count;
jqGrid.total = jqGrid.rows.Count; // Set this to total pages in your result...
return jqGrid;
}
}
Client-side JS:
function getData(pdata)
{
var params = new Object();
params.pageIndex = pdata.page;
params.pageSize = pdata.rows;
params.sortIndex = pdata.sidx;
params.sortDirection = pdata.sord;
$.ajax(
{
type: "POST",
contentType: "application/json; charset=utf-8",
url: "JQGridService.asmx/GetJQGrid",
data: JSON.stringify(params),
dataType: "json",
success: function (data, textStatus)
{
if (textStatus == "success") {
var thegrid = $("#jqGrid")[0];
thegrid.addJSONData(data.d);
}
},
error: function (data, textStatus) {
alert('An error has occured retrieving data!');
}
});
}
function pageLoad() { loadGrid() };
function loadGrid() {
$("#jqGrid").jqGrid({
gridComplete: function() {
$("#jqGrid").setGridParam({ datatype: 'local' });
},
datatype: function (pdata) {
getData(pdata);
},
colNames: ['ID', SomeColumn],
colModel: [
{ name: 'ID', index: 'ID', width: 150 },
{ name: SomeColumn, index: SomeColumn, width: 250}],
rowNum: 10,
rowList: [10, 20, 30],
viewrecords: false,
pagination: true,
pager: "#jqPager",
loadonce: true,
sortorder: "desc",
sortname: 'id',
cellEdit: false
});
}
I found this response from a Microsoft moderator (Gregory Leake) on their forums about whether to go with ASMX or WCF web services. The key quote (for me):
WCF is Microsoft's strategic
communication technology for .NET.
ASMX is supported; but is not the
future
Since the 3.5 SP1 release of the framework, I personally haven't used ASMX services and with the WCF WebHttp Services functionality released in the .NET 4 framework, I haven't looked back.
Changing over to use WCF REST services from ASMX would probably just involve:
Decorating your JQGrid class with DataContract and DataMember attributes;
Obviously, creating the WCF service interface (IJQGridService) and implemented class (JQGridService). Your JQGridService's implementation probably would change much at all except for the attributes on the class by replacing the current ones with a WebGetAttribute (on the interface) and a AspNetCompatibilityRequirementsModeAttribute (on the implementation class).
Some web.config changes since you'll have a <system.serviceModel> section now; but if you add a AJAX-enabled WCF service to your project, most of those settings will already be in place for you. The only thing you'd probably want to change is the endpointBehavior to use <webHttp/> instead of <enableWebScript>.
You shouldn't have to make any changes to your client-side JS, except changing the URL if your service name changes (which it probably will) and you should also change to using a GET verb from a POST since you're just retrieving data. jqGrid does a great job of handling the required parameters for paging on the query string.
Other than that, you're probably good to go.
I hope this helps. If there are other questions, let me know and I'll update this answer.
Good luck!

ASP.net MVC put complex data (array) to controller method

I'm porting an ASP.net Web Forms application to MVC.
The application uses AJAX, by means of Ajax-enabled WCF Web service and asp:ScriptManager. I send an array of objects for service, it handles it just great. Code example,
<script type="text/javascript">
$().ready(function () {
var ser = new Services.TasksService();
$('#tasks').tasksgrid(
'newTaskName',
'createTask',
'submitData',
loadData,
submitData,
deleteData
);
function loadData(callback) {
return ser.GetAllTasks(callback, null, null);
}
function submitData(data, callback) {
return ser.Submit(data, callback, null, null);
}
function deleteData(data, callback) {
return ser.Delete(data, callback, null, null);
}
}
);
</script>
WCF service side code:
[ServiceContract(Namespace = "Services")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TasksService
{
[OperationContract]
public IList<Task> GetAllTasks()
{
//Code..
}
[OperationContract]
public void Submit(IList<Task> tasks)
{
//Code..
}
[OperationContract]
public void Delete(IList<Task> tasks)
{
//Code..
}
}
The Submit/Delete method, recieves Array of Tasks objects. I create those array dynamically in client side script and just put it to corresponding Services.TasksService (no $.toJSON or JSON.stringly call, nothing like that). WCF infrastucture handles it greacefully and I always get a correct object on server.
Now, I'm getting rid of WCF service and try to do the same with Controller class. GetAllTasks were fine.. but I totally missed with 'recieving' data methods.
In controller I have,
[HttpPost]
public JsonResult Submit(IList<Task> tasks)
{
On client,
function submitData(data, callback) {
$.post('/Tasks/Submit', JSON.stringify(data), callback, 'json');
}
But anything I tried, I always recieve null as tasks object (so, data is not binded).
I've seen Phil Haack post on that, but would like to avoid using of any additional assemblies, if possible.
MVC needs to be told what variable on the server side to bind the data to. In your example you could do the following:
function submitData(data, callback) {
$.post('/Tasks/Submit', { tasks: data }, callback, 'json');
}
Look here http://theycallmemrjames.blogspot.com/2010/05/aspnet-mvc-and-jquery-part-4-advanced.html

Categories

Resources