青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

huangyi5209

  C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  0 Posts :: 13 Stories :: 0 Comments :: 0 Trackbacks

常用鏈接

留言簿

我參與的團隊

搜索

  •  

最新評論

Sunday, October 10, 2010

Passing a JSON array to a WCF service

While the following information is available on the Internet, I had to piece it together from various sources, so for my own documentation and hopefully to help someone else, here is a simple (I hope) example of passing a JSON array to a WCF service, all in one place. It can be easily generalized to passing any JSON-serialized object to WCF, but that is better documented than arrays.

Note: This sample uses jQuery and Douglas Crockford’s JSON2. It also uses some features of HTML 5, including placeholder text, autofocus fields and offline storage, but these aren’t essential for the solution.

First, let’s look at the HTML, because it’s probably the simplest part of the solution:

index.html

<!DOCTYPE html>

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <link rel="stylesheet" href="styles/branding.css" />

    <title>Send Array to WCF Service</title>

</head>

<body>

    <div id="content">

        <h3>User</h3>

        <form id="demographics_form">

            <span>Last Name: </span>

            <input id="last_name" name="last_name" type="text" placeholder="Last name" autofocus required />

            <br />

            <span>First Name: </span>

            <input id="first_name" name="first_name" type="text" placeholder="First name" />

            <br />

            <span>Email: </span>

            <input id="email_address" name="email_address" type="email" placeholder="someone@somewhere.com" />

            <br />

            <input id="save_button" type="button" value="Save" />

        </form>

    </div>

    <p id="app_status">

    </p>

    <script src="scripts/json2.js" type="text/ecmascript"></script>

    <script src="scripts/jquery-1.4.2.min.js" type="text/ecmascript"></script>

    <script src="scripts/main.js" type="text/ecmascript"></script>

</body>

</html>

Pretty much a simple form with three fields and a button. Pay attention to the input elements name attributes – we will be using those in various places. Note that the form doesn’t have action or method attributes. We will assign an event handler to the button in a bit. There is also a p element with an id of app_status which will be used to display status messages.

With that out of the way, let’s look at the JavaScript:

main.js

var UserApp = {

    docReady: function () {

        UserApp.loadForm();

        $("#save_button").bind("click", UserApp.sendFormData);

    },

 

    // Load form from saved data. Presumes that each input element's id is the same as its name.

    loadForm: function () {

        var formDataString = localStorage.getItem("user_data");

 

        if (formDataString) {

            var formData = JSON.parse(formDataString);

 

            for (var i in formData) {

                var fieldId = "#" + formData[i].name;

                $(fieldId).val(formData[i].value);

            }

        }

    },

 

    // Save data from a form. Presumes there is only one form element on a page.

    saveFormData: function () {

        var formData = $("form").serializeArray();

 

        localStorage.setItem("user_data", JSON.stringify(formData));

        return { nvps: formData };

    },

 

    sendFormData: function () {

        var formData = UserApp.saveFormData();

        $.ajax({

            type: "POST",

            url: "MyProject/UserSvc.svc/SaveUserData",

            data: JSON.stringify(formData),

            contentType: "application/json; charset=utf-8",

            dataType: "json",

            success: function (data) {

                if (data && data.d && data.d.Message) {

                    $("#app_status").html(data.d.Message);

                }

            },

            error: function (req, status, error) {

                if (req && req.responseText) {

                    var ex = JSON.parse(req.responseText);

 

                    if (ex && ex.Message) {

                        $("#app_status").html(ex.Message);

                    }

                    else {

                        $("#app_status").html("An error occurred saving the loan application data.");

                    }

                }

            }

        });

    }

};

 

$(document).ready(UserApp.docReady);

On the document becoming ready we execute the docReady function. It calls the loadForm function which loads the form values from local storage (if they exist), and also attaches the sendFormData function as the event handler for the “Save” button. We are storing the data in local storage using “user_data” as a key and a JSON-serialized array for the form elements (we will see how we create that array in the SaveFormData function). After parsing the JSON array we iterate over it to fill in the form input fields.

