The equivalent of C# consuming a WCF method in JavaScript (jQuery) - c#

I have a running WCF service that exposes a method GetStuff(String type). It's called by the automatically created client class, so the syntax is embarrassingly simple.
ServiceClient client = new ServiceClient();
String response = client.GetStuff("other's");
client.Close();
The straight-forward question is this. How do I convert that to a call in JavaScript (possiblyusing jQuery) in an easy way?
After some serious googling, I concluded that I'm only going to find examples of how to consume a JSON-formatted stream using jQuery. I prefer not to touch the service-side of the software, if at all possible.
I tried the code below (along with a bunch of derivatives that I could think of) but the error I got was "No Transport" and googling that didn't yield anything that I got me going.
$.ajax({
type: "GET",
url: "http://hazaa.azurewebsites.net/Service.svc",
success: function (response) { console.info(response); },
error: function (response) { console.error("Error! " + response.statusText); }
});
Will I have to write a totally different service that exposes the data in JSON format? How do I specify that the service is supposed to call this or that method? Am I out of luck and these convenience methods are for .NET clients only?
Please note that I've got another way of getting the data where I want, not using JavaScript at all but I'd prefer to see if this is (easily) doable too.

I would convert server method to use web invocation = WebInvoke attribute. Here you can specify uri for the method call.
Link to the info

Look into Jquery SOAP .. http://plugins.jquery.com/soap/ etc.
haven't tried it myself but it's the kind of thing you might be needing here.

Related

Call C# function from Javascript in aspx webform and then reload page

Trying to figure out how to call a c# function in a webform. I tried both ajax and windows.location but could just be off on my path. Trying to send it my c# code at SpeakerList.aspx/update and then gonna attach two variables i have in javascript which shouldnt be too bad. But want it to hit the C# function then reload the page so hoping there is just an easy call im missing.
buttons: {
"Save": function () {
var combo = ASPxClientControl.GetControlCollection().GetByName('DropDownList1');
var value = combo.GetSelectedItem().value;
var billID = $("#billID").val();
window.location = "SpeakerList.aspx/updateRec";
}
You might want to try using WebMethods:
http://aspalliance.com/1922_PageMethods_In_ASPNET_AJAX.all
This allows you to call a function in your page's code behind using JavaScript.
Assuming you are using MVC, you probably want to return a JSON result. An easy way to consume Json within your client webpage is using JQuery. You can return JSON as as the output of a webpage, but I don't recommend it. Create a separate service point that repesents the JSON method.
It is hard to tell what you are actually trying to accomplish, but the normal usage pattern for a JSON method is the supply the parameters as part of the querystring (which you can refactor with routing if you want). The result is then just a JSON packet.
Personally, I like JSON.Net for server side JSON, but you don't actually need this. Look up JSONMethod for examples, etc. that will show you how to do this.
From the browser client, JQuery has a json method, but I personally recommend using the more generic ajax method a JQuery so you can use the handlers for success, error and completion. E.g.
$.ajax({
url: "http:...",
data: queryparm,
cache:false,
timeout:15000,
success: function(data){
jresult = $.parseJSON(data);
...
},
error:function (xhr, ajaxOptions, thrownError)
{
setErrorMsg("Error getting search results: " + thrownError);
}
});
EDIT -- Actually, I've done this exact same thing with webforms too, code is essentially identically (if you use JSON.Net on the server side). You don't have the routing options to make the urls REST compliant, but as an internal json web service, you probably won't really care about that.
As a webpage (.aspx) page, you can use a "postback" this is the simplest method for a web form. You can always declare some hidden fields to use for data passing if you are not passing back a native "control" value. If you don't know how to do this, you need to read a tutorial on using web forms.

How can I target a specific method in an external .cs file with a jQuery AJAX call in a WebMatrix C#.net environment?

If I have this JavaScript function:
function fillMainStreetEvent(location) { // /AJAX Pages/Compute_Main_Street_Event.cshtml
$.ajax({
url: "/App_Code/ContentGenerator.cs/ContentGenerator.GenerateMainStreetEvents",
async: false,
type: "GET",
dataType: "html",
data: { page: location },
success: function (response) {
$("#MainStreetEvents").html(response);
},
error: function (jqXHR, textStatus, error) {
alert("Oops! We're sorry, there has been an AJAX error. The server responded with (" + textStatus + ": " + error + ").");
}
});
}
And I want to target the method: GenerateMainStreetEvents of the class: ContentGenerator in an external file named: ContentGenerator.cs, how do I do this?
This was my latest attempt to target a single method within my .cs file, however, I am not surprised that I couldn't get it working since guessing is a horrible way to begin writing syntactically correct code.
In the first line's comment you can see the string I would normally use to point to an external cshtml file, which, functionally would serve me fine, especially since I can just call my external .cs file's method from there. However, I am trying to reduce hops across files and began researching for ways to do this, but came up empty handed.
In addition to:
/App_Code/ContentGenerator.cs/ContentGenerator.GenerateMainStreetEvents
I have tried this:
/App_Code/ContentGenerator.cs/ContentGenerator/GenerateMainStreetEvents
This:
/App_Code/ContentGenerator.cs.ContentGenerator.GenerateMainStreetEvents
And this:
/App_Code/ContentGenerator.cs/GenerateMainStreetEvents
None of which have worked for me, considering my environment. The only online examples that I can find on how to do this involve PHP, classic ASP, or some other language I am not using with ASP.NET.
The answer here is probably something very simple, but since I have never targeted an external .cs file with AJAX before, I am all out of guesses and research is turning up no new ideas.
So to start - your App_Code directory in any ASP.NET application should NEVER serve content. This is to protect yourself from accidentally exposing your source code on your web site :) To get this rolling, you need to follow a few steps:
Create a new cshtml page named 'GenerateMainStreetEvents.cshtml'.
Inside of that page, add a razor block that invokes your GenerateMainStreetEvents function
After you have a list of objects in razor, you need to convert them into JSON. I suggest using JSON.NET, which is available on NuGet: http://james.newtonking.com/projects/json-net.aspx
Using Response.Write and Response.End to write out the JSON and end your HTTP response
Here is a really good example:
Retrieve JSON Array from jQuery Ajax call in asp.net webpages
Happy coding!

