Javascript to ASP.NET mvc controller fails using Katana - javascript

I have a controller. The code is below The javavascript that works with this controller is also below. This code was created in Visual Studio 2013 using MVC 5. The code was published to IIS and has worked as expected for several weeks. Because of changing requirements the code was ported to a project using Katana and is now self-hosed using a console application. The Controller and javascript are the same. The issue is that when I make a call to add a location the Get method is called, but the location variable is now null. Why does this code work hosted in Internet Information Server and not as a self hosted application using Katana?
Controller:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Mvc;
using PatientCommunication.Model;
using PatientCommunication.Repository;
using PatientCommunication.DataAccess;
using Walden.Utility;
namespace PatientCommunication.Web.Controllers
{
public class LocationController : ApiController
{
// GET api/location
private ILocations locations = new Locations();
public IEnumerable<Location> Get()
{
Database.ReminderConnection = ConfigurationManager.AppSettings["reminderConnection"];
List<Location> locationList = new List<Location>();
locationList = locations.GetLocationList();
return locationList;
}
public void Post([FromBody] Location locationList)
{
Database.ReminderConnection = ConfigurationManager.AppSettings["reminderConnection"];
locations.UpdateLocation(locationList);
}
public ActionResult Put(IEnumerable<Location> location)
{
Database.ReminderConnection = ConfigurationManager.AppSettings["reminderConnection"];
string toBeVoiced = string.Empty;
try
{
foreach (var loc in location)
{
Location singlelocation = new Location();
singlelocation.LocationID = loc.LocationID;
singlelocation.LocationName = loc.LocationName;
locations.AddLocation(singlelocation);
}
return new JsonResult { Data = new { Success = true } };
}
catch (Exception er)
{
string s1 = er.Message;
return new JsonResult { Data = new { Success = false } };
}
}
public void Delete([FromBody] Location locationList)
{
Database.ReminderConnection = ConfigurationManager.AppSettings["reminderConnection"];
locations.DeleteLocation(locationList);
}
}
}
Javascript:
$('#addLocation').click(function (e) {
if ($('#locationID').val().length < 1) {
ShowAlert("No Text", "Please Input Location ID")
e.preventDefault();
return;
}
if ($('#locationName').val().length < 1) {
ShowAlert("No Text", "Please Input Location Name")
e.preventDefault();
return;
}
locations.push({
ID: 0,
LocationID: $('#locationID').val(),
LocationName: $('#locationName').val()
});
$.ajax({
url: "api/location",
type: "PUT",
datatype: "json",
data: $.toJSON(locations),
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data.Data.Success) {
ShowAlert("Insert", "Record Inserted");
$("#gridLocations").data("kendoGrid").dataSource.read();
$('#locationID').val('');
$('#locationName').val('');
locations = [];
}
else {
alert("Error'");
}
}
});
e.preventDefault();
});

Figured out the issue. I am using Nancy to deliver static content and in the pipeline I had the call to use Nancy before the call to Web API. This is what was causing my problem

Related

Can't JSON parse message received from Azure Service Bus in Node.js app