The saveFormData function is the opposite of the loadForm function in that it serializes the form’s input values using jQuery’s serializeArray function, which is one of the reasons I chose this approach. It does one other thing, which is to wrap the (unserialized) array in an object with a single member, nvps (which stands for “name-value pairs”), that holds the array, and returns this object. Again, we’ll see why later. To be clear, we are changing the bare array, which WCF will not accept as a method parameter:

[ { name: “last_name”, value: “Smith”}, {name: “first_name”, value: “John”}, {name: “email_address”, value: “john.smith@xyz.com”} ]

…to a wrapped object, which WCF will take:

{ nvps:  [ { name: “last_name”, value: “Smith”}, {name: “first_name”, value: “John”}, {name: “email_address”, value: “john.smith@xyz.com”} ] }

Finally there is the sendFormData function, the event handler for the “Save” button. It consists of a single AJAX call to the WCF service, sending up the JSON-serialized wrapped object as the sole parameter for the SaveUserData method, and setting the status on the HTML page based on the success or failure of that call. Two things to note about that. First, on success the data coming down (a simple object with a single public property in it called Message) will be wrapped within a JavaScript object called data in a member called d. So any access to data returned on success is via data.d.xyz, in our case data.d.Message. This use of data.d as a (successful) response wrapper appears to be hold for all JSON-enabled WCF services.

Second, if there was a server-side exception it will come down to the error callback as the JSON-serialized responseText member of the (XMLHttpRequest) request parameter. After parsing the JSON you can get to various exception members, although in our case we are just interested in the exception’s Message member. When debugging both success and failures it is very helpful to use Fiddler or similar tools to see what is getting passed back and forth with each HTTP request and response.

Now it’s time to see the server-side implementation. Let’s look at the WCF interface definition first:

IUserSvc.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

using System.Text;

 

namespace MyProject

{

    [ServiceContract]

    public interface IUserSvc

    {

        [OperationContract]

        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]

        ResultMessage SaveUserData(NameValuePairs nvps);

    }

 

    [DataContract]

    public class NameValuePair

    {

        [DataMember]

        public string name { get; set; }

        [DataMember]

        public string value { get; set; }

    }

 

    [DataContract]

    public class ResultMessage

    {

        [DataMember]

        public string Message { get; set; }

    }

 

    [CollectionDataContract(Namespace = "")]

    public class NameValuePairs : List<NameValuePair>

    {

    }

}

The interface is pretty simple. There is a single SaveUserData method which takes in a collection of name-value pairs and returns a simple object that holds a result message. There are three things to notice here, and all are important. The first are the declarative attributes decorating the method. The following is where the real wiring for receiving and responding in JSON happens:

[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]

The Method can be either POST or GET (as long as your JavaScript code sends the request in the appropriate format). The BodyStyle and ResponseFormat parameters are required to get JSON in and out of the method. Any attempt to use a different BodyStyle (such as WebMessageBodyStyle.Bare) will result in a run-time exception because of settings in the web.config file, which we’ll see later.

Second, the parameter name to the method is nvps. Note this is the same name as the single member returned in the wrapper object on the array of form input field values in the JavaScript saveFormData function. This is some of the “magic” you just have to trust, but as far as I can tell, the parameter name to the WCF method must match the member name in the JavaScript wrapper object. In other words, it appears that when dealing with JSON, WCF is using name-matching between the JSON-serialized names and names in the managed code, probably via reflection.

Finally, while you don’t see it explicitly in the JavaScript code above, the jQuery serializeArray function returns an array of objects, one object for each input element in the form. Each object in the array contains two members - name, whose value matches the name attribute on the input element, and value, which contains the actual field’s value. Note that the NameValuePair class in the interface also uses name and value as member names. Again, these must match (as far as I can tell) the JavaScript member names to make all this work.

Here is the WCF implementation:

UserSvc.svc.cs

using System;

using System.Collections.Generic;

using System.Data;

using System.Data.SqlClient;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Activation;

using System.ServiceModel.Web;

using System.Text;

 

namespace MyProject

{