JSONP no get value result

I'm doing a project for college where one WebSite sends commands to a Windows Forms application. This application is responsible for access to serial port and send and receive commands.
Communication between the Website and the Windows Forms application, I used Web Api, however after publishing, auditioning remembered that the localhost in a C # WebSite. Net's own site and not my Windows Forms application.
I changed the call to the Web Api directly use Ajax and not a controller.
In the examples I found I saw that I use JSONP, but I can not read the results and use it on my website.
The calling code and return seen by Chrome are below
function cmdLocal() {
$.ajax({
type: "GET",
dataType: "jsonp",
url: "http://local host:8089/api/gps/",
jsonpCallback: "cmdTorre",
jsonp: "cmdTorre"
});
}
function cmdTorre(data) {
alert(data);
}
Response Header
Content-Length:10
Content-Type:application/json; charset=utf-8
Date:Tue, 10 Jun 2014 11:18:30 GMT
Server:Microsoft-HTTPAPI/2.0
Response
No Properties
Windows Forms APIController
namespace TCCWindows.Lib
{
public class GPSController : ApiController
{
[HttpGet]
public string Posicao()
{
var coordenada = TCCWindows.FormPrincipal.PegarCoordenadas();
return coordenada.Latitude + "|" + coordenada.Longitude + "|" + coordenada.Altitude;
}
}
}
First, you ajax call looks overly complicated try replacing it with :
function cmdLocal() {
$.ajax({
type: "GET",
dataType: "jsonp",
url: "http://local host:8089/api/gps/",
success: cmdTorre,
error: function(err){
alert("You have a error"+err);
}
});
}
function cmdTorre(data) {
alert(data);
}
Please validate the new code carefully. I just typed it in here so can have errors. If this runs at this point you should probably see the error message. That is because your GPSController doesnt seem to be returning a valid JSONP (or JSON for that matter). Please read up on JSONP for more clarification but, I think if you modify your return statement to make it look like following, it should work. Assuming your controller is actually getting called and your network stuff is working:
return "cmdTorre({\"lat\":"+coordenada.Latitude+" , \"lon\":"+coordenada.Longitude+" });"
Basically your return string should look like following when printed on console:
function cmdTorre({
"lat": 23.34,
"lon":34.23,
"alt":50
});
Again I suggest you check the code I wrote for syntax issues as i just typed it up in here, but it should give you the idea.
So problems were:
The return string you are generating is NOT in JSON format
It is also not wrapped in a function call making it a invalid JSONP too.
Lastly my solution should get your code working and JSONP started but its not the right way to do things. Its more of a ugly hack. Your GPS controller should read the HTTP request for parameter called 'callback' which is a accepted convention for JSONP calls. Then instead of hardcoding the function name in the return statement, you should use the value of this callback parameter. Then you dont need to use a specific function like 'cmdTorre' in your jQuery. Instead a anonymus function like success:function(response){...} will work just fine.
Hope that helps.

How to pass complex model from client to server?

