Xml 是否有将结构对象编码为HTTP GET请求参数的标准语法?

Xml 是否有将结构对象编码为HTTP GET请求参数的标准语法?,xml,json,http,data-structures,Xml,Json,Http,Data Structures,假设我们需要向web应用程序传递大量结构化对象,例如,区域设置、布局设置和某个查询的定义。这可以通过类似于以下片段的JSON或XML轻松完成: <Locale>en</Locale> <Layout> <Block id="header">hide</Block> <Block id="footer">hide</Block> <Block id="navigation">

假设我们需要向web应用程序传递大量结构化对象,例如,区域设置、布局设置和某个查询的定义。这可以通过类似于以下片段的JSON或XML轻松完成:

<Locale>en</Locale>  
<Layout>  
  <Block id="header">hide</Block>  
  <Block id="footer">hide</Block>  
  <Block id="navigation">minimize</Block>  
</Layout>  
<Query>  
  <What>water</What>  
  <When>  
    <Start>2010-01-01</Start>  
  </When>  
</Query>
但我要找的是“标准”语法,如果有的话

另外,我当然知道URL长度的问题。请假设在这种情况下这不是问题

pps。我也很乐意提供指向键值对URL API(如)的链接,您认为这些链接值得一看


购买力平价。我们当然会查看回调URL,但我们也需要HTTP GET键值对。问题集中在后者。

这取决于你想如何解码它。如果您有一个专门知道如何沿着
&
=
(即PHP)分割参数和值的系统,那么您的解决方案就可以工作,但如果取消了该限制,那么它可以变得更加简洁:

Locale{en}Layout{Block(id:header){hide}Block(id:footer){hide}Block(id:navigation){minimize}}Query{What{water}When{Start{2010-01-01}}}

简言之,没有标准(据我所知),所以要根据自己的需要创造。您甚至可以使用JSON,根据需要省略或编码空白。

只有在您同时控制服务器和客户端,并且两者都可以通过网络相互访问的情况下,此想法才有效。

客户端:

调用服务器的客户端需要在HTTP-REQUEST的HTTP-HEADER中传递回调URL。URL还将具有唯一的id,示例请求可能如下所示

//HTTP Request Header

GET / HTTP/1.1[CRLF]
Host: www.your-server.com/server-end.aspx[CRLF]
Connection: close[CRLF]
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)[CRLF]
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7[CRLF]
Cache-Control: no[CRLF]
Accept-Language: de,en;q=0.7,en-us;q=0.3[CRLF]
Referer: some referrer[CRLF]
Input-callback-Url: www.your-client.com/inputprovider.aspx?requestid=xxxxxxx[CRLF]
[CRLF]
服务器端:

在服务器端点,服务器将从客户端读取Http请求的头,并读取“输入回调Url”中接收到的Url。然后,服务器将在www.your-client.com/inputprovider.aspx?requestid=xxxxxxx上初始化Http请求GET。服务器调用此URL时,将以JASON或XML形式呈现输出

<Locale>en</Locale>          
<Layout>          
  <Block id="header">hide</Block>          
  <Block id="footer">hide</Block>          
  <Block id="navigation">minimize</Block>          
</Layout>          
<Query>          
  <What>water</What>          
  <When>          
    <Start>2010-01-01</Start>          
  </When>          
</Query>
en
隐藏
隐藏
减少
水
2010-01-01          

服务器可以从“输入回调Url”接收此响应,并继续处理原始客户端请求。

我很好地理解您的问题。我喜欢XML和XMLSchema,多年来一直在使用。半年以来,我一直在使用JavaScript和jQuery以及RESTfull WFC服务、ASP.NET MVC技术和JSON编码的数据进行传输。所以不久前我不得不问我同样的问题。这是我的答案,并作了简短的解释

您定义的XML结构可以表示Web服务的一个输入参数。如果您喜欢将XML结构划分为不同的输入参数(如区域设置、布局和查询),那么我在这里写的所有内容都可以很容易地修改为这种参数编码

在我看来,最自然的方式是使用现成的工具实现。因此,让我们使用一个类似于
MyMethod
的方法和一个类型为
MyData
的输入参数
param
1(类似于
public int MyMethod(MyData param1)
)。类
MyData
表示XML结构中的所有数据。那么相应的HTTP GET请求应该如下所示

其中JsonEncodedData

%7B%22locale%22%3A%22en%22%2C%22layout%22%3A%5B%7B%22id%22%3A%22%2C%22value%22%3A%22id%22%7D%2C%7B%22id%22%3A%22footer%22%2C%22value%22%3A%22id%22%7D%2C%7B%22id%22%3A%22%22%22%22%2C%22%22%22%2C%22value%

或不带HTML编码的相同内容:

