【问题标题】:Asmx web service how to return JSON and not XML?Asmx Web 服务如何返回 JSON 而不是 XML?
【发布时间】:2013-02-19 05:37:24
【问题描述】:

我的服务方式:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string getDataFromTrainingMaster()
{
    List<TrainingMasterDataStruct> results = new DAL().GetDataFromTrainingMaster();
    JavaScriptSerializer js = new JavaScriptSerializer();                    
    return js.Serialize(results).ToString(); 
}

我的 .net Web 服务返回包装在 XML 中的 JSON,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<string xmlns="http://tempuri.org/">   [{"Training_Code":"1234 ","Training_Duration":"2hrs ","Training_Startdate":"2/14/2013 3:00:00 PM","Training_Enddate":"2/14/2013 5:00:00 PM","Trainer_ID":1,"Training_Location":"B-Wing Training room-4","Comments":"C# training","Keyword":"C#1234","NumberofDays":1},{"Training_Code":"4321 ","Training_Duration":"16 ","Training_Startdate":"2/17/2013 10:30:00 AM","Training_Enddate":"2/17/2013 5:30:00 PM","Trainer_ID":2,"Training_Location":"A-Wing Training Room-6","Comments":"Objective-C","Keyword":"Obj-C4321","NumberofDays":2}]

我需要以下格式:

"Training":[{"Training_Code":"1234 ","Training_Duration":"2hrs ","Training_Startdate":"2/14/2013 3:00:00 PM","Training_Enddate":"2/14/2013 5:00:00 PM","Trainer_ID":1,"Training_Location":"B-Wing Training room-4","Comments":"C# training","Keyword":"C#1234","NumberofDays":1},{"Training_Code":"4321 ","Training_Duration":"16 ","Training_Startdate":"2/17/2013 10:30:00 AM","Training_Enddate":"2/17/2013 5:30:00 PM","Trainer_ID":2,"Training_Location":"A-Wing Training Room-6","Comments":"Objective-C","Keyword":"Obj-C4321","NumberofDays":2}]</string>

我该怎么做?

【问题讨论】:

  • 您使用什么技术来创建 Web 服务? ASP.NET Web API?静态页面方法? WCF?
  • 感谢您通过添加服务器端代码进行澄清,我看到您正在使用 WebMethod 属性。这是许多不同的网络服务框架之一,所以在提出问题时一定要提到这一点。看起来在这里讨论(并回答)了同样的问题 - stackoverflow.com/questions/5611134/…

标签: c# asp.net .net asmx javascriptserializer


【解决方案1】:

无需自己创建 JSON 字符串。返回 List&lt;TrainingMasterDataStruct&gt; 并让 .NET 即时为您序列化它:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public List<TrainingMasterDataStruct> getDataFromTrainingMaster()
{
   List<TrainingMasterDataStruct> list = doStuff();
   return list;
}

其次,非静态方法签名表明这是一个 asmx 文件(页面方法是静态的)。默认情况下,这些序列化为 xml,因此您需要取消注释或将 System.Web.Script.Services.ScriptService 属性添加到 Web 服务类:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService {

这允许它返回 JSON。一个问题:JSON 序列化器似乎能够序列化比 XML 更多的类型,所以如果你想输出或者/或在这里要小心 - 在这里使用列表和数组而不是集合。

第三,非常重要,客户端必须向服务器表明它需要 JSON 响应。

为了测试和验证第三点,我建议您按照上述步骤,然后使用 jQuery 从测试网页调用 Web 服务并监控 Fiddler 中的流量。比如:

$.ajax({
        type: "POST",
        url: "WebService.asmx/getDataFromTrainingMaster",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        data: "",
        success: function (msg) { }
    });

这是 JSON 请求/响应的样子 - 请特别注意 POST、Accept 和 Content-Type 标头:

POST http://scrubbed/GetVehicles HTTP/1.1
x-requested-with: XMLHttpRequest
Accept-Language: en-gb
Accept: application/json, text/javascript, */*
Content-Type: application/json; charset=utf-8
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; InfoPath.2)
Host: scrubbed
Content-Length: 0
Connection: Keep-Alive
Pragma: no-cache

HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Mon, 04 Oct 2010 10:49:12 GMT
Content-Length: 1417

{"d":{"Data":[{"Key":1,"Value":[{"VehicleId":15036,"VehicleAlias":"Whatever","Expiry":"\/Date(1915983035043)\/","Expired":false},{"VehicleId":

【讨论】:

    【解决方案2】:

    尝试将您的返回类型更改为List&lt;TrainingMasterDataStruct&gt; 并返回“results”。您不需要自己序列化字符串,带有 WebMethod 属性的 ASP.NET 会为您解决这个问题。

    【讨论】:

      【解决方案3】:

      你可以试试这个:

      var data = [{"Training_Code":"1234 ","Training_Duration":"2hrs ","Training_Startdate":"2/14/2013 3:00:00 PM","Training_Enddate":"2/14/2013 5:00:00 PM","Trainer_ID":1,"Training_Location":"B-Wing Training room-4","Comments":"C# training","Keyword":"C#1234","NumberofDays":1},{"Training_Code":"4321 ","Training_Duration":"16 ","Training_Startdate":"2/17/2013 10:30:00 AM","Training_Enddate":"2/17/2013 5:30:00 PM","Trainer_ID":2,"Training_Location":"A-Wing Training Room-6","Comments":"Objective-C","Keyword":"Obj-C4321","NumberofDays":2}]
      
      var result = JSON.stringify({ Training: data })
      

      result 会给你想要的输出。

      【讨论】:

      • 从哪个命名空间“JSON”belogs。现在出现错误,“JSON”不在当前上下文中。
      • 其实 json.stringify 是一个 javascript 函数,所以你可以尝试使用 ajax 在客户端调用你的 web 服务并使用它。也许这会起作用。
      • JSON.stringify 并非内置于所有浏览器中。使用 json2.js。 github.com/douglascrockford/JSON-js
      【解决方案4】:

      我遇到了类似的错误。一种方法以正确的 json 格式返回响应,但另一种方法以相同的 asmx 格式返回 xml。

      这里有两种方法:

      JSON 格式的响应:

      [WebMethod]
          [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
          public string loginOne(string param1, string param2){
                result = new JObject();
                ...
                ...
                return result.ToString();
          }
      

      XML 格式的响应:

       [WebMethod]
          [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
          public string getCompaniesOne()
          {
              ...
              ...
              return result.ToString();
          }
      

      我是怎么解决的?

      在错误的响应方法中添加一个虚拟参数。

       [WebMethod]
          [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
          public string getCompaniesOne(string dummy)
          {
             ...
             ...
             return result.ToString();
          }       
      

      希望对您有所帮助。

      【讨论】:

        猜你喜欢
        • 2012-06-20
        • 2020-06-02
        • 2011-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-26
        相关资源
        最近更新 更多