.NET ASMX - 返回纯 JSON?

2024-01-02

我在这里要疯了。我查看了以下条目并none他们中的一些人正在纠正我所看到的异常行为:

  • 如何从 2.0 asmx Web 服务返回 JSON https://stackoverflow.com/questions/288850/how-to-return-json-from-a-2-0-asmx-web-service
  • 如何从 ASP.NET .asmx 返回 JSON? https://stackoverflow.com/questions/1678101/how-to-return-json-from-asp-net-asmx
  • 如何让 ASMX 文件输出 JSON https://stackoverflow.com/questions/211348/how-to-let-an-asmx-file-output-json

我也查看并确认了我的设置:http://www.asp.net/AJAX/documentation/live/ConfiguringASPNETAJAX.aspx http://www.asp.net/AJAX/documentation/live/ConfiguringASPNETAJAX.aspx

这是我的代码(后面的 ASMX 代码):

namespace RivWorks.Web.Services
{
    /// <summary>
    /// Summary description for Negotiate
    /// </summary>
    [WebService(Namespace = "http://rivworks.com/webservices/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [ScriptService]
    public class Negotiate : System.Web.Services.WebService
    {
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public RivWorks.Data.Objects.rivProduct GetSetup(string jsonInput)
        {
            // Deserialize the input and get all the data we need...
            // TODO:  This is a quick hack just to work with this for now...
            char[] tokens = { '(', '{', '}', ')', ',', '"' };
            string[] inputs = jsonInput.Split(tokens);
            string inputRef = "";
            string inputDate = "";
            string inputProductID = "";
            for (int i = 0; i < inputs.Length; i++)
            {
                if (inputs[i].Equals("ref", StringComparison.CurrentCultureIgnoreCase))
                    inputRef = inputs[i+2];
                if (inputs[i].Equals("dt", StringComparison.CurrentCultureIgnoreCase))
                    inputDate = inputs[i+2];
                if (inputs[i].Equals("productid", StringComparison.CurrentCultureIgnoreCase))
                    inputProductID = inputs[i+2];
            }

            Guid pid = new Guid(inputProductID);
            RivWorks.Data.Objects.rivProduct product = RivWorks.Data.rivProducts.GetProductById(pid);

            return product;
        }
    }

当我从本地主机实例运行此命令时,我得到以下结果集:

  <ResultSet>
    <uiType>modal</uiType>
    <width>775</width>
    <height>600</height>
    <swfSource>
    http://localhost.rivworks.com/flash/negotiationPlayer.swf
    </swfSource>
    <buttonConfig>
    http://cdn1.rivworks.com/Element/Misc/734972de-40ae-45f3-9610-5331ddd6e8f8/apple-logo-2.jpg
    </buttonConfig>
  </ResultSet>

我错过了什么???


注意:我正在使用 3.5 框架(或者至少我认为我是这样,因为我的 web.config 中的所有内容都标记为 3.5.0.0)


更新:我正在浏览该服务并使用该页面上的输入框。您可以在这里尝试:http://dev.rivworks.com/services/Negotiate.asmx?op=GetSetup http://dev.rivworks.com/services/Negotiate.asmx?op=GetSetup。我们还尝试从另一个站点上运行的基于 JS 的 Web 应用程序访问它(此特定服务的主要目的)。我这里没有相关代码。 (抱歉,测试表格只能从本地主机获得。)


更新:我添加了以下测试页面(JsonTest.htm)来尝试查看来回发生了什么。我得到的只是 500 错误!我什至尝试附加到该进程并闯入我的服务。在 ASP 管道进入我的代码之前就抛出了 500 错误。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Untitled Page</title>
    <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.js" type="text/javascript"></script>

    <script language="javascript" type="text/javascript">
        function sendReq() {
            alert("Before AJAX call");
            $.ajax(
            {
                type: "POST"
                , url: "http://kab.rivworks.com/Services/Negotiate.asmx/GetSetup"
                , data: "{ \"ref\":\"http://www.rivworks.com/page.htm\", \"dt\":\"Mon Dec 14 2009 10:45:25 GMT-0700 (MST)\", \"productId\":\"5fea7947-251d-4779-85b7-36796edfe7a3\" }"
                , contentType: "application/json; charset=utf-8"
                , dataType: "json"
                , success: GetMessagesBack
                , error: Failure
            }
            );
            alert("After AJAX call");
        }
        function GetMessagesBack(data, textStatus) {
            alert(textStatus + "\n" + data);
        }
        function Failure(XMLHttpRequest, textStatus, errorThrown) {
            alert(textStatus + "\n" + errorThrown + "\n" + XMLHttpRequest);
        }
    </script>
</head>
<body>
    <div id="test">Bleh</div>
    <a href="javascript:sendReq()">Test it</a>
</body>
</html>

为什么这么难受?!?! :)


更新:通过 WCF 服务工作。这是我的设置:界面:

namespace RivWorks.Web.Services
{
    [ServiceContract(Name = "Negotiater", Namespace = "http://www.rivworks.com/services")]
    public interface INegotiaterJSON
    {
        //[WebMethod]
        [OperationContract]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        [ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]
        ResultSet GetSetup(string jsonInput);
    }
}

Class:

namespace RivWorks.Web.Services
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class Negotiater : INegotiaterJSON
    {
        public ResultSet GetSetup(string jsonInput)
        {
            //code removed for brevity - see ASMX code above if you are really interested.
            return resultSet;
        }
    }


    [DataContract()]
    public class ResultSet
    {
        [DataMember]
        public string uiType = "modal";
        [DataMember]
        public int width = 775;
        [DataMember]
        public int height = 600;
        [DataMember]
        public string swfSource = "";
        [DataMember]
        public string buttonConfig = "";
    }
}

网络配置

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name ="soapBinding">
          <security mode="None" />
        </binding>
      </basicHttpBinding>
      <webHttpBinding>
        <binding name="webBinding">
          <security mode="None" />
        </binding>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="poxBehavior">
          <webHttp/>
        </behavior>
        <behavior name="jsonBehavior">
          <enableWebScript  />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="defaultBehavior">
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="RivWorks.Web.Services.Negotiater" behaviorConfiguration="defaultBehavior">
        <endpoint address="json"
                  binding="webHttpBinding"
                  bindingConfiguration="webBinding"
                  behaviorConfiguration="jsonBehavior"
                  contract="RivWorks.Web.Services.INegotiaterJSON" />
      </service>
    </services>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
      <baseAddressPrefixFilters>
        <add prefix="http://dev.rivworks.com" />
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
  </system.serviceModel>

简单的测试页

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Untitled Page</title>
    <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.js" type="text/javascript"></script>

