I'm developing a win8 app, that should consume a WCF service hosted on IIS, but it wont...
NOTE: The Web service works just fine. I've tested it with the WCF Test Client in VS2012
Here's my code:
IService.cs:
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
[ServiceContract]
public interface IService
{
[OperationContract]
string SitePredmeti();
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Xml)]
List<Profesor> SiteProfesori();
}
i made two methods: one returns xml one returns json just so i can test which one works. it doesn't matter whether the WS returns json or xml, i can work with either in the app.
i use the default SPLIT APP TEMPLATE for a html5/JS app in win8 WITHOUT ANY CHANGES. for now i just need to consume the wcf service, i'll deal with the data templates later.
the url to my iis hosted wcf:
http://localhost/InformatorWS/Service.svc
here's what i've tried so far:
var baseURl = "http://localhost/InformatorWS/Service.svc/SitePredmeti/";
var url = baseURl+Number1.value+"/"+Number2.value;
WinJS.xhr({ url: url }).then(function (r) {
var result = JSON.parse(r.responseText);
ResultSpan.innerHTML = result; });
the error i get here is:
{"exception":null,"error":{},"promise":{"_oncancel":null,"_nextState":null,"_state":>{"name":"error","done":null,"then":null},"_listeners":null,"_value":{},"_isException":false,"_errorId":2},"id":2}
next i tried calling it via jquery ajax:
$(document).ready(function () {
jQuery.support.cors = true;
//Calling WCF Service using jQuery ajax method
$.ajax({
type: "GET",
async: "false",
url: "http://localhost/InformatorWS/Service.svc/SitePredmeti",
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: true,
success: function (result) {
//AjaxSucceeded(result);
alert('ok')
},
error: alert('ne ok')
});
});
and when i link jquery
<script type="text/javascript" src="js/jquery-ui-1.8.9.custom.min.js"></script>
<script type="text/javascript" src="js/jquery-1.4.3.js"></script>
i get three exceptions:
Unhandled exception at line 10, column 2 in
ms-appx://66b782f9-8814-4b8e-a2e3-d6e73893690a/js/jquery-ui-1.8.9.custom.min.js
0x800a1391 - JavaScript runtime error: 'jQuery' is undefined
(and two of these - for the two alert in success and error)
Unhandled exception at line 8, column 9 in
ms-appx://66b782f9-8814-4b8e-a2e3-d6e73893690a/js/default.js
0x800a1391 - JavaScript runtime error: 'alert' is undefined
anyone have any idea what i am doing wrong? or just anyone know any way of consuming a WCF service hosted on IIS?
Thank you very much in advance.
There may be a couple of issues at play here. You need different endpoints to be consumed by the WCFTestClient and JavaScript. For the first, you need a SOAP endpoint, but for the second you need a non-SOAP (a.k.a. REST) endpoint. Since you didn't mention in your question, I'm assuming you only have one endpoint, and since the WCFTestClient works, it's a SOAP endpoint, which doesn't work for JavaScript 1. If this is the case, add a new Web endpoint to your service (or replace the one you have with that)2. You can read more about web endpoints in the WCF Web HTTP Programming Model doc at MSDN.
1 In theory, it's possible to call SOAP endpoints with JavaScript (especially if the endpoint is using some simple binding like BasicHttpBinding). But you'll need to create the XML payload to send to it, and format it according to the SOAP specification - not the JSON payload which you're sending and expecting as a result.
2 And if you do that - have only one, non-SOAP, endpoint, WCF Test Client will not work with it anymore, but that's expected, since it tries to consume the service WSDL to talk to it.
Related
So here's my situation...
We have an on-prem installation of Microsoft Dynamics CRM and I am trying to make an ajax call from it to a service I created on another one of our servers. There have been many issues already that I've solved - but I'm able at this point to successfully make a GET request to my service from CRM via javascript I've put on a form in CRM.
Just for reference (because I'm not entirely sure at this point if these things are related or not)...
I had to set anonymous authentication in IIS for my service (CRM has
its own authentication that I will be relying on)
I had to set a response header of Access-Control-Allow-Origin with the host address of our CRM installation
So, after doing those things I was able to successfully call my web service via GET. I could return back a string I had from a [HttpGet] web method.
But, now I need to actually call a web method via POST to post some data to my web service. So, below you can see my implementation for the service as well as the javascript I'm using the make the POST call.
using CRMService.Models;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Net.Mail;
using System.Web;
using System.Web.Http;
namespace CRMService.Controllers
{
public class DefaultController : ApiController
{
// GET: Default
public string Get()
{
return "Hi";
}
[HttpPost]
public string GiveParameters(TestClass tc)
{
try
{
Dictionary<string, object> Parameters = new Dictionary<string, object>();
Parameters.Add("id", tc.id);
Parameters.Add("one", tc.one);
Parameters.Add("two", tc.two);
NonQuery("InsertTestItem", ConfigurationManager.ConnectionStrings["TestConnection"].ToString(), Parameters);
return "success";
}
catch (Exception ex)
{
return "ex";
}
}
}
}
var new_budget = Xrm.Page.data.entity.attributes.get("new_budget").getValue();
var new_name = Xrm.Page.data.entity.attributes.get("new_name").getValue();
var id = Xrm.Page.data.entity.getId();
data = '{"TestClass":{"one":"' + new_name + '", "two":"'+ new_budget +'", "id":"'+ id +'"}}'
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "https://<hiddingMyUrl>/api/Default/GiveParameters",
data: data,
dataType: "json",
success: function(data) {
console.log("Success");
},
error: function(result) {
console.log("Error");
}
});
When I make this POST call, at first I could see it was doing some "preflight" stuff and making an OPTIONS request - then returning a 403 (I think, if memory serves me right). I looked that up and solved that issue by adding a Access-Control-Allow-Headers header to my web service in IIS with the value of Origin, X-Requested-With, Content-Type, Accept
After doing that my POST actually gives a 200 status code - but, as you can see in my code, I should then be seeing data in a database if everything went well.
..So of course then the question is... is my web service code working properly? And normally I could test for that easily - however I am fairly new to web api. I don't really get the best way to testing at this point - and I don't know if it's something with my code specifically or if there is some configuration issue with web api itself.
Here is my routeconfig:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional }
);
}
You should try working with a REST client.
Here are two nice ones :
Advanced Rest Client
Postman
I personally prefer Postman but really both are good.
At the moment I am working on an APP. I am trying to find out why the methods from my webservices are not working but because I'm working with javascript in the app developer I am not able to debug my C# (Cordova and visual studio). Is there a way for me to write popups in the C# code so I can still see the values of my objects and properies?
So:
I want to be able to force a popup from C# while running the javascript APP because I can not debug my C# code since it's only a webservice.
Update:
This would be the normal way, C# is server-side and JavaScript is client-side. Inside of the web-method your C# should generate something like:
JavaScript serializer = new JavaScriptSerializer();
var response = serializer.Serialize(jsonObject);
Response.Write(response);
Response.End();
That would basically allow you to receive an object or collection back into the Ajax success or error for instance.
Since your utilizing a JavaScript Application, I'm under the notion that you're calling the service via Ajax. Your Ajax request will contain a success and error. These will allow you to return data from your Ajax.
// Sample:
$.ajax({
url: '...',
type: '...',
data: { Model : jsonObject },
success: function (response) {
// Response would be your C# Success.
},
error: function (response) {
// Response would be your C# Error.
}
});
The web-service should be serializing the response back for your web-service.
Our assistance will be minimal without seeing how you call the web-service, how the web-service responds, hopefully this helps you though.
I have a simple web service that I am trying to utilize. Obviously, this will be more enahnced down the road but am trying to grasp the basic concept of the ajax call.
Web Service
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
namespace Tools
{
/// <summary>
/// Summary description for CFServices1
/// </summary>
[WebService(Namespace = "http://localhost:51342/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class CFServices1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hellow World";
}
}
}
JavaScript
$.ajax({
type: "POST",
url: "CFServices.asmx?/HelloWorld",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
console.log(data);
},
error: function (response) {
console.log(response);
}
});
The ajax call appears to work fine as it returns an error:
"<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><soap:Code><soap:Value>soap:Receiver</soap:Value></soap:Code><soap:Reason><soap:Text xml:lang="en">System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlTextReader.Read()
at System.Web.Services.Protocols.SoapServerProtocol.SoapEnvelopeReader.Read()
at System.Xml.XmlReader.MoveToContent()
at System.Web.Services.Protocols.SoapServerProtocol.SoapEnvelopeReader.MoveToContent()
at System.Web.Services.Protocols.SoapServerProtocolHelper.GetRequestElement()
at System.Web.Services.Protocols.Soap12ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
--- End of inner exception stack trace ---</soap:Text></soap:Reason><soap:Detail /></soap:Fault></soap:Body></soap:Envelope>"
I have tried a couple different things that lead me down the path of the URL property being invalid but since I'm getting an actual response, I'm assuming it's correct. It definitely renders if I navigate to it through a browser. Even if I try and invoke the web service through the asmx page, it all works.
I have tried changing the data type to be plain text but that doesn't work either. Since all the web method does is reutnr the string 'Hellow World', I shouldn't need to pass any arguments but tried passing blank values just in case. Everything either brings me back to the response returning 'undefined', the html markup for the asmx page or this. The 'data at the root element is invalid.' This tells me that either the data being sent to, or recieved from the web service is incorrect or doesn't have the right formatting. This is where I'm getting hung up at because I can't figure out what could possibly be wrong here.
Although this is something probably simple, I'm not finding any luck whatsoever on SOF or other threads. Any helpful insight is greatly appreciated.
As we are calling it from jquery ie., from script part you need to make the below changes to Webservice part,
[System.Web.Script.Services.ScriptService] // Mark it for accessing from script
public class CFServices1 : System.Web.Services.WebService
We need to set script method attribute for the web method as below
[WebMethod]
[ScriptMethod]
public string HelloWorld()
Then while calling it from ajax call just remove ? in url part as below,
$.ajax({
type: "POST",
url: "CFServices.asmx/HelloWorld",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
console.log(data);
},
error: function (response) {
console.log(response);
}});
Hope it helps.
I had everything thilsiva suggested but was still receiving this error. It worked on my local development machine but not when deployed. The problem was I was getting my URL from the config file and I was accidentally missing the method name in my deployed version. So make sure you have the method name included if you're in the same situation.
url: "CFServices.asmx/HelloWorld",
not
url: "CFServices.asmx",
I have a working prototype Symfony2 RESTful webservice which I am still working on and I am trying to figure out how a client can send JSON or consume JSON data from the webservice. All I need is an example(s) on how to send a request or post data to it and I can figure out the rest. From my browser, if I visit http://localhost/app_dev.php/users.json, I get the correct result from my database as JSON, e.g.
[{"id":1,"username":"paulo","username_canonical":"paulo","email":"a#ymail.com","email_canonical":"a#ymail.com","enabled":true,"salt":"66r01","password":"UCxSG2v5uddROA0Tbs3pHp7AZ3VMV","last_login":"2013-12-03T13:55:15-0500","locked":false,"expired":false,"roles":[],"credentials_expired":false,"first_name":"Monique","last_name":"Apple"}, ... etc.
All other routes are working correctly and I can get the same result by using httpie or cURL. Now, the problem I am trying to solve is to get the same JSON data using AJAX (and mobile iOS, Android, etc later). Here is my attempt at using AJAX JS:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$.ajax({
dataType: "json",
type: "GET",
url: "http://192.168.1.40/symfony/web/app_dev.php/users.json",
success: function (responseText)
{
alert("Request was successful, data received: " + responseText);
},
error: function (error) {
alert(JSON.stringify(error));
}
});
</script>
The AJAX alerts the following results which indicates an error:
{"readyState":0,"responseText":"","status":0,"statusText":"error"}
What am I doing wrongly and how can I solve the problem. Kindly give an example.
This is a cross-domain request issue. You need to make the request to the same domain you are on. This is a browser-level security feature.
For example, you can only request URLs on http://192.168.1.40 if you are currently ON http://192.168.1.40. This means that a request from http://192.168.1.39 (for example) won't work
Can i Call web service from java script?
Thanks
Yes, you can do this.
Definitely. We would need a bit more information to know what kind of service you are using and if you are using a JS library. This is very easy with Dojo or EXT.
I'll show you a Dojo example as that is what I'm working with the most lately. I mostly create my services as REST services at this point. Depending on the service and how it's going to be used, I either send the response back as JSON or JSONP.
Below is an example for services that send the response as JSONP, which I use for cross-domain calls. You would need to use dojo.io.script.get (if using the Dojo library):
dojo.io.script.get({
callbackParamName: 'method',
url: 'http://mydomain/myservicename/mymethodname/param1/param2',
timeout: 20000,
load: dojo.hitch(this,function(response,ioArgs) {
this.doSomething(response);
}),
error: dojo.hitch(this,function(error) {
alert('uh oh, something went wrong');
})
});
For services that send the response back as JSON, you can use the following Dojo functions:
dojo.xhr, dojo.xhrDelete, dojo.xhrGet, dojo.xhrPost, dojo.xhrPut, dojo.rawXhrPost, and dojo.rawXhrPut depending on the type of call you make. Below is an example:
dojo.rawXhrPost({
url: url,
handleAs: 'json',
postData: parametersJSON,
headers: { "Content-Type": "text/json" },
timeout: 45000,
//function to be run in case of successful call to the specified Web method
load: function(data) {
onComplete(data);
},
//function to be run in case of failed call to the specified Web method
error: function(error) {
onError(error.message);
}
});
You can call a webservice on the same server as the page with a normal XHR call. If the server is on a different server then you should use a JSONP call. NOTE the JSONP doesnt have the best error handling.
You can easily call a JSON or a RESTful web service.
For SOAP web services you need a library.