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




2 則留言:

  1. Great insights! I really appreciate how clearly you’ve outlined the topic. Your post has provided some valuable clarity. Thanks for sharing!

    回覆刪除
  2. This sample demonstrates how to use AJAX with Axios in ASP.NET to make asynchronous HostMyCode requests to a web service for data retrieval or manipulation.

    回覆刪除