我在这里疯了。我查看了以下条目, none 正在纠正我看到的异常行为:
我也看过了,并确认了我的设置:http://www.asp.net/AJAX/documentation/live/ConfiguringASPNETAJAX.aspx
这是我的代码(ASMX代码背后):
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;
}
}
当我从我的localhost实例运行时,我得到了这个结果集:
<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>
我缺少什么?
注意:我正在使用3.5框架(或者至少我认为我的web.config标记为3.5.0.0)
更新:我正在浏览该服务并使用该页面上的输入框。你可以在这里试试:http://dev.rivworks.com/services/Negotiate.asmx?op=GetSetup。我们还试图从在另一个站点上运行的基于JS的Web应用程序(此特定服务的主要目的)访问它。我这里没有代码。 (对不起,测试表只能从localhost获得。)
更新:我添加了以下测试页面(JsonTest.htm)以尝试查看来回的内容。我得到的只是500错误!我甚至试图加入这个过程并打破我的服务。在ASP管道进入我的代码之前,会抛出500错误。
<!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>
为什么这么痛苦?!?! :)
更新:通过WCF服务。这是我的设置: 接口:
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);
}
}
类别:
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>
简单测试页
<!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>
现在我收到了这个错误: IIS指定的身份验证方案“IntegratedWindowsAuthentication,Anonymous”,但绑定仅支持一种身份验证方案的规范。有效的身份验证方案是Digest,Negotiate,NTLM,Basic或Anonymous。更改IIS设置,以便仅使用单个身份验证方案。
我该如何处理? &lt; state emotion ='拧干'physical ='beat up'/&gt;
答案 0 :(得分:8)
为什么不将ASMX Web服务迁移到WCF?
.NET Framework 3.5中的WCF API本身支持JSON Web服务。
此外,Microsoft将ASMX称为“遗留技术”,并建议“现在应使用Windows Communication Foundation(WCF)创建Web服务和XML Web服务客户端”。 (Source)。
您可以查看这些链接以开始使用:
此外,您可能还想阅读以下我从我自己托管的WCF项目中“提取”的示例。自托管WCF服务不需要IIS,但可以从任何托管的.NET应用程序提供。此示例托管在一个非常简单的 C#控制台应用程序:
中<强> IContract.cs 强>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace MyFirstWCF
{
[ServiceContract]
public interface IContract
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/CustomerName/{CustomerID}")]
string GET_CustomerName(string CustomerID);
}
}
<强> Service.cs 强>
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;
namespace MyFirstWCF
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.NotAllowed)]
public class Service : IContract
{
public string GET_CustomerName(string CustomerID)
{
return "Customer Name: " + CustomerID;
}
}
}
WCFHost.cs (控制台应用程序)
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using System.Threading;
using System.Text;
namespace MyFirstWCF
{
class Program
{
private static WebServiceHost M_HostWeb = null;
static void Main(string[] args)
{
M_HostWeb = new WebServiceHost(typeof(MyFirstWCF.Service));
M_HostWeb.Open();
Console.WriteLine("HOST OPEN");
Console.ReadKey();
M_HostWeb.Close();
}
}
}
<强>的app.config 强>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="MyFirstWCF.Service">
<endpoint address="http://127.0.0.1:8000/api"
binding="webHttpBinding"
contract="MyFirstWCF.IContract" />
</service>
</services>
</system.serviceModel>
</configuration>
以上示例非常基本。如果您使用Fiddler与http://127.0.0.1:8000/api/CustomerName/1000
建立请求,则只会返回"Customer Name: 1000"
。
确保在请求标头中设置content-type: application/json
。要返回更复杂的数据结构,您必须使用数据协定。这些构造如下:
[DataContract]
public class POSITION
{
[DataMember]
public int AssetID { get; set; }
[DataMember]
public decimal Latitude { get; set; }
[DataMember]
public decimal Longitude { get; set; }
}
您需要将System.RuntimeSerialization
,System.ServiceModel
和System.ServiceModel.Web
的.NET引用添加到此示例项目中进行编译。
答案 1 :(得分:3)
对方法的请求设置的“内容类型”是什么?
从我对ASP.NET所做的工作来看,如果设置为text/xml
,你将获得XML;但如果它设置为application/json
,你将获得JSON。