I have some data "Foo" that I want to pass from the browser to the server and retrieve predicted statistics based on the information contained within foo.
$.ajax({
type: 'GET',
url: "/api/predictedStats/",
data: "foo=" + ko.toJSON(foo, fooProperties),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(data) {
return _this.viewModel.setPredictedStats(data);
},
error: function(jqXHR, statusText, errorText) {
return _this.viewModel.setErrorValues(jqXHR, errorText);
}
});
I created a predicted stats controller and get method taking an argument of Foo.
public class PredictedStatsController : ApiController
{
public PredictedStats Get(Foo foo)
{
return statsService.GetPredictedStats(foo);
}
}
Sticking a breakpoint on the Get method I see the Foo object is always null. There are no errors thrown from the webapi trace logging just the following lines.
WEBAPI: opr[FormatterParameterBinding] opn[ExecuteBindingAsync] msg[Binding parameter 'foo'] status[0]
WEBAPI: opr[JsonMediaTypeFormatter] opn[ReadFromStreamAsync] msg[Type='foo', content-type='application/json; charset=utf-8'] status[0]
WEBAPI: opr[JsonMediaTypeFormatter] opn[ReadFromStreamAsync] msg[Value read='null'] status[0]
I've no problem sending the data via a post to the Foo controller to create the Foo object on the server so I can say there's nothing wrong with the json created clientside.
Looking in fiddler the resulting Get looks like the following where jsondata is the object foo.
GET /api/predictedStats?foo={jsondata} HTTP/1.1
Is this even possible or am I going about this all wrong?
Thanks
Neil
EDIT:
I feel like I almost got this working with the following
public PredictedStats Get([FromUri]Foo foo)
{
return statsService.GetPredictedStats(foo);
}
The object foo was coming back fine but no properties of Foo were being populated properly.
In the mean time I've resorted to using a POST with near identical data just dropping the "foo=" and this is working just fine.
I'm not sure whether the POST or the GET should be used in this case but that would be interesting to know.
I also found this http://bugs.jquery.com/ticket/8961 which seems to suggest you can't attach a body to a GET request with jquery so POST is probably the only sensible option
You almost got there :)
When you use [FromUri] (which you have to use for 'complex' objects because by default Web API doesn't 'bind' complex objects, it's always looking to deserialize them from the body) you don't need to pass param= in the Uri - you just pass the members of the value as query string parameters. That is 'member1=value&member2=value' - where member1 and member2 are members of the Foo.
Note there is no 'bug' in jQuery - while the HTTP spec doesn't prohibit a request body, it's likely that the browser does (and if that's the case, the jQuery can't send it), and it's more than likely that a server will never read it anyway. It's just not accepted practise. It also has interesting issues with caching potentially, as well, in that a browser won't cache a POST, PUT, DELETE etc, but will cache a GET if the response headers don't prohibit it - that could have serious side effects for a client application. I recommend you look at this SO: HTTP GET with request body for more information and some useful links on this subject.
Equally, when using jQuery - you don't need to convert the object to JSON either - just pass the javascript object in the data member of the options and jQuery turns it into the correct format.
Or should that be, Web API understands the format the jQuery passes it as.

web request from the user browser

is it possible to send a web request from the user browser to another api and then process the result sent back??
im trying the following ajax code but its not working, i was wondering whether is it possible or not and if its a yes how can i implement it ...
$(document).ready(function() {
$.ajax({
type: "GET",
url: "http://api.ipinfodb.com/v2/ip_query.php?key=a9a2b0ec2c4724dd95286761777b09f1c8e82894de277a5b9d7175fa5275f2da&ip=&output=xml",
dataType: "xml",
success: function(xml) {
alert("sucess");
$(xml).find('Ip').each(function() {
var ip = $(this).find('Ip').text();
alert(ip);
});
}
});
});
Due to same origin policy restriction you are pretty limited to sending AJAX requests to your own domain only. JSONP is a common workaround but the remote site needs to support it. Another workaround consists in crating a server side script on your domain which will serve as a bridge between your domain and the remote domain and it will simply delegate the AJAX request sent to it from javascript.
Should be possible, I have done the same.
BUT you have to have the pages on the same server, you cannot send a request to another server, in that case you would have to use a proxy on your server to relay the call.
Just to add to what was already said: if you can't create your own JSONP proxy, you can use YQL service which creates that proxy for you. Note that YQL will wrap your data with it's own meta data (unless there is a way yo disable that...).
By the way, you should use JSON output instead of XML output from your API service. JSON is a more lightweight format and as such is more adapted for Web.
Below is a fully functional example with your API URL (outputting JSON this time) and YQL:
var apiRequestUrl = "http://api.ipinfodb.com/v2/ip_query.php?key=a9a2b0ec2c4724dd95286761777b09f1c8e82894de277a5b9d7175fa5275f2da&ip=&output=json";
var yqlRequestUrl = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20where%20url%20%3D%20%22";
yqlRequestUrl += encodeURIComponent(apiRequestUrl);
yqlRequestUrl += "%22&format=json&callback=?";
$.getJSON(yqlRequestUrl,
function(jsonData) {
alert(jsonData.query.results.json.Ip);
});
Finally, this article can come handy: http://www.wait-till-i.com/2010/01/10/loading-external-content-with-ajax-using-jquery-and-yql/

Categories