JSONP(JSON with Padding)是一种在客户端与服务器之间进行跨域数据交换的技术。它通过动态添加script标签到当前文档,并使用回调函数返回结果的方式来实现。尽管JSONP存在一些限制,例如无法进行数据的POST请求,但它在请求不同域服务器的数据时非常有用。
在.NET 4.0中,WCF(Windows Communication Foundation)提供了对JSONP的支持。通过使用WebHttpBinding和设置crossDomainScriptAccessEnabled属性为true,可以让WCF服务支持跨域脚本。此外,还可以使用WebScriptEndpoint,它会自动添加WebScriptEnabling行为。
下面是一个示例,演示如何构建一个WCF服务,该服务返回一个字符串数组,用于在UI中加载HTML select控件的选项。
// OptionsService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace OptionsBuilderService
{
[DataContract]
public class ResponseOption
{
[DataMember]
public string[] Options;
}
[ServiceContract(Namespace = "OptionsBuilderService")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class OptionsService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public ResponseOption GetOptions(int typeId)
{
List options = new List();
ResponseOption rOptions = new ResponseOption();
switch (typeId)
{
case 1:
options.Add("Hero Honda");
options.Add("Bajaj");
options.Add("Harley Dvson");
options.Add("TVS");
break;
case 2:
options.Add("Toyota");
options.Add("TATA");
options.Add("General Motors");
options.Add("Audi");
options.Add("BMW");
break;
}
rOptions.Options = options.ToArray();
return rOptions;
}
}
}
为了使上述服务支持跨域脚本(JSONP),需要进行以下配置。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="None" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="OptionsService.svc" service="OptionsBuilderService.OptionsService" factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" />
</serviceActivations>
</serviceHostingEnvironment>
<standardEndpoints>
<webScriptEndpoint>
<standardEndpoint crossDomainScriptAccessEnabled="true" />
</webScriptEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>
客户端是一个简单的ASP.NET应用程序,它有一个名为Default.aspx的页面,使用Master.master。Default.aspx有两个HTML Select控件SelectVehicleTypes和SelectVehicles。SelectVehicles的选项来自服务调用。
// Default.aspx
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="http://localhost:7838/OptionsService.svc" />
</Services>
</asp:ScriptManager>
<br />
Select the vehicle type:
<select id="SelectVehicleTypes" onchange="makeMyServiceCall();">
<option value="1">Motor Bike</option>
<option value="2">Car</option>
</select>
<select id="SelectVehicles">
<option></option>
</select>
<br />
<script type="text/javascript" defer="defer">
makeMyServiceCall();
</script>