I am going nuts here. I've looked at the following entries and none of them are correcting the aberrant behavior I am seeing:
- http://stackoverflow.com/questions/288850/how-to-return-json-from-a-2-0-asmx-web-service
- http://stackoverflow.com/questions/1678101/how-to-return-json-from-asp-net-asmx
- http://stackoverflow.com/questions/211348/how-to-let-an-asmx-file-output-json
I've also looked at, and confirmed my setup: http://www.asp.net/AJAX/documentation/live/ConfiguringASPNETAJAX.aspx
Here is my code (ASMX code behind):
namespace RivWorks.Web.Services
{
/// <summary>
/// Summary description for Negotiate
/// </summary>
[WebService(Namespace = "http://rivworks.com/webservices/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[ScriptService]
public class Negotiate : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public RivWorks.Data.Objects.rivProduct GetSetup(string jsonInput)
{
// Deserialize the input and get all the data we need...
// TODO: This is a quick hack just to work with this for now...
char[] tokens = { '(', '{', '}', ')', ',', '"' };
string[] inputs = jsonInput.Split(tokens);
string inputRef = "";
string inputDate = "";
string inputProductID = "";
for (int i = 0; i < inputs.Length; i++)
{
if (inputs[i].Equals("ref", StringComparison.CurrentCultureIgnoreCase))
inputRef = inputs[i+2];
if (inputs[i].Equals("dt", StringComparison.CurrentCultureIgnoreCase))
inputDate = inputs[i+2];
if (inputs[i].Equals("productid", StringComparison.CurrentCultureIgnoreCase))
inputProductID = inputs[i+2];
}
Guid pid = new Guid(inputProductID);
RivWorks.Data.Objects.rivProduct product = RivWorks.Data.rivProducts.GetProductById(pid);
return product;
}
}
When I run this from my localhost instance I am getting this result set:
<ResultSet>
<uiType>modal</uiType>
<width>775</width>
<height>600</height>
<swfSource>
http://localhost.rivworks.com/flash/negotiationPlayer.swf
</swfSource>
<buttonConfig>
http://cdn1.rivworks.com/Element/Misc/734972de-40ae-45f3-9610-5331ddd6e8f8/apple-logo-2.jpg
</buttonConfig>
</ResultSet>
What am I missing???
NOTE: I am using the 3.5 framework (or at least I thought I was as everything in my web.config is marked for 3.5.0.0)
UPDATE: I am browsing to the service and using the input box on that page. You can try here: http://dev.rivworks.com/services/Negotiate.asmx?op=GetSetup. We are also trying to access it from a JS based web app running on another site (the main purpose of this particular service). I do not have the code for that here. (Sorry, the test form is only available from localhost.)
UPDATE: I added the following test page (JsonTest.htm) to try to see what was going back and forth. All I get is a 500 error! I even tried attaching to the process and break into my service. THe 500 error is thrown before the ASP pipeline ever gets into my code.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled Page</title>
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
function sendReq() {
alert("Before AJAX call");
$.ajax(
{
type: "POST"
, url: "http://kab.rivworks.com/Services/Negotiate.asmx/GetSetup"
, data: "{ \"ref\":\"http://www.rivworks.com/page.htm\", \"dt\":\"Mon Dec 14 2009 10:45:25 GMT-0700 (MST)\", \"productId\":\"5fea7947-251d-4779-85b7-36796edfe7a3\" }"
, contentType: "application/json; charset=utf-8"
, dataType: "json"
, success: GetMessagesBack
, error: Failure
}
);
alert("After AJAX call");
}
function GetMessagesBack(data, textStatus) {
alert(textStatus + "\n" + data);
}
function Failure(XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus + "\n" + errorThrown + "\n" + XMLHttpRequest);
}
</script>
</head>
<body>
<div id="test">Bleh</div>
<a href="javascript:sendReq()">Test it</a>
</body>
</html>
Why is this so painfully hard?!?! :)
UPDATE: Working through a WCF service. Here is my setup: Interface:
namespace RivWorks.Web.Services
{
[ServiceContract(Name = "Negotiater", Namespace = "http://www.rivworks.com/services")]
public interface INegotiaterJSON
{
//[WebMethod]
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]
ResultSet GetSetup(string jsonInput);
}
}
Class:
namespace RivWorks.Web.Services
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Negotiater : INegotiaterJSON
{
public ResultSet GetSetup(string jsonInput)
{
//code removed for brevity - see ASMX code above if you are really interested.
return resultSet;
}
}
[DataContract()]
public class ResultSet
{
[DataMember]
public string uiType = "modal";
[DataMember]
public int width = 775;
[DataMember]
public int height = 600;
[DataMember]
public string swfSource = "";
[DataMember]
public string buttonConfig = "";
}
}
web.config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name ="soapBinding">
<security mode="None" />
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="webBinding">
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="poxBehavior">
<webHttp/>
</behavior>
<behavior name="jsonBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="RivWorks.Web.Services.Negotiater" behaviorConfiguration="defaultBehavior">
<endpoint address="json"
binding="webHttpBinding"
bindingConfiguration="webBinding"
behaviorConfiguration="jsonBehavior"
contract="RivWorks.Web.Services.INegotiaterJSON" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://dev.rivworks.com" />
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>
simple test page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled Page</title>
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
function sendReq() {
alert("Before AJAX call");
$.ajax(
{
type: "POST"
, url: "http://dev.rivworks.com/Services/Negotiater.svc/GetSetup"
, data: "{ \"ref\":\"http://www.rivworks.com/page.htm\", \"dt\":\"Mon Dec 14 2009 10:45:25 GMT-0700 (MST)\", \"productId\":\"5fea7947-251d-4779-85b7-36796edfe7a3\" }"
, contentType: "application/json; charset=utf-8"
, dataType: "json"
, success: GetMessagesBack
, error: Failure
}
);
alert("After AJAX call");
}
function GetMessagesBack(data, textStatus) {
alert(textStatus + "\n" + data);
}
function Failure(XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus + "\n" + errorThrown + "\n" + XMLHttpRequest);
}
</script>
</head>
<body>
<div id="test">Bleh</div>
<!--<button onclick="javascript:sendReq()">TEST IT</button>-->
<a href="javascript:sendReq()">Test it</a>
</body>
</html>
And now I am getting this error: IIS specified authentication schemes 'IntegratedWindowsAuthentication, Anonymous', but the binding only supports specification of exactly one authentication scheme. Valid authentication schemes are Digest, Negotiate, NTLM, Basic, or Anonymous. Change the IIS settings so that only a single authentication scheme is used.
How do I handle this? <state emotion='wrung out' physical='beat up' />