    [AspNetCompatibilityRequirements (RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

    public class UserSvc : IUserSvc

    {

        public ResultMessage SaveUserData(NameValuePairs nvps)

        {

            var columns = new StringBuilder();

            var parameters = new StringBuilder();

            var rm = new ResultMessage() { Message = "User saved successfully." };

 

            using (var conn = new SqlConnection(Properties.Settings.Default.AppDb))

            using (var cmd = new SqlCommand() { CommandType = CommandType.Text, Connection = conn })

            {

                var paramCollection = cmd.Parameters;

                var rows = 0;

 

                try

                {

                    if (nvps == null || nvps.Count == 0)

                    {

                        throw new ArgumentNullException("nvps");

                    }

 

                    foreach (NameValuePair nvp in nvps)

                    {

                        columns.Append(nvp.name).Append(",");

                        parameters.Append("@").Append(nvp.name).Append(",");

                        paramCollection.Add(new SqlParameter("@" + nvp.name, nvp.value));

                    }

 

                    // KLUDGE: Remove trailing commas.

                    columns.Remove(columns.Length - 1, 1);

                    parameters.Remove(parameters.Length - 1, 1);

                    cmd.CommandText = String.Format(Properties.Settings.Default.InsertSql, columns.ToString(), parameters.ToString());

                    conn.Open();

                    rows = cmd.ExecuteNonQuery();

                    rm.Message = String.Format(Properties.Settings.Default.SuccessMessage, rows, cmd.CommandText);

                }

                catch (Exception ex)

                {

                    rm.Message = ex.Message;

                }

            }

 

            return rm;

        }

    }

}

There isn’t really much going on here. As noted, the method parameter nvps must match the member within the JSON-serialized wrapper object around the array being sent to the method. As the code iterates through the array (collection), note also the use of name and value, again, matching the object member namess that are within the array. The code basically builds a dynamic, parameterized SQL INSERT statement (see the web.config) that assumes the underlying table column names are the same as the input elements name attributes. Cheesy, I know, but it shows we’re actually “doing something” on the server. I don’t claim this to be production-quality! The interesting thing about the code as written, however, is that by simply changing the form to add more input elements and altering the table to add more columns, additional data could be accommodated with no change in the JavaScript or managed code, which gives a bit of flexibility that I like.

Finally, we have the web.config file:

web.config

<?xml version="1.0"?>

<configuration> 

  <configSections>

    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >

      <section name="LoanAppDataRouter.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />

    </sectionGroup>

  </configSections>

  <system.web>

    <compilation debug="true" targetFramework="4.0" />

  </system.web>

  <system.serviceModel>

    <bindings>

      <webHttpBinding>

        <binding name="MyBinding">

          <security mode="TransportCredentialOnly">

            <transport clientCredentialType="Windows"/>

          </security>

        </binding>

      </webHttpBinding>

    </bindings>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

    <services>

      <service name="MyProject.UserSvc" behaviorConfiguration="JsonBehavior">

        <endpoint address="" binding="webHttpBinding" bindingConfiguration="MyBinding" behaviorConfiguration="JsonBehavior" contract="MyProject.IUserSvc">

          <identity>

            <dns value="mywebserver"/>

          </identity>

        </endpoint>

      </service>

    </services>

    <behaviors>

      <endpointBehaviors>

        <behavior name="JsonBehavior">

          <enableWebScript/>

        </behavior>

      </endpointBehaviors>

      <serviceBehaviors>

        <behavior name="JsonBehavior">

          <serviceMetadata httpGetEnabled="true"/>

          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

<system.webServer>

    <modules runAllManagedModulesForAllRequests="true"/>

  </system.webServer>

<applicationSettings>

  <MyProject.Properties.Settings>

   <setting name="InsertSql" serializeAs="String">

    <value>INSERT INTO Users ({0}) VALUES({1})</value>

   </setting>

   <setting name="AppDb" serializeAs="String">

    <value>server=.;initial catalog=ApplicationDB;integrated security=sspi;</value>

   </setting>

   <setting name="SuccessMessage" serializeAs="String">

    <value>Inserted {0} rows using the following statement: {1}</value>

   </setting>

  </MyProject.Properties.Settings>

</applicationSettings>

</configuration>

I won’t go over all of this in detail, but simply call out the pieces that make the JSON work with WCF. You can also see the three properties being stored for access by the managed code at the end of the file. The important part is contained in the service element. Note first the binding attribute of the endpoint element is set to webHttpBinding. This is required for JSON to work. The endpoint also points via the behaviorConfiguration attribute to “JsonBehavior.” If you look at the “JsonBehavior” behavior element under endpointBehaviors, you will see an empty enableWebScript element. This is also required for JSON.

The serviceBehaviors element is basically set up to ease debugging. It enables GET requests (so you could do a URL-encoded request if you chose, even from a browser’s address bar) as well as turning on some debugging sugar. You won’t want that to go into production, however. The rest of the web.config is fairly self-evident. I’ve called out the things you need to pay attention to specifically for WCF services to interact with a JSON client, which could be JavaScript, or anything else that eats and excretes JSON (the list of which is fairly large).

Hopefully this post will help save someone some time by pulling all the required pieces into one place and calling out some of the more obscure aspects of JSON-to-WCF interaction. As always, I appreciate comments, corrections and questions.



http://ednortonengineeringsociety.blogspot.com/2010/10/passing-json-array-to-wcf-service.html
posted on 2011-04-21 22:14 huangyi5209 閱讀(1307) 評論(0)  編輯 收藏 引用 所屬分類: JavascriptC#

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产区二精品视| 午夜久久电影网| 亚洲一区二区三区精品在线| 亚洲国产欧美一区二区三区同亚洲| 亚洲精品视频中文字幕| 欧美mv日韩mv国产网站app| 欧美成人精品三级在线观看| 亚洲欧洲日产国产综合网| 欧美岛国在线观看| 最近看过的日韩成人| 一本色道久久综合亚洲精品婷婷 | 一区二区三区精品视频| 亚洲欧洲视频| 亚洲男人av电影| 美女视频黄a大片欧美| 欧美三级电影大全| 狠狠色狠狠色综合日日91app| 亚洲国产综合视频在线观看| 在线午夜精品| 久久视频国产精品免费视频在线| 欧美大片免费观看| 亚洲国产毛片完整版| 亚洲国产成人久久| 午夜精品久久久99热福利| 欧美ed2k| 欧美亚洲日本网站| 欧美日韩美女一区二区| 一区二区三区在线观看视频| 亚洲制服欧美中文字幕中文字幕| 久久久国产成人精品| 久久亚洲私人国产精品va| 亚洲电影免费观看高清完整版在线| 日韩午夜在线电影| 久久午夜av| 国产精品免费一区豆花| 欧美日韩无遮挡| 亚洲高清不卡一区| 亚洲欧美日韩精品久久奇米色影视| 欧美大片在线看| 久久精品国产欧美亚洲人人爽| 欧美日韩伦理在线| 亚洲精品四区| 欧美.日韩.国产.一区.二区| 亚洲欧美成人一区二区三区| 国产精品theporn| 99视频国产精品免费观看| 美国成人直播| 香蕉免费一区二区三区在线观看 | 在线观看欧美日韩| 久久高清免费观看| 亚洲一区二区在线免费观看视频| 欧美精品亚洲二区| 亚洲日本理论电影| 欧美激情第10页| 女同一区二区| 日韩午夜在线播放| 亚洲美女尤物影院| 国产精品久久久久毛片大屁完整版 | 亚洲国产你懂的| 宅男在线国产精品| 欧美理论片在线观看| 亚洲久久成人| 亚洲伦理在线免费看| 欧美噜噜久久久xxx| 一区二区三区高清视频在线观看| 亚洲成人在线视频播放 | 国产精品视频第一区| 一本色道久久综合狠狠躁篇的优点 | 亚洲国产精品福利| 欧美黑人在线播放| 欧美激情一区二区三区| 亚洲一区二区三区在线| 在线亚洲国产精品网站| 国产精品色婷婷| 久久久欧美精品| 女人香蕉久久**毛片精品| 99精品视频一区二区三区| 亚洲天堂久久| 狠狠爱综合网| 亚洲精品久久嫩草网站秘色| 欧美日韩午夜剧场| 久久精品官网| 欧美国产精品v| 午夜精品理论片| 久色成人在线| 亚洲永久免费av| 久久久久一区| 亚洲综合另类| 久久久久99| 亚洲专区在线视频| 久久久精品欧美丰满| 一区二区三区毛片| 久久精品盗摄| 亚洲在线观看| 裸体女人亚洲精品一区| 亚洲一区在线播放| 美女视频一区免费观看| 欧美一区二区精品| 欧美精品偷拍| 欧美/亚洲一区| 国产欧美精品va在线观看| 欧美电影美腿模特1979在线看| 国产精品国产自产拍高清av| 欧美国产日韩二区| 国产欧美日韩亚洲精品| 最新69国产成人精品视频免费| 国产亚洲精品v| 在线中文字幕日韩| 亚洲欧洲偷拍精品| 午夜免费在线观看精品视频| 日韩西西人体444www| 久久夜色精品国产亚洲aⅴ| 欧美一区二区黄| 国产精品天天摸av网| 日韩视频在线一区| 亚洲日本黄色| 老牛影视一区二区三区| 久久久国产精品一区二区三区| 欧美视频中文字幕| 亚洲人成网站影音先锋播放| 亚洲大片精品永久免费| 久久久成人精品| 开心色5月久久精品| 国产一区香蕉久久| 午夜在线观看免费一区| 性色一区二区三区| 国产精品理论片在线观看| 午夜精彩视频在线观看不卡| 欧美成人精品影院| 欧美大片专区| 亚洲精品欧美极品| 男男成人高潮片免费网站| 嫩草影视亚洲| 91久久久在线| 欧美女主播在线| 99re6热在线精品视频播放速度| 99re6热只有精品免费观看| 欧美成人精品一区二区三区| 亚洲国产影院| 日韩亚洲在线观看| 欧美日韩亚洲视频一区| 一卡二卡3卡四卡高清精品视频 | 老司机精品视频一区二区三区| 国产有码在线一区二区视频| 欧美影院久久久| 欧美1级日本1级| 日韩五码在线| 国产精品福利影院| 午夜精品久久久久| 美女尤物久久精品| 亚洲精品国久久99热| 欧美性猛交视频| 欧美在线资源| 91久久极品少妇xxxxⅹ软件| 亚洲在线观看视频| 国产专区欧美精品| 欧美二区不卡| 亚洲一区二区三区四区视频| 久久永久免费| 亚洲私拍自拍| 国产在线视频欧美一区二区三区| 麻豆精品视频| 亚洲午夜精品一区二区三区他趣| 久久精品一区二区三区不卡牛牛| 亚洲国产精品va| 国产精品白丝av嫩草影院| 欧美在线三区| 日韩一级欧洲| 免费看黄裸体一级大秀欧美| 在线视频欧美精品| 黑人一区二区| 国产精品露脸自拍| 欧美国产视频在线观看| 性8sex亚洲区入口| 亚洲美女色禁图| 麻豆精品一区二区av白丝在线| 亚洲一区二区免费| 亚洲国产精品ⅴa在线观看| 国产伦精品一区二区三区四区免费| 狼人天天伊人久久| 亚洲一区国产视频| 亚洲激情第一页| 麻豆精品在线视频| 欧美亚洲一区二区在线| 日韩亚洲欧美成人| 亚洲国产第一页| 国产一区免费视频| 国产精品久久夜| 欧美日韩免费一区| 欧美电影免费观看大全| 久久蜜桃精品| 久久成人这里只有精品| 亚洲一区二区网站| 国产精品99久久久久久久久| 亚洲黄色免费电影| 欧美本精品男人aⅴ天堂| 久久久久久久久久久成人| 午夜老司机精品| 亚洲伊人观看| 亚洲午夜在线|