1

我正在尝试使用返回 json 的 Mono 3.0.3.5 创建 Web 服务。

但到目前为止,我一直无法获得返回 xml 以外的任何内容的服务。这似乎是过去讨论过很多的问题,但即使在检查了我对这里和其他地方的大量资源的尝试之后,我也无法说出我遗漏了什么。

我创建了一个空的 ASP.NET 解决方案,并在其中添加了一个带有代码隐藏页面的 asmx。据我所知,使用 ScriptService 属性装饰服务类名称和使用 ScriptMethod 的方法/函数名称以及为 ResponseFormat 属性指定 Json 是代码中唯一必要的步骤。

using System;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;

namespace MonoJsonTest
{
   [WebService]
   [ScriptService]
   public class GimmeJson : System.Web.Services.WebService
   {
      [WebMethod]
      [ScriptMethod(ResponseFormat=ResponseFormat.Json)]
      public    string  simpleTestString()
      {
         return DateTime.Now.ToString();
      }
   }
}

(我知道将日期放入 json 的问题,我只是想要一些会随着后续调用我的服务而改变的字符串)

然后我将 System.Web.Extensions 添加到项目的引用中。这是针对 .NET 3.5 版构建的,因此我确保包含了 System.Web.Extensions 的 3.5 版。

然后 web.config 的 httpHandlers 被修改为通过 ScriptHandlerFactory (如我发现的几页所述)

http://vampirebasic.blogspot.com/2009/04/aspnet-ajax-in-mono.html

http://encosia.com/asmx-scriptservice-mistakes-installation-and-configuration/

敏锐的眼睛可能会注意到两个页面上指定的 web.config 更改存在差异。“Culture=neutral”属性在第一页的 type 属性的字符串内部指定,但在第二页作为 add 标记的属性。但是我发现当指定第二种方式时,启动服务时出现错误。

我的最终 web.config:

<?xml version="1.0"?>
<configuration>
    <system.web>
    <compilation defaultLanguage="C#" debug="true">
      <assemblies>
        <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral,    PublicKeyToken=31bf3856ad364e35" />
      </assemblies>
    </compilation>
    <customErrors mode="RemoteOnly">
    </customErrors>
    <authentication mode="None">
    </authentication>
    <authorization>
      <allow users="*" />
    </authorization>
    <httpHandlers>
      <!-- should produce json responses -->
      <remove verb="*" path="*.asmx" />
      <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </httpHandlers>
    <trace enabled="false" localOnly="true" pageOutput="false" requestLimit="10" traceMode="SortByTime" />
    <sessionState mode="InProc" cookieless="false" timeout="20" />
    <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
    <pages>
    </pages>
  </system.web>
</configuration>

但是从 WSDL 页面或使用来自 javascript 的 ajax 查询(使用 JQuery 库)访问服务(本地),它总是返回 XML。使用 Charles 和 Firefox 调试工具检查响应标头向我显示了 text/xml 的响应类型。

经研究,调用时似乎需要向服务请求json,所以我设置了ajax调用的contentType、accept和dataType参数来指定json,但这并没有什么区别。奇怪的是,即使请求标头显示“Accepts”参数在我在 Ajax 调用中明确设置后仍然指定 xml。

这是 ajax 调用(注意接受并且 dataType 类型设置为 json):

$.ajax({
url: "http://localhost:8080/GimmeJson.asmx/simpleTestString",
type: "POST",
contentType: "application/json; charset=utf-8",
accepts: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
success: function (data, textStatus, jqXHR) { console.log( "success" ); alert.show("success"); },
error: function(request, type, errorThrown) { console.log( "error" ); }
});    

这是该调用生成的请求标头(Accept 仍然是 xml):

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding:gzip,deflate
Accept-Language:en-us,en;q=0.5
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Cache-Control:no-cache
Host:localhost:8080
Origin:null
Pragma:no-cache
Proxy-Connection:keep-alive
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:14.0) Gecko/20100101 Firefox/14.0.1

这会产生一个 200 的 HTTP 代码,以及这个响应头(注意内容类型是 xml):

Cache-Control:private
Content-Length:103
Content-Type:text/xml; charset=utf-8
Date:Thu, 09 Aug 2012 23:38:59 GMT
Keep-Alive:timeout=15, max=100
Proxy-Connection:Keep-alive
Server:Mono.WebServer2/0.2.0.0 
UnixX-AspNet-Version:2.0.50727

我注意到我不确定的一件事很重要,但似乎很奇怪。我浏览了 Mono 中的 System.Web.Extensions dll,发现其中似乎不存在 ScriptHandlerFactory。修改 web.config 中添加工厂的行以指定“FOOScriptHandlerFactory”作为类型在启动服务时没有产生任何错误,这似乎表明 Mono 没有在 web.config 中报告未找到的类型。但我对 .Net 和 Mono 的这方面了解不够,无法肯定地说。但由于这个工厂是自动 Json 序列化的关键,这可能很重要。

我不确定我在这里省略了什么。我觉得我没有在服务器端正确配置一些东西,或者它会在 WSDL 页面上的某处报告返回类型的 json。正如您可能已经猜到的那样,我还是在线开发的新手,所以如果我忽略了非常明显的事情,我深表歉意。

4

1 回答 1

1

您是否尝试过将 WebMethod 设为静态?

我要考虑的另一点是返回的函数是否可以返回 3 个值而不仅仅是一个。

于 2012-12-19T21:25:03.667 回答