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;}
    }

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);
                    }
                });
            });
        });

如果是执行表单提交,则可以直接利用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;
            }
        }

    }

具体调用代码:

        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);
        }

调用结果:

传入的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;}
    }

那么猜想的传递方法为:

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

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

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

那么猜想的传递方法为:

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

请员友自行验证。

时间: 2024-10-10 10:00:51

WebApi传参总动员(三)的相关文章

WebApi传参总动员(一)

目前自己的工作和WebApi相关,免不了传入.接收参数.以前的老办法是从请求流中获取json,再反序列化,这中间有2个不能控制的地方,一个是流,一个是反序列化,都需要try,总感觉非常的不爽.因此对WebApi传参做了深入的研(bai)究(du). 正常的WebApi有三种接收参数的方式: 1.以json字符串的形式传入.从请求的输入流获取传入的json字符串,再反序列化成自己需要的实体.利用的是Request.InputStream. 2.以url传参的形式传入.WebApi自动转换成对应的实

WebApi传参总动员(四)

前文介绍了Form Data 形式传参,本文介绍json传参. WebApi及Model: public class ValuesController : ApiController { [HttpPost] public string GetData(string name,[FromBody]Woman woman) { return "我是" + name + ",我喜欢" + woman.Name; } [HttpPost] public string Ge

WebApi传参总动员(五)

上回说到涉及多个实体的传参,用常规的方法已经不能解决了.这回我们用终极大招搞定她. WebApi:注意要引用JSON.Net [HttpPost] public string GetData(string name,JObject obj) { dynamic json = obj; //获得动态对象 JObject womanJson = json.woman; //获取动态对象中子对象 JObject sonJson = json.son; var woman = womanJson.ToO

WebApi传参总动员(填坑)

本以为系列文章已经Over,突然记起来前面留了个大坑还没填,真是自己给自己挖坑. 这个坑就是: (body 只能被读取一次)Only one thing can read the body MVC和WebAPI之间的一个关键不同点在于MVC缓存请求主体(request body).这意味着MVC的参数绑定可以反复从body中查找参数片断.然而,在WebAPI中,请求主体(HttpContent) 只能被读取一次,不被缓存,只能向前读取的流.这意味着parameter binding需要谨慎对待s

WebApi传参总动员(二)

上篇,从最简单的string入手.本篇演示了从请求的输入流中获取实体.api: public class ValuesController : ApiController { [HttpPost] public string GetData(string name) { return "我爱" + name; } [HttpPost] public string GetData() { var stream = HttpContext.Current.Request.InputStre

C# WebApi传参之Post请求-AJAX

最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷.  学无止境,精益求精    上一节讲述了C# WebApi传参之Get请求-AJAX 本节讲述C# WebApi传参之Post请求-AJAX,说起Ajax针对webApi的Post请求,真的不敢恭维,确实比较怪异,如果你不幸要写一个Ajax Post请求webApi接口,那么您还是有必要花点时间看看本篇博客,如果你也遇到了同样的问题,就不妨在最后给本篇博客点个赞.谢谢 说

vue 路由传参的三种基本模式

路由是连接各个页面的桥梁,而参数在其中扮演者异常重要的角色,在一定意义上,决定着两座桥梁是否能够连接成功. 在vue路由中,支持3中传参方式. 场景,点击父组件的li元素跳转到子组件中,并携带参数,便于子组件获取对应li的数据,显示相应的正确的内容. 父组件中: <li v-for="article in articles" @click="getDescribe(article.id)"> 方案一: getDescribe(id) { // 直接调用$

HttpClient 调用WebAPI时,传参的三种方式

public void Post() { //方法一,传json参数 var d = new { username = " ", password = " ", grant_type = "password", appcode = " ", companyid = " ", version = "1.0", }; var data = JsonConvert.SerializeObjec

react传参的三种方案

可以直接: https://jsfiddle.net/u0no1t2z/ class LoggingButton extends React.Component { // 此语法确保 `handleClick` 内的 `this` 已被绑定. // 所以就不需要bind this了,但是没有办法传自定义参数,所以只能通过data-参数 读取 handleClick = (e) => { console.log('this is 1:',this); console.log('this is 1: