Ярлыки

.Net (17) (9) 1с8 (4) 1с8.2 УП (3) документирование (1) интеграция (10) карта (1) собеседование (1) ado (1) ajax (11) ASP (1) asp.net (10) authentication (1) c# (14) coding (2) Crm Ribbon (2) csv (1) datareader (1) delegate (5) dhtml (5) exam (1) excel (10) ext (1) extjs (8) google maps (1) iis (3) javascript (33) JSON (5) linq (1) LN (5) log (1) lotus notes (5) mail (1) MS CRM (63) MS CRM 2015 (3) MS CRM 5 (48) MS CRM 6 (28) ms office (2) msi (1) MVC (1) namespace (1) oData (3) outlook (1) parent-child (2) plugin (1) program (4) Project Management (1) remote debugger (1) REST (1) SharePoint (1) SharePoint 2010 (2) Silverlight (2) soft (1) sql (13) sql reporting service (8) sql2005 (3) ssrs (2) Thread (4) tree (1) vb (6) vba (1) VSTO (1) WCF (4) wmi (1) wsc (2) xml (1) Xrm.Page (1) xslt (1)

среда, 13 января 2010 г.

AJAX: REST Webservice и сериализация JSON

Для применения AJAX удобна сериализация JSON. А REST сервисы проще SOAP (как бы традиционных).
В общем, от совместного использования обоих Ajax становится проще. А в минусы - не будет автоматической генерации прокси классов под такие сервисы.

1. REST service (для net framework 3.5)
<%@ WebHandler Language="C#" Class="WebServiceRestJsonHandler" %>

using System;
using System.Web;
using System.Web.Script.Serialization; //from System.Web.Extensions.dll

[Serializable]
public class account
{
    public string name;
    public int age;
    public string fname;
    public account reports;
}

public class WebServiceRestJsonHandler : IHttpHandler 
{
    public void ProcessRequest (HttpContext context) 
    {
        context.Response.ContentType = "text/plain";
        JavaScriptSerializer js = new JavaScriptSerializer();
        
        switch (context.Request.QueryString["oper"].ToLower())
        {
            case "accountinfo":
                account a = GetAccInfo(context.Request.QueryString["who"]);
                context.Response.Write(js.Serialize(a));
                //account a1 = js.Deserialize<account>(js.Serialize(a)); // пример 
                break;
        }
    }

    account GetAccInfo(string who)
    {
        account a = new account();
        account ar = new account();
        ar.fname = "другие";
        a.name = who;
        a.age = 36;
        a.reports = ar;
        return (a);
    }
    
    public bool IsReusable {
        get {
            return false;
        }
    }
}

2. web.config (минимальный)
<?xml version="1.0"?>
<configuration>
 <configSections/>
 <appSettings/>
 <connectionStrings/>
 <system.web>
  <compilation debug="true">
   <assemblies>
    <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
   </assemblies>
  </compilation>
  <authentication mode="Windows"/>
 </system.web>
</configuration>

3. Пример использования
<html>
<head>
    <title>Тест WebServiceRestJsonHandler</title>
    <script>
        function a() {
            var xhr = new ActiveXObject('Msxml2.XMLHTTP'); // for IE
            var account;
            xhr.open('GET', 'WebServiceRestJsonHandler.ashx?oper=accountinfo&who=' + param.value, false);
            xhr.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');

            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    if (xhr.status == 200) {
                        taOut.value += "responseText: " + xhr.responseText+"\r\n\r\n";
                        account = eval('(' + xhr.responseText + ')');
                        taOut.value += "account.reports.fname: " + account.reports.fname;
                    }
                }
            };
            xhr.send(null);
        }
    </script>
</head>
<body>
Параметр: <input type=text value="ANTON" id="param" /> 
<input type=button value="Test" onclick="a();" />
<p>
<textarea rows="8" style="width:400px" id="taOut"></textarea>
</body>
</html>

Полезные ссылки:
JSON in ASP.NET Ajax: Part 2. Calling a remote JSON Web Service from client script
Клиентский вызов веб-служб средствами AJAX Extensions


Еще на эту тематику...
В ASP.Net вебсервисы можно вызывать с удаленных машин не только по SOAP, но и традиционными GET & POST. Для включения этой возможности в web.config надо указать

<system.web>
  <webServices>
   <protocols>
    <add name="HttpGet"/>
    <add name="HttpPost"/>
   </protocols>
  </webServices>
...
...
</system.web>

Тогда по GET можно использовать ссылку вида http://servername/myservice.asmx/WebMethodName?Param1=xxx&Param2=yyy
а для POST примерно такой jscript код
var serverUrl = "http://servername/myservice.asmx/WebMethodName";
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("post", "http://servername/myservice.asmx/WebMethodName", false);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send("Param1=xxx&Param2=yyy");
var sS = xmlhttp.responseXML.xml; // ответ сервера, например <string xmlns="http://tempuri.org/">01.02.2011</string>
...

Для Basic или VBA вызов надо делать примерно так

Set xmlHttp = CreateObject("Microsoft.XMLHTTP")
xmlHttp.Open "POST", "http://servername/myservice.asmx/WebMethodName", False
xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
'ввиду способа отправки наличие символа '&' в строке недопустимо
'поэтому надо следить, чтобы xxx и yyy не содержат '&'
sendStr = "Param1=xxx&Param2=yyy"
xmlHttp.setRequestHeader "Content-Length", Len(sendStr)
xmlHttp.send sendStr

Do While xmlHttp.readyState <> 4
    DoEvents
Loop

Есть также готовые решения для вывода вебметода в формат JSON
...
//одно из
//using System.Web.Extensions; // from Net Framework 3.5 System.Web.Extensions.dll
//using Microsoft.Web.Script.Services; // from http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ca9d90fa-e8c9-42e3-aa19-08e2c027f5d6&displaylang=en for Net Framework 2.0

namespace MsdnMagazine
{
    [WebService(Namespace = "http://msdnmagazine.com/ws")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ScriptService]
    public class StockQuoteService : WebService
    {
        static Random _rand = new Random(Environment.TickCount);

        [WebMethod]
        public int GetStockQuote(string symbol)
        {
            return _rand.Next(0, 120);
        }
    }
}


Ссылки
ASP.NET AJAX 1.0 download
Client-Side Web Service Calls with AJAX Extensions (как пользоваться ASP.NET AJAX 1.0)
Тоже, только уже встроенное в Framework 3.5
SOAP и REST, обзор

годный пример с MSDN как управлять форматом ответа внутри службы с помощью атрибутов ScriptService и ScriptMethod

Вот пример как использовать JSON от служб ASMX для ExtJs (Framework 3.5)

web.config

...
<system.web>
 ...
 <httpHandlers>
  <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>
 <httpModules>
  <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
 </httpModules>
</system.web>
...

ASMX

<%@ WebService Language="C#" Class="test" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

public class client
{
    public string Name;
    public int Age;
}

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

    [WebMethod]
    public client HelloWorld(string Name) {
        client c = new client();
        c.Age = 38;
        c.Name = Name;
        return c;
    }
}

javascript ExtJs

Ext.Ajax.request({
 url : '/test.asmx/HelloWorld',
 headers: {
  'Content-Type': 'application/json; charset=utf-8'
 }, 
 success : function(response, opts) {
  var obj = Ext.decode(response.responseText);
  Ext.MessageBox.alert ('',obj.d.Name+'<br/>'+obj.d.Age);
 },
  failure : function(r,o){
  debugger;
  },
 method : 'POST', // get нельзя без дополнительной модификации web.config
 jsonData  : {'Name':'Kaban'} // params тут не пройдет
});

jQuery как то так:

$.ajax({
    type: "POST",
    url: "/test.asmx/HelloWorld", 
    data: "{ Name: \"Kaban\" }", // jQuery требует в строке
    dataType: "json",
    headers: {'Content-Type': 'application/json; charset=utf-8'},
    success: parseGetOtc,
    error: errHelpXML
});  //end ajax

function parseGetOtc(data) {
    alert(data.d);
}
function errHelpXML(jqXHR, textStatus, errorThrown) {
    alert(textStatus + "\r\n" + errorThrown);
    debugger;
}

а такой функцией я пользуюсь для синхронного вызова

