2017年9月27日 星期三

[ASP.NET] Ajax with web service

 ASP.NET    Web service    vue.js  



Introduction


This is an ajax sample with web service and axios in ASP.NET.


Environment


Visual Studio 2015 Community
MVC 5
vue 2.4.2
axios 0.16.2



Implement


Create web service




WsSysInfo.asmx.cs

To enable ajax calls on the web service, add [ScriptService] (System.Web.Script.Services. ScriptServiceAttribute) on the class.

[ScriptService]
[WebService(Namespace = "Mvc517.Website.Webservice", Description = "System information")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class WsSysInfo : System.Web.Services.WebService
{
}




XHR WebMethod

WsSysInfo.asmx.cs

//Skip attributes...
public
class WsSysInfo : System.Web.Services.WebService
{
  [
WebMethod]
[ScriptMethod(UseHttpGet = true)]
public SysInfo GetXml()
{
            var sys = new SysInfo()
            {
                Title = "Get XML from web service",
                Year = 2017,
                Author = "JB.Lin"
            };
            return sys;
 }
}


1.  Also add [ScriptMethod] on the WebMethod for ajax calls.
2.  The WebMethod supports HttpPost in default. If we would like to enable HttpGet on it, add the attribute and parameter like this,
[ScriptMethod(UseHttpGet = true)]

Further more, update the WebConfig as following.

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

We will use Vue.js with axios to get and show the data from the web service.

HTML

<div id="app">
    <div>
        <span class="alert alert-info"><b>{{ sysinfo.Title }}</b>  &copy; Copyright {{ sysinfo.Year }} by {{  sysinfo.Author }}</span>
    </div>
</div>



JS

var app = new Vue({
    el: '#app',
    data: {
        sysinfo: {}
    },
    methods: {
       
        getSysInfoXml: function () {
            var vm = this;

            axios.get('../Webservice/WsSysInfo.asmx/GetXml')
                .then(function (response) {
                    let xml = response.data;

                    let parser = new DOMParser();
                    xmlDoc = parser.parseFromString(xml, "text/xml");

                    let title =
                       xmlDoc.getElementsByTagName("Title")[0].childNodes[0].nodeValue;
                    let year =
                        xmlDoc.getElementsByTagName("Year")[0].childNodes[0].nodeValue;
                    let author =
                      xmlDoc.getElementsByTagName("Author")[0].childNodes[0].nodeValue;

                    vm.sysinfo = {
                        Title: title,
                        Year: year,
                        Author: author
                    };

                }, function (error) {
                });
        }
    },
    mounted: function () {
        this.getSysInfoXml();
    }
})


Result:








WebMethod returns JSON string

WsSysInfo.asmx.cs

//Skip attributes...
public
class WsSysInfo : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetJsonStr()
{
            var sys = new SysInfo()
            {
                Title = "Get json string from web service",
                Year = 2017,
                Author = "JB.Lin"
            };
            return new JavaScriptSerializer().Serialize(sys);  
//using System.Web.Script.Serialization;
}
}


JS

var app = new Vue({
    el: '#app',
    data: {
        sysinfo: {}
    },
    methods: {
        getSysInfoJsonStr: function () {
            var vm = this;

            axios.post('../Webservice/WsSysInfo.asmx/GetJsonStr', {
                headers: {
                    'Content-Type': 'application/json'
                }
            }).then(function (response) {
                if (response.data.hasOwnProperty("d")) {
                    vm.sysinfo = JSON.parse(response.data.d);
                }
                else {
                    vm.sysinfo = JSON.parse(response.data);
                }
            }, function (error) {
            });
        }
    },
    mounted: function () {
        this.getSysInfoJsonStr();
    }
})


Notice that the web service will prevent from cross site scripting attacks(XSS) with these two ways,

1.  Avoid returning json with HttpGet, even if UseHttpGet = true is set, the web service returns XML.
2.  Return the json string with a property: ‘d’, to. So we have to parse response.data.d into a json object, not just response.data.


Result:








WebMethod returns JSON object


WsSysInfo.asmx.cs

//Skip attributes...
public
class WsSysInfo : System.Web.Services.WebService
{
[WebMethod]
   [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
   public SysInfo GetJsonObj()
   {
            var sys = new SysInfo()
            {
                Title = "Get json object from web service",
                Year = 2017,
                Author = "JB.Lin"
            };
            return sys;
   }
}


JS

var app = new Vue({
    el: '#app',
    data: {
        sysinfo: {}
    },
    methods: {
        getSysInfoJsonObj: function () {
            var vm = this;

            axios.post('../Webservice/WsSysInfo.asmx/GetJsonObj', {
                headers: {
                    'Content-Type': 'application/json'
                }
            }).then(function (response) {
                vm.sysinfo = response.data.d;
            }, function (error) {
                console.log(error.statusText);
            });
        }
    },
    mounted: function () {
        this.getSysInfoJsonObj();
    }
})



Result:






Source code





Reference




沒有留言:

張貼留言