{“locale”:“en”,“layout”:[{“id”:“header”,“value”:“hide”},{“id”:“footer”,“value”:“hide”},{“id”:“navigation”,“value”:“minimize”}],“query”:{“what”:“water”,“when”:{“Start”:{“Year”:2010,“Month”:1,“Day”:1}}

此数据是一个JSON编码的JavaScript对象

var myInput = {
  locale: "en",
  layout:[
    {id: "header", value: "hide"},
    {id: "footer", value: "hide"},
    {id: "navigation", value: "minimize"}
  ],
  query:{
    what: "water",
    when: {
      Start:{Year:2010,Month:1,Day:1}
    }
  }
};
备注:因为JavaScript类的
日期
可以以稍微不同的方式序列化,所以我在这里稍微更改了开始日期的表示形式。在“Microsoft world”中我们可以使用
Sys.Serialization.JavaScriptSerializer.serialize
来序列化
DateTime
.NET类型,该类型将像“/Date(1262300400000)/”一样编码2010-01-01

我们可以用C#编写一个简单的Web方法,类似于Web服务Service1.asmx

[WebMethod]
[ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public int MyMethod (MyData param1) {
    return param1.query.when.Start.Year;
}
在哪里

对于示例json2.js中使用的JSON编码(请参阅和)。可以使用JSON jQuery(from),然后将
JSON.stringify
替换为
$.toJSON

初始化
MyData
类型的数据如下所示

new MyData {
        locale = "en",
        layout = new List<Block> {
            new Block() { id="header", value=BlockType.hide.ToString()},
            new Block() { id="footer", value=BlockType.hide.ToString()},
            new Block() { id="navigation", value=BlockType.minimize.ToString()}
        },
        query = new Query {
            what = "water",
            //when = new When() {Start = new DateTime(2010,1,1)}
            when = new When () {
                Start = new MyDate () {
                    Year = 2010,
                    Month = 1,
                    Day = 1
                }
            }
        }
    };
}
newmydata{
locale=“en”,
布局=新列表{
new Block(){id=“header”,value=BlockType.hide.ToString()},
new Block(){id=“footer”,value=BlockType.hide.ToString()},
new Block(){id=“navigation”,value=BlockType.minimize.ToString()}
},
查询=新查询{
什么=“水”,
//when=newwhen(){Start=new DateTime(2010,1,1)}
when=新的when(){
开始=新的MyDate(){
年份=2010年,
月份=1,
天=1
}
}
}
};
}
如果将WCF与webHttpBinding(RESTfull端点)一起使用,而不是使用基于asmx的web服务,则可以获得更灵活的解决方案

如果将JSON与HTTP GET一起使用,您应该考虑JSON劫持问题的存在(请参阅)。这个问题可以用不同的方法来解决(或大大减少),但这并不会阻止我在HTTP请求中使用JSON,它可以完美地缓存

有关同一主题的更多信息,您可以查看我对一系列问题的回答:
在URI中编码数据的标准方法是
application/x-www-form-urlencoded
。大多数ap
public enum BlockType {
    hide,
    minimize
}
public class Block {
    public string id { get; set; }
    //public BlockType value { get; set; }
    public string value { get; set; }
}
public class MyDate {
    public int Year { get; set; }
    public int Month { get; set; }
    public int Day { get; set; }
}
public class When {
    public MyDate Start { get; set; }
}
public class Query {
    public string what { get; set; }
    public When when { get; set; }
}
public class MyData {
    public string locale;
    public List<Block> layout;
    public Query query;
}
var myInput = {
  locale: "en",
  layout:[
    {id: "header", value: "hide"},
    {id: "footer", value: "hide"},
    {id: "navigation", value: "minimize"}
  ],
  query:{
    what: "water",
    when: {
      Start:{Year:2010,Month:1,Day:1}
    }
  }
};

$.ajax({
    type: "GET",
    url: "/Service1.asmx/Method2",
    data: {param1: JSON.stringify(myInput)},
    contentType: "application/json; charset=utf-8",
    success: function(data, textStatus, XMLHttpRequest) {
        alert(XMLHttpRequest.responseText);
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties:
            //      ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});
new MyData {
        locale = "en",
        layout = new List<Block> {
            new Block() { id="header", value=BlockType.hide.ToString()},
            new Block() { id="footer", value=BlockType.hide.ToString()},
            new Block() { id="navigation", value=BlockType.minimize.ToString()}
        },
        query = new Query {
            what = "water",
            //when = new When() {Start = new DateTime(2010,1,1)}
            when = new When () {
                Start = new MyDate () {
                    Year = 2010,
                    Month = 1,
                    Day = 1
                }
            }
        }
    };
}
Locale=en&
Layout[Block][header]=hide&
Layout[Block][footer]=hide&
Layout[Block][navigation]=minimize&
Query[What]=water&
Query[When][Start]=2010-01-01