    <script language="javascript" type="text/javascript">
        function sendReq() {
            alert("Before AJAX call");
            $.ajax(
            {
                type: "POST"
                , url: "http://dev.rivworks.com/Services/Negotiater.svc/GetSetup"
                , data: "{ \"ref\":\"http://www.rivworks.com/page.htm\", \"dt\":\"Mon Dec 14 2009 10:45:25 GMT-0700 (MST)\", \"productId\":\"5fea7947-251d-4779-85b7-36796edfe7a3\" }"
                , contentType: "application/json; charset=utf-8"
                , dataType: "json"
                , success: GetMessagesBack
                , error: Failure
            }
            );
            alert("After AJAX call");
        }
        function GetMessagesBack(data, textStatus) {
            alert(textStatus + "\n" + data);
        }
        function Failure(XMLHttpRequest, textStatus, errorThrown) {
            alert(textStatus + "\n" + errorThrown + "\n" + XMLHttpRequest);
        }
    </script>

</head>
<body>
    <div id="test">Bleh</div>
    <!--<button onclick="javascript:sendReq()">TEST IT</button>-->
    <a href="javascript:sendReq()">Test it</a>
</body>
</html>

现在我收到这个错误:IIS 指定了身份验证方案“IntegratedWindowsAuthentication、Anonymous”,但绑定仅支持指定一种身份验证方案。有效的身份验证方案包括摘要、协商、NTLM、基本或匿名。更改 IIS 设置,以便仅使用单一身份验证方案。

我该如何处理这个问题?


为什么不将 ASMX Web 服务迁移到 WCF?

.NET Framework 3.5 中的 WCF API 本身支持 JSON Web 服务。

此外,Microsoft 还宣布 ASMX 为“遗留技术”,并建议“Web 服务和 XML Web 服务客户端现在应该使用 Windows Communication Foundation (WCF) 创建”。 (Source http://msdn.microsoft.com/en-us/library/bb552872.aspx).

您可能需要查看这些链接来开始:

  • ASP.NET 3.5 中启用 JSON 的 WCF 服务 http://dotnetslackers.com/articles/ajax/json-enabledwcfservicesinaspnet35.aspx
  • 使用 WCF 和 JSON 的 REST 服务 http://dotnetninja.wordpress.com/2008/05/02/rest-service-with-wcf-and-json/
  • 使用 WebGet 和 WCF 3.5 创建 JSON 服务 http://dotnetslackers.com/articles/ajax/json-enabledwcfservicesinaspnet35.aspx
  • Microsoft WCF REST 入门套件 http://www.asp.net/downloads/starter-kits/wcf-rest/
  • 托管和使用 WCF 服务 http://msdn.microsoft.com/en-us/library/bb332338.aspx

此外,您可能还想阅读以下我从我的自托管 WCF 项目中“提取”的示例。自托管 WCF 服务不需要 IIS,但可以从任何托管 .NET 应用程序提供服务。这个例子托管在一个非常简单的C# 控制台应用程序:

IContract.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace MyFirstWCF
{
    [ServiceContract] 
    public interface IContract
    {
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/CustomerName/{CustomerID}")]
        string GET_CustomerName(string CustomerID);
    }
}

服务.cs

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;

namespace MyFirstWCF
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.NotAllowed)]
    public class Service : IContract
    {
        public string GET_CustomerName(string CustomerID)
        {
            return "Customer Name: " + CustomerID;
        }
    }
}

