2012-08-10 79 views
1

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

但到目前为止,我一直无法得到一个服务来返回任何东西,但XML。这似乎是过去很多讨论的问题,但即使在查看我在这里和其他地方的众多资源的尝试之后,我也无法知道我在省略什么。

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

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版,所以我确保我包含3.5版的System.Web.Extensions。

然后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更改有所不同。指定了“文化=中性”属性 - 在第一页中指定type属性的字符串,但作为第二个页面上添加标签的属性。但是我发现,当指定第二种方式时,启动服务时出现错误。

我最后的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(使用jQuery库)的AJAX查询始终返回XML服务(本地)。使用Charles和Firefox调试工具检查响应头文件会显示响应类型的text/xml。

经过研究,在进行调用时,似乎需要从服务请求json,因此我设置了ajax调用的contentType,accepting和dataType参数以指定json,但这没什么区别。奇怪的是,即使请求标头显示“接受”参数仍然指定xml后,我已明确设置它在Ajax调用。

这里是AJAX调用(注接受和数据类型类型设置为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"); } 
});  

这里是由通话产生请求头(接受还在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似乎并不存在于其中。修改网络中的行。配置文件中添加了工厂以指定“FOOScriptHandlerFactory”,因为类型在启动服务时不会产生任何错误,这似乎表明Mono不报告web.config中的不合适的类型。但是我对.NET和Mono的这方面知之甚少,无法确定。但由于这家工厂是自动Json系列化的关键,这可能很重要。

我不知道我在这里略过了什么。我觉得我没有正确地在服务器端配置某些东西,或者它将报告json作为WSDL页面某处的返回类型。正如你可能已经猜到的,我还是新来的在线开发,所以我很抱歉,如果我忽略了非常明显的事情。

回答

1

您是否尝试过使WebMethod静态?

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