数小时的困惑导致我向SO提出自己的贡献问题:
我已将问题缩小到测试解决方案,这就是我所拥有的:
单击按钮后, RunService()会调用WCF服务(webHttpBinding),然后显示服务的响应。接下来的步骤是将一些数据保存到HttpContext.Current.Session(另一个多天的头痛,通过盲目刺伤找到解决方案)。
这是一个Visual Studio 2012解决方案,具有Webforms项目(com.dwf)和WCF服务项目(com.dwf.services),这些项目被发送到本地主机(不同的本地主机,因为它们是两个不同的项目)。为了解决跨域问题,在javascript方面,我添加了 $ .support.cors = true 标志以防止“No Transport”错误。当它发布到共享服务器时,该服务将存在于虚拟目录中,该目录是原始域的子目录(httpdocs / Service)。
当用户单击按钮时,以下功能在客户端运行。
function RunService() {
$.support.cors = true;
$.ajax({
url: 'http://localhost:XXXX/Service1.svc/web/GetData',
cache:false,
data: {
userName: 'DWF',
password: 'ban',
},
contentType: 'application/json; charset=utf-8',
success: function (response) {
$('#results').text('jQuery says ' + response);
$.ajax({
type:'POST',
url: location.href.slice('http://localhost:7177/'.length + '/SaveToSession',
data: JSON.stringify({userName: 'DWF',password: 'ban'}),
error: function (e) {
alert(e.statusText);
},
contentType: 'application/json; charset=utf-8'
});
},
error: function (err) {
$('#results').text(err.statusText);
}
});
}
Service1.svc是一个支持REST的服务,如下所示:
[System.ServiceModel.Activation.AspNetCompatibilityRequirements
(RequirementsMode=
System.ServiceModel.Activation.AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public string GetData(string userName, string password)
{
return string.Format("You entered: {0}/{1}", userName, password);
}
}
当然,它的界面是这样的:
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(ResponseFormat=WebMessageFormat.Json)]
string GetData(string userName, string password);
}
,网络配置就像这样
<system.serviceModel>
...
<behaviors>
<endpointBehaviors>
<behavior name="RESTEndpointBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="com.dwf.services.Service1">
<endpoint address="web" behaviorConfiguration="RESTEndpointBehavior" binding="webHttpBinding" contract="com.dwf.services.IService1"></endpoint>
<endpoint address="ws" binding="wsHttpBinding" contract="com.dwf.services.IService1"></endpoint>
</service>
</services>
我调用的WebMethod SaveToSession存在于每个页面都将继承的BasePage类中。它看起来像这样:
public class BasePage : Page
{
[System.Web.Services.WebMethod]
[System.ServiceModel.Web.WebInvoke(Method="POST")]
public static void SaveToSession(string userName, string password)
{
HttpContext.Current.Session["TextValue"] = "Session says " + userName + " entered " + password;
}
}
如果我使用 JSON.stringify 调用第一个方法(WCF的GetData),我的参数将为null。 如果我在不使用 JSON.stringify 的情况下调用第二种方法(WebMethod的SaveToSession),我的方法会收到内部服务器错误。只有使用上面的ajax调用才能解决此问题。
EDIT
为什么WCF服务需要JSON.stringify,而WebMethod不适用?
为什么JSON.stringify对WCF服务不合适,而WebMethod需要?
这最初是为了更好地理解ASP.NET,Sessions,WCF和静态方法之间的通信,并希望揭开Web.config的神秘面纱。看起来好像我正在努力解决它的一切工作方式的每一步,最后似乎没有什么方便。
答案 0 :(得分:1)
WCF服务将参数作为对象,服务器在输入时解释输入,“理解”参数名称是传入JSON对象的成员名称。
通过对其进行字符串化来发送整个对象正在发送一个巨大的字符串,其中服务器端代码需要将对象解析为其各自的部分。一种序列化/反序列化的交易。如果有人想要将服务的签名简化为一个参数,则可以使用此选项,如果您拥有可以默认值的对象,这将非常有用。
<强>伪代码强>
GetData(string data)
{
EstablishedDataObject obj = DeserializeData(data);
DoSomething(obj);
}
这比
更容易服务器端代码GetData(int id, string name, bool likesBruceWillisAsASinger, int numberOfFelonies,
string streetName, int numberOfTattoos, bool dislikesTacosButLikesTheIdeaOfTacos)
WebMethod,我仍然坚持的那个。它可能最终变得像“微软如何编程它一样简单,但祝你好运找到可靠的文档。”