WCFHost.cs(控制台应用程序)

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using System.Threading;
using System.Text;

namespace MyFirstWCF
{
    class Program
    {
        private static WebServiceHost M_HostWeb = null;

        static void Main(string[] args)
        {
            M_HostWeb = new WebServiceHost(typeof(MyFirstWCF.Service));

            M_HostWeb.Open();

            Console.WriteLine("HOST OPEN");
            Console.ReadKey();

            M_HostWeb.Close();
        }
    }
}

应用程序配置

<?xml version="1.0" encoding="utf-8" ?>

<configuration>
  <system.serviceModel>
    <services>
      <service name="MyFirstWCF.Service">

        <endpoint address="http://127.0.0.1:8000/api"
                  binding="webHttpBinding"
                  contract="MyFirstWCF.IContract" />

      </service>
    </services>

  </system.serviceModel>
</configuration>

上面的例子是非常基本的。如果您使用以下命令构建请求Fiddler http://www.fiddler2.com/ to http://127.0.0.1:8000/api/CustomerName/1000它只会返回"Customer Name: 1000".

确保设置content-type: application/json在请求头中。要返回更复杂的数据结构,您将必须使用数据契约。它们的构造如下:

[DataContract]
public class POSITION
{
    [DataMember]
    public int      AssetID { get; set; }

    [DataMember]
    public decimal  Latitude { get; set; }

    [DataMember]
    public decimal  Longitude { get; set; }
}