syncJax = function (url) {
    var oXmlHttp = CreateXmlHttp(); // реализация ниже 
    oXmlHttp.open('GET', url, false); // синхронно
    oXmlHttp.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');
    oXmlHttp.setRequestHeader('Cache-Control', 'no-cache'); // не кешировать
    oXmlHttp.setRequestHeader('Pragma', 'no-cache'); // не кешировать
    oXmlHttp.setRequestHeader("If-Modified-Since", "Sat, 01 Jan 2000 00:00:00 GMT");
    var oo;
    oXmlHttp.onreadystatechange = function () {
        if (oXmlHttp.readyState == 4) {
            if (oXmlHttp.status == 200) {
                oo = eval('(' + oXmlHttp.responseText + ')');
            }
        }
    }
    oXmlHttp.send(null);
    return (oo);
}

CreateXmlHttp = function () {
    var oXmlHttp = null;
    if (window.XMLHttpRequest) {
        oXmlHttp = new XMLHttpRequest();
    }
    else {
        var arrProgIds = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
        for (var iCount = 0; iCount < arrProgIds.length; iCount++) {
            try {
                oXmlHttp = new ActiveXObject(arrProgIds[iCount]);
                break;
            }
            catch (e) { }
        }
    }
    return oXmlHttp;
}

Тут видно какие заголовки использовать и как передавать (POST) параметры для xml и для json при вызове метода вебслужбы asmx

