.NET ASMX - 回归纯粹的JSON? [英] .NET ASMX - Returning Pure JSON?

查看:244
本文介绍了.NET ASMX - 回归纯粹的JSON?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要疯了这里。我看着下面的条目,其中的被纠正异常行为我看到:

I am going nuts here. I've looked at the following entries and none of them are correcting the aberrant behavior I am seeing:

  • <一个href="http://stackoverflow.com/questions/288850/how-to-return-json-from-a-2-0-asmx-web-service">http://stackoverflow.com/questions/288850/how-to-return-json-from-a-2-0-asmx-web-service
  • <一个href="http://stackoverflow.com/questions/1678101/how-to-return-json-from-asp-net-asmx">http://stackoverflow.com/questions/1678101/how-to-return-json-from-asp-net-asmx
  • <一个href="http://stackoverflow.com/questions/211348/how-to-let-an-asmx-file-output-json">http://stackoverflow.com/questions/211348/how-to-let-an-asmx-file-output-json
  • http://stackoverflow.com/questions/288850/how-to-return-json-from-a-2-0-asmx-web-service
  • http://stackoverflow.com/questions/1678101/how-to-return-json-from-asp-net-asmx
  • http://stackoverflow.com/questions/211348/how-to-let-an-asmx-file-output-json

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

I've also looked at, and confirmed my setup: http://www.asp.net/AJAX/documentation/live/ConfiguringASPNETAJAX.aspx

下面是我的code(ASMX code后):

Here is my code (ASMX code behind):

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;
        }
    }

当我运行这个从我的本地实例中,我得到这个结果集:

When I run this from my localhost instance I am getting this result set:

  <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>

我在想什么???

What am I missing???


注:我使用的是3.5架构(或至少我认为我是因为一切都在我的web.config文件被标记为3.5.0.0)

NOTE: I am using the 3.5 framework (or at least I thought I was as everything in my web.config is marked for 3.5.0.0)


更新:我浏览到服务,并使用输入框的页面上。你可以试一下: http://dev.rivworks.com/services/Negotiate。 ASMX?OP = GetSetup 。我们也试图从一个JS基于Web的应用程序运行的访问在另一个网站(这项服务的主要目的)。我没有$ C $下这里。 (对不起,测试窗体只能从本地主机。)

UPDATE: I am browsing to the service and using the input box on that page. You can try here: http://dev.rivworks.com/services/Negotiate.asmx?op=GetSetup. We are also trying to access it from a JS based web app running on another site (the main purpose of this particular service). I do not have the code for that here. (Sorry, the test form is only available from localhost.)


更新:我添加了以下测试页(JsonTest.htm)试试,看看发生了什么事情来回。我得到的是一个500错误!我甚至尝试连接到该进程,并闯入我的服务。 500引发错误前的ASP管道不断进入我的code。

UPDATE: I added the following test page (JsonTest.htm) to try to see what was going back and forth. All I get is a 500 error! I even tried attaching to the process and break into my service. THe 500 error is thrown before the ASP pipeline ever gets into my code.

<!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>

为什么会这样痛苦难?!?! :)

Why is this so painfully hard?!?! :)


更新:通过WCF服务工作。下面是我的设置: 接口:

UPDATE: Working through a WCF service. Here is my setup: Interface:

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);
    }
}

类:

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 = "";
    }
}

的web.config

  <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,无名氏,但结合仅支持标准只有一个认证方案。有效的身份验证方案是摘要,协商,NTLM,基本或匿名。更改IIS设置,以便只有一个认证方案中使用。

And now I am getting this error: IIS specified authentication schemes 'IntegratedWindowsAuthentication, Anonymous', but the binding only supports specification of exactly one authentication scheme. Valid authentication schemes are Digest, Negotiate, NTLM, Basic, or Anonymous. Change the IIS settings so that only a single authentication scheme is used.

我要如何处理呢? &LT;国家情感='拧干的身体='痛殴'/&GT;

How do I handle this? <state emotion='wrung out' physical='beat up' />

推荐答案

你为什么不迁移ASMX web服务的WCF?

在.NET框架3.5的WCF API支持JSON Web服务本身。

The WCF API in .NET Framework 3.5 supports JSON web services natively.

另外微软宣布ASMX为传统技术,并提出Web服务和XML Web服务客户端现在应该使用Windows通信基础(WCF)创建。 (来源)。

In addition Microsoft declared ASMX as "legacy technology", and suggests "Web services and XML Web service clients should now be created using Windows Communication Foundation (WCF)". (Source).

您可能要检查这些链接即可开始使用:

You may want to check out these links to get started:

  • JSON-Enabled WCF Services in ASP.NET 3.5
  • REST Service with WCF and JSON
  • Creating a JSON Service with WebGet and WCF 3.5
  • Microsoft WCF REST Starter Kit
  • Hosting and Consuming WCF Services

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

In addition, you may also want to read through the following example which I "extracted" from a self-hosted WCF project of mine. Self-hosted WCF services do not require IIS, but can be served from any managed .NET application. This example is being hosted in a very simple C# Console Application:

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);
    }
}

的Service.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 (控制台应用程序)

WCFHost.cs (Console Application)

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();
        }
    }
}

的app.config

<?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>

上面的例子是非常基本的。如果你用提琴手的请求 http://127.0.0.1:8000/ API /客户名称/ 1000 将简单的返回客户名称:1000。

确认设定内容类型:应用程序/ JSON 的请求头。要返回更复杂的数据结构,你将不得不使用数据合同。这些被构造如下:

Make sure to set the content-type: application/json in the request header. To return more complex data structures, you will have to use Data Contracts. These are constructed as follows:

[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 System.ServiceModel.Web 在这个例子中的项目进行编译。

You need to add .NET References to System.RuntimeSerialization, System.ServiceModel and System.ServiceModel.Web for this example project to compile.

这篇关于.NET ASMX - 回归纯粹的JSON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