This is my JS code to receive a message from Azure Service Bus
function receiveMessage(serviceBusTopic, serviceBusSubscriber, callback) {
serviceBus.receiveSubscriptionMessage(serviceBusTopic, serviceBusSubscriber,
{ isPeekLock: true }, function (error, lockedMessage) {
if (!error) {
try {
const receivedMessage = JSON.parse(lockedMessage.body);
console.log('receivedMessage', receivedMessage);
if (!_.isEqual(receivedMessage.Type, messageType.USERPROFILES_USER_UPDATED)) {
return;
}
//Message received and locked
callback(receivedMessage);
serviceBus.deleteMessage(lockedMessage, function (deleteError) {
if (!deleteError) {
// Message deleted
console.log('message has been deleted.');
}
});
}
catch (error) {
console.log('Start debugging');
console.log(lockedMessage.body);
}
When I receive a message it has strange encoding and JSON.parse throws an exception.
The lockedMessage output is:
{ body: '#\fbase64Binary\b3http://schemas.microsoft.com/2003/10/Serialization/�s\u0002{"Type":"SomeEvent"�\u0001}',
brokerProperties:
{ DeliveryCount: 9,
EnqueuedSequenceNumber: 0,
EnqueuedTimeUtc: 'Thu, 16 Nov 2017 23:50:16 GMT',
LockToken: '6e3e311f-0fe9-4366-844d-18046fd000db',
LockedUntilUtc: 'Fri, 17 Nov 2017 00:10:46 GMT',
MessageId: 'nil',
PartitionKey: '1d84084f-65af-4a33-bb30-62d97d85557d',
SequenceNumber: 61643019899633670,
SessionId: '1d84084f-65af-4a33-bb30-62d97d85557d',
State: 'Active',
TimeToLive: 1566804.069 },
location: '',
contentType: 'application/xml; charset=utf-8',
customProperties: { 'strict-transport-security': NaN, connection: NaN } }
The message is coming from a .NET Core service and that service sends with this code:
var payload = JsonConvert.SerializeObject(SomeEvent);
var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(payload));
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
topicClient.SendAsync(serviceBusMessage).Wait();
Why is Node.js not able to parse the message? Another .NET app can receive the same message without any issues.
To avoid this, you need to set ContentType to text/plain when sending a message from .NET Core service. So it should be something like this:
var payload = JsonConvert.SerializeObject(SomeEvent);
var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(payload))
{
ContentType = "text/plain"
};
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
topicClient.SendAsync(serviceBusMessage).Wait();
In this article, they explained the problem and the solution for .NET.
Update:
After some diving, this would not happen to me when I either use .NET Core or .NET to send a message with the standard library Microsoft.Azure.ServiceBus whether ContentType is specified or not.
This is my C# code to send a message:
class Program
{
static void Main(string[] args)
{
string connectionString = "Endpoint=sb://...";
var client = new TopicClient(connectionString, "MyTopic");
var payload = JsonConvert.SerializeObject(new DemoMessage() { Title = $"hello core!!! {DateTime.Now}" });
var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(payload));
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
client.SendAsync(serviceBusMessage).Wait();
}
private class DemoMessage
{
public DemoMessage()
{
}
public string Title { get; set; }
}
}
This is my Node.js code to receive a message:
var azure = require('azure');
var serviceBusService = azure.createServiceBusService("Endpoint=sb://...");
serviceBusService.receiveSubscriptionMessage('MyTopic', 'sub1', { isPeekLock: true }, function(error, lockedMessage) {
if(!error) {
console.log(lockedMessage);
serviceBusService.deleteMessage(lockedMessage, function (deleteError){
if(!deleteError){
// Message deleted
console.log('message has been deleted.');
}
})
}
});
The lockedMessage output is:
This only happens when I use .NET and the SDK WindowsAzure.ServiceBus with this code:
class Program
{
static void Main(string[] args)
{
string connectionString = "Endpoint=sb://...";
var client = TopicClient.CreateFromConnectionString(connectionString, "MyTopic");
var payload = JsonConvert.SerializeObject(new DemoMessage() { Title = $"hello core!!! {DateTime.Now}" });
var serviceBusMessage = new BrokeredMessage(Encoding.UTF8.GetBytes(payload));
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
client.Send(serviceBusMessage);
}
private class DemoMessage
{
public DemoMessage()
{
}
public string Title { get; set; }
}
}
Now, the lockedMessage output is:
So, I think the message you received is sent from another .NET client and I suggest you clear all messages from the topic before you test it in Node.js.
I ran into this issue as well. If you are using Stream Analytics then its compatibility level may be the cause of this issue. Stream Analytics compatibility level 1.0 uses an XML serializer producing the XML tag you are seeing. Compatibility level 1.1 "fixes" this issue.
See my previous answer here: https://stackoverflow.com/a/49307178/263139.

Access hard-coded data in MVC controller using Angularjs

I have some knowledge about Angularjs but I'm new to ASP.NET MVC.
So I was following this https://learn.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api tutorial. But I came up with a problem as it uses Jquery. I want to access the hard coded data in below controller using Angular.
using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
namespace ProductsApp.Controllers
{
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 }
};
public IEnumerable<Product> GetAllProducts()
{
return products;
}
public IHttpActionResult GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
}
I just want the method to access the data.
Can anyone help me with this. Thanks
Use $http in your service or controller of AngularJS to access data from your Web API. For example:
$http.get("http://localhost:8080/api/products/getallproducts")
.then(function(response) {
console.log(response.data);
});
If writing WebApi application then you need to change the IHttpActionResult Name to Get. and try this URL:
localhost:8080/api/products/{id}
*{id} is optional.
if you want to use the route you should change WebApiConfig.cs in App_Start folder.
Take a look at angularjs $http service which is used to establish communication with the http server in situation as yours.
To call GetAllProducts(), using the $http, use the route "api/products" like this
$http.get("api/products")
.then(function(response) {
console.log(response);
});
And to call GetProduct() use the route "api/products/1" if your product is 1 like this
$http.get("api/products/1")
.then(function(response) {
console.log(response);
});