<!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></title>
    <script language=javascript>
        function CreateXmlHttp() {
            var oXmlHttp = null;
            if (window.XMLHttpRequest) {
                oXmlHttp = new XMLHttpRequest();
            }
            else {
                var arrProgIds = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
                for (var iCount = 0; iCount < arrProgIds.length; iCount++) {
                    try {
                        oXmlHttp = new ActiveXObject(arrProgIds[iCount]);
                        break;
                    }
                    catch (e) { }
                }
            }
            return oXmlHttp;
        }

        function syncJax(url,jx) {
            var oXmlHttp = CreateXmlHttp();
            oXmlHttp.open('POST', url, false);
            if (jx == 'json')
                oXmlHttp.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
            else
                oXmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
            oXmlHttp.setRequestHeader('Cache-Control', 'no-cache');
            oXmlHttp.setRequestHeader('Pragma', 'no-cache');
            oXmlHttp.setRequestHeader("If-Modified-Since", "Sat, 01 Jan 2000 00:00:00 GMT");
            
            var oo;
            oXmlHttp.onreadystatechange = function() {
                if (oXmlHttp.readyState == 4) {
                    if (oXmlHttp.status == 200) {
                        oo = oXmlHttp.responseText;
                        //oo = eval('(' + oXmlHttp.responseText + ')');
                    }
                }
            }
            if (jx == 'json')
                oXmlHttp.send('{Name:"Kaban"}');
            else
                oXmlHttp.send('Name=Kaban');
            return (oo);
        }

        String.prototype.escapeHTML = function() {
            return (
            this.replace(/&/g, '&amp;').
                replace(/>/g, '&gt;').
                replace(/</g, '&lt;').
                replace(/"/g, '&quot;'));
        }
        
        function getServerData() {
            var jx = jsonOrXml[0].checked ? jsonOrXml[0].value : jsonOrXml[1].value;
            outDiv.innerHTML = syncJax("/ISV/funcs/ws.asmx/HelloWorld", jx).escapeHTML();
        }
    </script>
</head>
<body>
<div><input type=radio name=jsonOrXml value=json checked />json
<br/><input type=radio name=jsonOrXml value=xml />xml
</div>
<input type=button value="test" onclick="getServerData();" /><p/>
<textarea id="outDiv" style="width:600px" rows=6>

</textarea>
</body>
</html>


А здесь пример AJAX с WCF

WCF служба ProductService.svc

<%@ ServiceHost Factory="System.ServiceModel.Activation.WebServiceHostFactory"
Language="C#" Debug="true" Service="ProductService" %>
/*
 * Factory="System.ServiceModel.Activation.WebServiceHostFactory"
 * позволяет обходиться без конфигурации, обеспечивает простую сериализацию вывода в JSON.
 * Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"
 * также можно использовать без конфигурации. Но при этом будет другой вид сериализации вывода в JSON.
 * ************************
 * другой вид значит, что основной результат будет заключен в ключ d Пример:
 * {"d":{"type":"oldmobile","age":45}}
 * ************************
 * с точки зрения кроссдоменности и разнобраузерности :) лучше пользовать WebScriptServiceHostFactory
 */

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

[DataContract]
public class Product
{
    [DataMember]
    public int pid { get; set; }
    [DataMember]
    public string name { get; set; }
    [DataMember]
    public string dsc { get; set; }
}



[ServiceContract(Namespace="http://test.org")]
// если использовать с микрософтовским AJAX (также нужен WebScriptServiceHostFactory)
//[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
public class ProductService
{
    [WebInvoke(Method = "POST"
        , BodyStyle = WebMessageBodyStyle.WrappedRequest
        , ResponseFormat = WebMessageFormat.Json
        , UriTemplate = "/GetProduct/{id}"
    )]
    public Product GetProduct(string id, string message)
    {
        Product p = new Product { pid = int.Parse(id), name = "tomato", dsc = new Random().Next(1, 2000).ToString() + " " + message };
        return (p);
    }

    [WebGet(BodyStyle = WebMessageBodyStyle.WrappedRequest
        , ResponseFormat = WebMessageFormat.Json
        , UriTemplate = "/GetProductGet/{id}"
    )]
    [OperationContract(Name = "GetProductGet")]
    public Product GetProduct(string id)
    {
        Product p = new Product { pid = int.Parse(id), name = "tomato", dsc = new Random().Next(1, 2000).ToString() };
        return (p);
    }

    [WebInvoke(Method = "POST"
        , BodyStyle = WebMessageBodyStyle.WrappedRequest
        , ResponseFormat = WebMessageFormat.Json
    )]
    public Product SetProduct(string id, Product product)
    {
        // с помощью WebOperationContext.Current можно задать любой формат вывода
        Product p = new Product { pid = int.Parse(id), name = product.name, dsc = product.dsc };
        return (p);
    }
}

Также тип json можно указать как основной в конфиге

      <endpointBehaviors>
      <behavior name="ServicesJSONEndpointBehavior">
        <webHttp defaultOutgoingResponseFormat="Json"/>
      </behavior>
      </endpointBehaviors>

Тестовая HTML страница

<html>
<head>
    <title></title>
    <script language=javascript>
        function CreateXmlHttp() {
            var oXmlHttp = null;
            if (window.XMLHttpRequest) {
                oXmlHttp = new XMLHttpRequest();
            }
            else {
                var arrProgIds = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
                for (var iCount = 0; iCount < arrProgIds.length; iCount++) {
                    try {
                        oXmlHttp = new ActiveXObject(arrProgIds[iCount]);
                        break;
                    }
                    catch (e) { }
                }
            }
            return oXmlHttp;
        }

        function syncJax(url, param, method) {
            var oXmlHttp = CreateXmlHttp();
            if (method == undefined || method == null) method = "POST";
            method = method.toUpperCase();
            if (method != "GET") method = "POST";
            oXmlHttp.open(method, url, false);
            oXmlHttp.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
            oXmlHttp.setRequestHeader('Cache-Control', 'no-cache');
            oXmlHttp.setRequestHeader('Pragma', 'no-cache');
            oXmlHttp.setRequestHeader("If-Modified-Since", "Sat, 01 Jan 2000 00:00:00 GMT");

            var oo;
            oXmlHttp.onreadystatechange = function () {
                if (oXmlHttp.readyState == 4) {
                    if (oXmlHttp.status == 200) {
                        oo = oXmlHttp.responseText;
                        //oo = eval('(' + oXmlHttp.responseText + ')');
                    }
                }
            }
            //необхожима сериализация параметра в строку
            param == null ? oXmlHttp.send() : oXmlHttp.send(param.toString());
            return (oo);
        }

        String.prototype.escapeHTML = function () {
            return (
            this.replace(/&/g, '&amp;').
                replace(/>/g, '&gt;').
                replace(/</g, '&lt;').
                replace(/"/g, '&quot;'));
        }

        // hash в строку
        Object.prototype.toString = function () {
            var parse = function (_o) {
                var a = [], t;
                for (var p in _o) {
                    if (_o.hasOwnProperty(p)) {
                        t = _o[p];
                        if (t && typeof t == "object") {
                            a[a.length] = "\""+p+"\"" + ":{ " + arguments.callee(t).join(", ") + "}";
                        }
                        else {
                            if (typeof t == "string") {
                                a[a.length] = ["\"" + p + "\"" + ": \"" + t.toString() + "\""];
                            }
                            else {
                                a[a.length] = ["\"" + p + "\"" + ": " + t.toString()];
                            }
                        }
                    }
                }
                return a;
            }
            return "{" + parse(this).join(", ") + "}";
        }

        function getProductGet() {
            // только GET в UriTemplate = "/GetProductGet/{id}"
            getProductGetDiv.innerHTML = syncJax("ProductService.svc/GetProductGet/55",
            null, "GET").escapeHTML();
        }

        function getProduct() {
            // только POST в UriTemplate = "/GetProduct/{id}", с параметром
            getProductDiv.innerHTML = syncJax("ProductService.svc/GetProduct/77",
            '{"message":"I love you!"}'
            ).escapeHTML();
        }

        function setProduct() {
            // только POST без UriTemplate, со сложным параметром
            setProductDiv.innerHTML = syncJax("ProductService.svc/SetProduct",
            { "id": 44, "product": { "dsc": "etc", "name": "apple", "pid": 8} }
            ).escapeHTML();
        }

    </script>
</head>
<body>
<div>
    <input type=button value="getProductGet" onclick="getProductGet();" style="width:100" />
    <textarea id="getProductGetDiv" style="width:500px" rows=2> </textarea><p/>
    <input type=button value="getProduct" onclick="getProduct();" style="width:100" />
    <textarea id="getProductDiv" style="width:500px" rows=2> </textarea><p/>
    <input type=button value="setProduct" onclick="setProduct();" style="width:100" />
    <textarea id="setProductDiv" style="width:500px" rows=2> </textarea><p/>
</body>
</html>

По-моему, лучшим способом является ASP MVC. Вот пример использования
1. в VS 2010 с установленным MVC 2-ой или 3-ей версии создать новый пустой проект ASP NET MVC Web Application

2. Создать файлы в папках ProductModels.cs, ProductController.cs, Product.cshtml, ProductMvc-TestSimpleAjaxt.htm

ProductModels.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication2.Models
{

    public class ProductModel
    {
        public int pid { get; set; }
        public string name { get; set; }
        public string dsc { get; set; }
    }

    public class ProductActionsModel
    {
        public List<ProductModel> GetProducts()
        {
            List<ProductModel> pq = new List<ProductModel>();
            ProductModel p = new ProductModel() { pid = 1, name = "tomato", dsc = "" };
            pq.Add(p);
            p = new ProductModel() { pid = 2, name = "apple", dsc = "" };
            pq.Add(p);
            p = new ProductModel() { pid = 3, name = "lemon", dsc = "" };
            pq.Add(p);
            return (pq);
        }

        public ProductModel GetProduct(int pid)
        {
            return (GetProducts().SingleOrDefault(n => n.pid == pid));
        }

        public bool AddNewProduct(ProductModel p)
        {
            p.pid = 4;
            //CRUD.Create(p);
            return true;
        }
    }
}

ProductController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using MvcApplication2.Models;

namespace MvcApplication2.Controllers
{
    public class ProductController : Controller
    {
        // GET: /Product/
        public ActionResult Index()
        {
            ProductActionsModel pm = new ProductActionsModel();
            ViewBag.AllProducts = pm.GetProducts();
            return View("Product");
        }
        // GET: /AllProducts/
        [HttpGet]
        public JsonResult AllProducts()
        {
            ProductActionsModel pm = new ProductActionsModel();
            return (Json(pm.GetProducts(), JsonRequestBehavior.AllowGet));
        }
        // GET: /Product/Details/5
        public JsonResult Details(int id)
        {
            ProductActionsModel pm = new ProductActionsModel();
            return (Json(pm.GetProduct(id), JsonRequestBehavior.AllowGet));
        }
        // POST: /Product/Create
        [HttpPost]
        public JsonResult Create(ProductModel p)
        {
            ProductActionsModel pm = new ProductActionsModel();
            return (Json(pm.AddNewProduct(p)));
        } 
    }
}

Product.cshtml

@{
    ViewBag.Title = "product";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>products</h2>
<table border=1><thead>
<tr><th>ID</th><th>NAME</th><th>DESCR</th></tr></thead>
@foreach (var item in ViewBag.AllProducts)
{
    <tr><td>@item.pid</td><td>@item.name</td><td>@item.dsc</td></tr>
}
</table>

ProductMvc-TestSimpleAjaxt.htm

<html>
<head>
    <title></title>
    <script language=javascript>
        function CreateXmlHttp() {
            var oXmlHttp = null;
            if (window.XMLHttpRequest) {
                oXmlHttp = new XMLHttpRequest();
            }
            else {
                var arrProgIds = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
                for (var iCount = 0; iCount < arrProgIds.length; iCount++) {
                    try {
                        oXmlHttp = new ActiveXObject(arrProgIds[iCount]);
                        break;
                    }
                    catch (e) { }
                }
            }
            return oXmlHttp;
        }

        function syncJax(url, param, method) {
            var oXmlHttp = CreateXmlHttp();
            if (method == undefined || method == null) method = "POST";
            method = method.toUpperCase();
            if (method != "GET") method = "POST";
            oXmlHttp.open(method, url, false);
            oXmlHttp.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
            oXmlHttp.setRequestHeader('Cache-Control', 'no-cache');
            oXmlHttp.setRequestHeader('Pragma', 'no-cache');
            oXmlHttp.setRequestHeader("If-Modified-Since", "Sat, 01 Jan 2000 00:00:00 GMT");

            var oo;
            oXmlHttp.onreadystatechange = function () {
                if (oXmlHttp.readyState == 4) {
                    if (oXmlHttp.status == 200) {
                        oo = oXmlHttp.responseText;
                        //oo = eval('(' + oXmlHttp.responseText + ')');
                    }
                }
            }
            //необходима сериализация параметра в строку
            param == null ? oXmlHttp.send() : oXmlHttp.send(param.toString());
            return (oo);
        }

        String.prototype.escapeHTML = function () {
            return (
            this.replace(/&/g, '&amp;').
                replace(/>/g, '&gt;').
                replace(/</g, '&lt;').
                replace(/"/g, '&quot;'));
        }

        // hash в строку
        Object.prototype.toString = function () {
            var parse = function (_o) {
                var a = [], t;
                for (var p in _o) {
                    if (_o.hasOwnProperty(p)) {
                        t = _o[p];
                        if (t && typeof t == "object") {
                            a[a.length] = "\"" + p + "\"" + ":{ " + arguments.callee(t).join(", ") + "}";
                        }
                        else {
                            if (typeof t == "string") {
                                a[a.length] = ["\"" + p + "\"" + ": \"" + t.toString() + "\""];
                            }
                            else {
                                a[a.length] = ["\"" + p + "\"" + ": " + t.toString()];
                            }
                        }
                    }
                }
                return a;
            }
            return "{" + parse(this).join(", ") + "}";
        }

        function getProducts() {
            getProductGetDiv.innerHTML = syncJax("/Product/AllProducts",
            null, "GET").escapeHTML();
        }

        function getProduct() {
            getProductDiv.innerHTML = syncJax("/Product/Details/2",
            null
            ).escapeHTML();
        }

        function setProduct() {
            setProductDiv.innerHTML = syncJax("/Product/Create",
            { "dsc": "etc", "name": "apple", "pid": "null" } 
            ).escapeHTML();
        }

    </script>
</head><body><div>
    <input type=button value="getProducts" onclick="getProducts();" style="width:100" />
    <textarea id="getProductGetDiv" style="width:500px" rows=3 cols=40> </textarea><p/>
    <input type=button value="getProduct" onclick="getProduct();" style="width:100" />
    <textarea id="getProductDiv" style="width:500px" rows=1 cols=40> </textarea><p/>
    <input type=button value="setProduct" onclick="setProduct();" style="width:100" />
    <textarea id="setProductDiv" style="width:500px" rows=1 cols=40> </textarea><p/>
</div></body></html>

Вот что получится в результате


PS
в заметке рассмотрены основные способы (для технологий Microsoft) получения JSON от сервера. заметка охватывает период с 2003 года по 2011.

Комментариев нет: