zoukankan      html  css  js  c++  java
  • 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";

    请员友自行验证。

  • 相关阅读:
    jira启动错误解决:Failed to read artifact descriptor for com.atlassian.plugins.rest:atlassian-rest-doclet:jar:2.9.2:
    jira8.0 api变化--含解决方法
    jira spring scanner注意事項
    pom文件添加aliyun镜像
    jira插件打包时报osgi的错误
    jira 根据项目(project)获取优先级(proirity)
    scriptrunner fragments设置web resource的路径
    Ubuntu16.04 LTS上安装Go1.10
    ubuntu 常见错误--Could not get lock /var/lib/dpkg/lock 问题修改
    VS2015编译OpenSSL
  • 原文地址:https://www.cnblogs.com/luhuanong/p/4925193.html
Copyright © 2011-2022 走看看