WebApi传参总动员(三)

上篇介绍了如何从输入流中获取实体对象。本篇介绍以url形式传递参数。简单的参数不再赘述,这里主要实现形如(string name,Woman woman)这样的参数传递。

本篇及后面几章均涉及js调用及C#调用,而且篇幅较长,请大家见谅。

一、js调用。

WebApi:

public class ValuesController : ApiController
    {
        
        [HttpPost]
        public string GetData(string name,Woman woman)
        {
            return "我是" + name + ",我喜欢" + woman.Name;
        }
        [HttpPost]
        public string GetData(Woman woman)
        {
            return woman.Age + "" + woman.Name;
        }

    }
    public class Woman//仅仅为了演示方便
    {
        public string Name{get;set;}
        public string Age{get;set;}
    }
View Code

JS端。JS端的obj2url(对象生成键值对)实现方法比较丑陋,如果有更好的方法请大家不吝赐教。

        var woman = { Name: '刘亦菲', Age: 18 };
        function obj2url(obj) {
            var result='';
            for (var i in obj) {
                result += i + "=" + obj[i]+ "&";
            }
            return result.substr(0, result.length - 1);//返回 Name=刘亦菲&Age=18
        }
        $(function () {

            $('#btn').click(function () {
                $.ajax({
                    type: "post",
                    url: "http://localhost:7601/api/values/GetData?name=楼主",
                    data: obj2url(woman),
                    success: function (r) {
                        alert(r);
                    }
                });
            });
        });
View Code

如果是执行表单提交,则可以直接利用jq的 $('#formID').serialize()直接获取键值对。

看请求数据:

执行结果:

这里有两点注意:

1、浏览器发起的请求,url中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,也就是会自动urlencode。

2、请求中的Form Data,未经编码,也能正确的传递到Api中。(如:Name:刘亦 菲?/)

这是经过试验得出来的,理论依据没找。结论是否正确?忘有那位朋友不吝赐教。

二、C#调用。这里主要涉及

服务端WebApi代码不变。给Woman类添加一个属性,public List<DateTime> ExerciseTime { get; set; },来增大难度。

客户端:

首先来个基础调用类:此类是用HttpWebRequest发起请求,是同步的,后期我们会升级到HttpClient,异步。

    //PostService.cs
    public class PostService
    {
        public bool PostWebRequest(string postUrl, string postvalue, out string returnValue)
        {
            returnValue = string.Empty;
            try
            {
                byte[] byteData = Encoding.UTF8.GetBytes(postvalue);
                Uri uri = new Uri(postUrl);
                HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(uri);
                webReq.Method = "POST";
                webReq.ContentType = "application/x-www-form-urlencoded";
                webReq.ContentLength = byteData.Length;
                //定义Stream信息
                Stream stream = webReq.GetRequestStream();
                stream.Write(byteData, 0, byteData.Length);
                stream.Close();
                //获取返回信息
                HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
                StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                returnValue = streamReader.ReadToEnd();
                //关闭信息
                streamReader.Close();
                response.Close();
                stream.Close();
                return true;
            }
            catch (Exception ex)
            {
                returnValue = ex.Message;
                return false;
            }
        }

    }
View Code

具体调用代码:

        private void btnPost_Click(object sender, EventArgs e)
        {
            NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(string.Empty);
            queryString["Name"] = "刘亦菲";
            queryString["Age"] = "18";
            queryString["ExerciseTime[0]"] = DateTime.Now.ToString();
            queryString["ExerciseTime[1]"] = DateTime.Now.AddHours(-12).ToString();
            queryString["ExerciseTime[2]"] = "哈哈";
            string postdata = queryString.ToString(); // Returns "key1=value1&key2=value2", all URL-encoded
            //string postdata = "Name=刘亦菲&Age=18";//string postdata = "Name=刘亦 菲?/&Age=18";也OK。
            string url = "http://localhost:7601/api/values/GetData?name=楼主";
            string retValue = "";
            PostService service = new PostService();
            service.PostWebRequest(url, postdata, out retValue);
            MessageBox.Show(retValue);
        }
View Code

调用结果:

传入的Name为编码后的值,需要解码才能获得正确的值。有点奇怪。

好吧,再做一次试验:

调用代码修改一下,不编码直接拼字符串:

            string postdata = "Name=刘亦菲&Age=18";//string postdata = "Name=刘亦 菲?/&Age=18";也OK。
            string url = "http://localhost:7601/api/values/GetData?name=楼主";
            string retValue = "";
            PostService service = new PostService();
            service.PostWebRequest(url, postdata, out retValue);

结论:由客户端发起的请求数据,需要编码、解码配对使用。

基础差啊,就表现出来了。原理、原理、原理,说三遍。忘知道的员友不吝赐教。

注意1、List<T>的传参方式。2、类的属性为实体类的情况,比如:

    public class Woman//仅仅为了演示方便
    {
        public string Name{get;set;}
        public string Age{get;set;}
        public List<DateTime> ExerciseTime { get; set; }
        public Son Son { get; set; }
    }
    public class Son
    {
        public string Name{get;set;}
        public int Age{get;set;}
    }
View Code

那么猜想的传递方法为:

            queryString["Son.Name"] = "儿子";
            queryString["Son.Age"] = "2";

再复杂一点,有几个儿子:

        public List<Son> Son { get; set; }

那么猜想的传递方法为:

            queryString["Son[0].Name"] = "儿子";
            queryString["Son[0].Age"] = "2";

请员友自行验证。

原文地址:https://www.cnblogs.com/luhuanong/p/4925193.html