您需要将 .NET 引用添加到System.RuntimeSerialization, System.ServiceModel and System.ServiceModel.Web为了编译这个示例项目。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.NET ASMX - 返回纯 JSON? 的相关文章

  • 是否曾经建议使用 ECB 密码模式?

    判断从这篇关于密码模式的维基百科文章 http en wikipedia org wiki Block cipher modes of operation以及我听说过的有关 ECB 的其他事情 这是一个很大的禁忌 并且可能会泄露有关您的加密
  • 如何将当前应用程序域的程序集动态加载到c#项目中?

    我正在尝试加载第三方assemblies 动态地到项目并使用reflection创建其类型的实例 I used Assembly LoadFrom Assembly1 dll Assembly LoadFrom Assembly2 dll
  • Json.dump 失败并显示“必须是 unicode,而不是 str”TypeError

    我有一个 json 文件 其中恰好有大量中文和日文 以及其他语言 字符 我将其加载到我的 python 2 7 脚本中使用io open如下 with io open multiIdName json encoding utf 8 as j
  • 使用 TCP 套接字在本地代理视频

    我一直对向媒体浏览器添加对视频播客的支持非常感兴趣 我希望用户能够浏览可用的视频播客并从互联网上流式传输它们 这真的很容易 因为媒体播放器等将愉快地播放存在于云中的文件 问题是我想在本地缓存这些文件 因此同一集的后续观看将不涉及流式传输 而
  • .NET 或 Windows 同步原语性能规范

    我目前正在写一篇科学文章 我需要非常准确地引用 有人可以向我指出 MSDN MSDN 文章 一些已发表的文章来源或一本书 我可以在其中找到 Windows 或 NET 同步原语的性能比较 我知道这些是按性能降序排列的 互锁 API 关键部分
  • 如何使用 .NET 捕获我的桌面视频?

    我想知道是否有任何方法可以使用 NET 捕获我的桌面的视频 截屏视频 我并不是在寻找截屏软件 而只是在寻找一种可以让我自己生成桌面视频的技术 我想过拍摄多个屏幕截图 但我不确定如何以编程方式生成带有图像序列的视频 有人有主意吗 Thanks
  • 使用生成的 Golang DLL 返回字符串或 *C.Char

    我一直在努力追随z505 goDLL https github com z505 goDLL回购并遇到了一个大问题 该方法无法返回字符串 我无法读取结果的输出变量 这是我到目前为止使用的代码 Go 完整代码https play golang
  • 该进程无法访问该文件,因为该文件正在被另一个进程使用

    当我从 bat 文件启动 net 控制台应用程序时 例如start myapp exe 然后 myapp exe 尝试将文件写入其当前目录 尽管我收到 net 运行时错误 声称该文件正在被另一个应用程序使用 没有其他应用程序在运行 http
  • 将新属性动态添加到 Node 中现有的 JSON 数组中

    我需要添加当前 JSON 中不存在的属性 json 对象如下所示 var jsonObj result OK data 我想在 数据 中添加温度 我可以像下面那样做 jsonObj data push temperature 然后 我想在
  • 使用 TFS API 在单个查询中检索工作项及其链接的工作项

    有谁知道是否可以检索工作项目及其列表链接的工作项使用 TFS API Web 服务从 TFS 进行一趟 目前 我们必须对第一次调用期间进行的每个工作项进行第二次调用 并且引入了性能问题 如果这不可能 是否有办法查看链接工作项的类型而不检索它
  • Node.js - 异步 JSON 查询

    如果这是一个愚蠢的问题 我深表歉意 但我对 Javascript 很陌生 而 Node js 确实让我很头疼 因为它是异步的 我的目标是从 API 查询 JSON 对象并能够使用它 我试图寻找关于我应该做什么的问题和答案 但它们对我来说都没
  • DateTime.Ticks 没有 100 ns 的分辨率? [复制]

    这个问题在这里已经有答案了 可能的重复 C DateTime Now 精度 https stackoverflow com questions 2143140 c sharp datetime now precision SO 有一些关于
  • 使用 TCP 时是否需要使用校验和来保护我的消息?

    使用 TCP 作为网络协议 在通过线路发送消息之前 我会为每条消息的大小 以及可能的校验和 添加前缀 我想知道 计算和传输消息的校验和是否有意义 以确保消息将被不变地传递 如果以及何时传递 例如因为一些网络错误 目前 我在发送消息本身之前发
  • 使用 HttpClient 从 webapi 消费 xml

    我使用 WebClient 从 Restfull 服务 net web api 获取 Xml 对象 一切都运行良好 using WebClient client new WebClient client Encoding UTF8Encod
  • 气流:如何将读取 json 文件的方法放入本地库中

    我必须产生一些DAG 我已将 json 表架构文件保存在GCP铲斗 https cloud google com storage docs json api v1 buckets GCP 存储桶上的文件关联到composer将被重新映射到
  • 远程服务器返回错误:NotFound。银光+WCF

    我正在尝试调用网络服务几个小时 我添加了 clientaccesspolicy xml
  • Web 服务调用后响应对象中的属性为 null

    我可以在 Fiddler 中看到该对象 但该对象在我这边没有反序列化 有没有人见过这个 响应为空 或 响应包含空值 或 请求为空 或 请求包含空值 几乎总是意味着命名空间不匹配 例如 响应可能包含
  • 如何在WebBrowser控件中注入Javascript?

    我试过这个 string newScript textBox1 Text HtmlElement head browserCtrl Document GetElementsByTagName head 0 HtmlElement scrip
  • 如何为 Jackson 编写一个包罗万象的(反)序列化器

    当您提前知道类型时 编写自定义序列化器非常容易 例如 MyType一个人可以写一个MyTypeSerializer extends StdSerializer
  • 窗体最大化时自动缩放子控件

    有没有办法在最大化屏幕或更改分辨率时使 Windows 窗体上的所有内容自动缩放 我发现手动缩放它是正确的 但是当切换分辨率时我每次都必须更改它 this AutoScaleDimensions new System Drawing Siz

随机推荐