Edit /Update with Web API Repository Pattern

I'm trying to work out the very basics of updating my database using a Web API Controller that is backed by a repository pattern. So far I have everything working POST, GET, DELETE (Create, Read, Delete). But I'm missing the Update.
Below is my angular code, I'm not going to post the Angular Views/Templates, but just know that they do bind and they work just fine. My problem is only on the Edit View, where I try to update using the vm.save function. My save function works fine on the Angular side, but I'm not sure what to do on the Web API & Repository side. You will see that my code to get this working is very basic bare bones. I have all of the code pages from my project in a gist here:
All Files in Gist
Just in case you want to see the big picture, otherwise I will just put here the few pages where I am having trouble getting the Edit/Update methods to work in using http.put with Angular Controller, Web API Controller & Repository.
WORKING Angular Edit Controller:
function editFavoriteController($http, $window, $routeParams) {
var vm = this;
var url = "/api/favorites/" + $routeParams.searchId;
$http.get(url)
.success(function (result) {
vm.search = result[0];
})
.error(function () {
alert('error/failed');
})
.then(function () {
//Nothing
});
vm.update = function (id) {
var updateUrl = "/api/favorites/" + id;
$http.put(updateUrl, vm.editFavorite)
.success(function (result) {
var editFavorite = result.data;
//TODO: merge with existing favorites
//alert("Thanks for your post");
})
.error(function () {
alert("Your broken, go fix yourself!");
})
.then(function () {
$window.location = "#/";
});
};
};
NOT WORKING Web API Controller
public HttpResponseMessage Put(int id,[FromBody]Search editFavorite)
{
if (_favRepo.EditFavorite(id, editFavorite) && _favRepo.Save())
{
return Request.CreateResponse(HttpStatusCode.Created, editFavorite);
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
NOT WORKING Repository
public bool EditFavorite(int id, Search editFavorite)
{
try
{
var search = _ctx.Search.FirstOrDefault(s => s.SearchId == id);
search(editFavorite).State = EntityState.Modified;
return true;
}
catch
{
var item = "";
}
}
WORKING Interface
bool EditFavorite(int id, Search newSearch);
Again, my only problems are figuring out what to do for the update in the WebAPI FavoritesController and FavoritesRepository. I have example of how I have done everything else in the Gist, so I'm hoping someone might be able to help me out. I'm just hitting a wall of what I know how to do in Web API.
Fixed Code:
public HttpResponseMessage Put(int id,[FromBody]Search editFavorite)
{
if (_favRepo.EditFavorite(id, editFavorite))
{
_favRepo.Save()
return Request.CreateResponse(HttpStatusCode.Created, editFavorite);
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
I am also posting code which should work fine for handling edit on server side using WEB API and Repository Pattern.
WebAPI Controller:
public HttpResponseMessage Put(int id,[FromBody]Search editFavorite)
{
if (!ModelState.IsValid || id != editFavorite.Id)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
db.EditFavorite(editFavorite);
try
{
db.Save();
}
catch (DbUpdateConcurrencyException)
{
if (!db.SearchExists(id))
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
else
{
throw;
}
}
return Request.CreateResponse(HttpStatusCode.Created, editFavorite);
}
Repository Method:
public void EditFavorite(Search editFavorite)
{
db.Entry(editFavorite).State = EntityState.Modified;
}
public void Save()
{
db.SaveChanges();
}
public bool SearchExists(int id)
{
return db.Search.Count(e => e.Id == id) > 0;
}
Modify Interface:
void Save();
void EditFavorite(Search newSearch);
bool SearchExists(int id);
Edit:
I have made some changes so that only operations that are carried out on your db context is done in repository layer (Data Layer) and the error checking is done in the WEB API Controller.
Suggestion:
You should inherit IDisposable on the interface and implement it your repository class so that your entities are properly disposed...
public interface IFavoritesRepository : IDisposable
{
// code here
}
public class FavoritesRepository : IFavoritesRepository
{
// code here
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
db.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}

Where exactly to put the antiforgeryToken

I have a layout page that has a form with AntiForgeryToken
using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl }, FormMethod.Post, new { Id = "xcrf-form" }))
This generates a hidden field
<input name="__RequestVerificationToken" type="hidden" value="p43bTJU6xjctQ-ETI7T0e_0lJX4UsbTz_IUjQjWddsu29Nx_UE5rcdOONiDhFcdjan88ngBe5_ZQbHTBieB2vVXgNJGNmfQpOm5ATPbifYE1">
In my angular view (that is loaded in a div in the layout page, I do this
<form class="form" role="form" ng-submit="postReview()">
And my code for postReview() is as follows
$scope.postReview = function () {
var token = $('[name=__RequestVerificationToken]').val();
var config = {
headers: {
"Content-Type": "multipart/form-data",
// the following when uncommented does not work either
//'RequestVerificationToken' : token
//"X-XSRF-TOKEN" : token
}
}
// tried the following, since my other MVC controllers (non-angular) send the token as part of form data, this did not work though
$scope.reviewModel.__RequestVerificationToken = token;
// the following was mentioned in some link I found, this does not work either
$http.defaults.headers.common['__RequestVerificationToken'] = token;
$http.post('/Review/Create', $scope.reviewModel, config)
.then(function (result) {
// Success
alert(result.data);
}, function (error) {
// Failure
alert("Failed");
});
}
My MVC Create method is as follows
[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
public ActionResult Create([Bind(Include = "Id,CommentText,Vote")] ReviewModel reviewModel)
{
if (User.Identity.IsAuthenticated == false)
{
// I am doing this instead of [Authorize] because I dont want 302, which browser handles and I cant do client re-direction
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
}
// just for experimenting I have not yet added it to db, and simply returning
return new JsonResult {Data = reviewModel, JsonRequestBehavior = JsonRequestBehavior.AllowGet};
}
So no matter where I put the token, no matter what I use for 'Content-Type' (I tried application-json and www-form-urlencoded) I always get the error "The required anti-forgery form field "__RequestVerificationToken" is not present."
I even tried naming __RequestVerificationToken and RequestVerificationToken
Why does my server not find the damn token?
I also looked at couple of links that ask you to implement your own AntiForgeryToeknVerifyAttrbute and verify the token that is sent as cookieToken:formToken, I have not tried that but why I am not able to get it working whereas this works for the MVC controllers (non-angular posts)
Yes. By default, MVC Framework will check for Request.Form["__RequestVerificationToken"].
Checking the MVC source code
public AntiForgeryToken GetFormToken(HttpContextBase httpContext)
{
string value = httpContext.Request.Form[_config.FormFieldName];
if (String.IsNullOrEmpty(value))
{
// did not exist
return null;
}
return _serializer.Deserialize(value);
}
You need to create your own filter to check it from Request.Header
Code Snippet from Phil Haack's Article - MVC 3
private class JsonAntiForgeryHttpContextWrapper : HttpContextWrapper {
readonly HttpRequestBase _request;
public JsonAntiForgeryHttpContextWrapper(HttpContext httpContext)
: base(httpContext) {
_request = new JsonAntiForgeryHttpRequestWrapper(httpContext.Request);
}
public override HttpRequestBase Request {
get {
return _request;
}
}
}
private class JsonAntiForgeryHttpRequestWrapper : HttpRequestWrapper {
readonly NameValueCollection _form;
public JsonAntiForgeryHttpRequestWrapper(HttpRequest request)
: base(request) {
_form = new NameValueCollection(request.Form);
if (request.Headers["__RequestVerificationToken"] != null) {
_form["__RequestVerificationToken"]
= request.Headers["__RequestVerificationToken"];
}
}
public override NameValueCollection Form {
get {
return _form;
}
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,
AllowMultiple = false, Inherited = true)]
public class ValidateJsonAntiForgeryTokenAttribute :
FilterAttribute, IAuthorizationFilter {
public void OnAuthorization(AuthorizationContext filterContext) {
if (filterContext == null) {
throw new ArgumentNullException("filterContext");
}
var httpContext = new JsonAntiForgeryHttpContextWrapper(HttpContext.Current);
AntiForgery.Validate(httpContext, Salt ?? string.Empty);
}
public string Salt {
get;
set;
}
// The private context classes go here
}
Check out here for MVC 4 implementation, to avoid salt issue
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,
AllowMultiple = false, Inherited = true)]
public sealed class ValidateJsonAntiForgeryTokenAttribute
: FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
var httpContext = filterContext.HttpContext;
var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
AntiForgery.Validate(cookie != null ? cookie.Value : null,
httpContext.Request.Headers["__RequestVerificationToken"]);
}
}
I had the same problem. Turned out that I don't need to set antiforgery token anywhere explicitly in my angular js code. The MVC controller expects this token value to be delivered from 1. the form field, 2. cookie. The filter equates and is happy when they match.
When we submit the form, hidden field for the anti forgery token automatically supplies its value. Cookie is automatically set by the browser. So as I said, we don't need to do anything explicitly.
The problem really is request's content-type. By default it goes as as application/json and therefore the a.f. token value (or rather any form data) is not received.
Following worked for me:
// create the controller
var RegisterController = function ($scope, $http) {
$scope.onSubmit = function (e) {
// suppress default form submission
e.preventDefault();
var form = $("#registerform");
if (form.valid()) {
var url = form.attr('action');
var data = form.serialize();
var config = {
headers: {
'Content-type':'application/x-www-form-urlencoded',
}
};
$http.post(url, data, config).success(function (data) {
alert(data);
}).error(function(reason) {
alert(reason);
});
}
};
};
As Murali suggested I guess I need to put the toekn in the form itself, so I tried putting the token as part of form data and I needed to encode the form data as explained in https://stackoverflow.com/a/14868725/2475810
This approach does not require any additional code on server side, also we do not need to create and join cookie and form token. Just by form-encoding the data and including token as one of the fields as explained in the answer above we can get it rolling.
You should perform the HTTP request in this way:
$http({
url: '/Review/Create',
data: "__RequestVerificationToken=" + token + "&param1=1&param2=2",
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).success(function(result) {
alert(result.data);
}).error(function(error) {
alert("Failed");
});

How to call a C# function from 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.

Categories

Resources