Kei*_*ows 5 .net wcf json web-services asmx
我在这里疯了.我查看了以下条目,但没有一个能纠正我看到的异常行为:
我也看过了,并确认了我的设置: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;
}
}
Run Code Online (Sandbox Code Playgroud)
当我从我的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>
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
注意:我正在使用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>
Run Code Online (Sandbox Code Playgroud)
为什么这么痛苦?!?!:)
更新:通过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);
}
}
Run Code Online (Sandbox Code Playgroud)
类:
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 = "";
}
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
简单的测试页面
<!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>
Run Code Online (Sandbox Code Playgroud)
现在我收到此错误: IIS指定了身份验证方案'IntegratedWindowsAuthentication,Anonymous',但绑定仅支持一种身份验证方案的规范.有效的身份验证方案是Digest,Negotiate,NTLM,Basic或Anonymous.更改IIS设置,以便仅使用单个身份验证方案.
我该如何处理?<state emotion ='拧干'physical ='beat up'/>
为什么不将ASMX Web服务迁移到WCF?
.NET Framework 3.5中的WCF API本机支持JSON Web服务.
此外,Microsoft将ASMX称为"遗留技术",并建议"现在应使用Windows Communication Foundation(WCF)创建Web服务和XML Web服务客户端".(来源).
您可以查看这些链接以开始使用:
此外,您可能还想阅读以下示例,该示例是我从我自己托管的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);
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
的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>
Run Code Online (Sandbox Code Playgroud)
上面的例子非常基本.如果你建立一个请求提琴手到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; }
}
Run Code Online (Sandbox Code Playgroud)
您需要添加.NET引用System.RuntimeSerialization,System.ServiceModel并System.ServiceModel.Web为此示例项目进行编译.