C # advanced series -- WebApi interface parameters are no longer confused: detailed parameter passing,

Source: Internet
Author: User

C # advanced series -- WebApi interface parameters are no longer confused: detailed parameter passing,

When I look at this article, I am confused: the parameter in WebApi is added with [FromBody]. If I don't know why, I am Baidu. I have seen the following article and shared it with you:

Link: http://www.cnblogs.com/landeanfen/archive/2016/04/06/5337072.html#undefined

 

I still remember that when I was using WebApi, I had to go over the parameter transfer mechanism for a long time and read the documents for a long time. Today, we have been using webapis for some time. Today we have recorded some methods for passing parameters through API interfaces. This is a note, and we hope to help beginners avoid detours. This article is intended for beginners who are interested in using webapis.

WebApi Series

  • C # advanced series -- WebApi Interface Test Tool: WebApiTestClient
  • C # advanced series-WebApi cross-origin problem solution: CORS
  • C # advanced series-WebApi Identity Authentication solution: Basic Authentication
  • C # advanced series -- passing parameters through WebApi
  • C # advanced series -- WebApi interface return value is not confusing: Return Value Type Details
  • C # advanced series-WebApi Exception Handling Solution
  • C # advanced series-Overview of Area usage in the WebApi Area

This article describes how to pass parameters of basic types (including int, string, datetime, and so on), entities, arrays, and Other types through the get, post, put, and delete request methods.

1. get request

For data retrieval, we should use the get request most. The following example shows how to pass the get request parameters.

1. Basic type parameters
[HttpGet]public string GetAllChargingData(int id, string name){    return "ChargingData" + id;}
$.ajax({        type: "get",        url: "http://localhost:27221/api/Charging/GetAllChargingData",        data: { id: 1, name: "Jim", bir: "1988-09-11"},        success: function (data, status) {            if (status == "success") {                $("#div_test").html(data);            }        }    });

Parameter Effect

This is the most basic parameter transfer method for get requests.

2. entities as parameters

If we want to directly pass object parameters to the background during the get request, is it feasible? Let's take a look.

Public class TB_CHARGING {// <summary> // primary key Id /// </summary> public string ID {get; set ;} /// <summary> /// NAME of the charging device /// </summary> public string NAME {get; set ;} /// <summary> /// description of the charging device /// </summary> public string DES {get; set ;} /// <summary> /// creation time /// </summary> public DateTime CREATETIME {get; set ;}}
[HttpGet]public string GetByModel(TB_CHARGING oData){     return "ChargingData" + oData.ID;}
  $.ajax({        type: "get",        url: "http://localhost:27221/api/Charging/GetByModel",        contentType: "application/json",        data: { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" },        success: function (data, status) {            if (status == "success") {                $("#div_test").html(data);            }        }    });

Test Results

It can be seen that when a get request is sent, the json object is directly transmitted as an object to the background, and the background cannot receive the object. Why? Let's take a look at the corresponding http Request

It turns out that when a get request is sent, all parameters are put in the url and passed in the string format by default. The backend is naturally unable to get the parameters.

Cause analysis:Do you remember the difference between get and post requests? One difference is that the get request data is appended to the URL (that is, the data is placed in the HTTP header), while the post request is placed in the http packet body.

According to the suggestions of the school friends, you can add [FromUri] In the parameter to Get the object during Get requests. Or paste the Code:

    var postdata = { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" };    $.ajax({        type: "get",        url: "http://localhost:27221/api/Charging/GetAllChargingData",        data: postdata,        success: function (data, status) { }    });
        [HttpGet]        public string GetAllChargingData([FromUri]TB_CHARGING obj)        {            return "ChargingData" + obj.ID;        }

Expected result:

If you do not want to use the [FromUri] method that adds features to the parameter, you can also use the serialization method before backend deserialization.

  $.ajax({        type: "get",        url: "http://localhost:27221/api/Charging/GetByModel",        contentType: "application/json",        data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) },        success: function (data, status) {            if (status == "success") {                $("#div_test").html(data);            }        }    });
        [HttpGet]        public string GetByModel(string strQuery)        {            TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery);            return "ChargingData" + oData.ID;        }

In this way, we can get the serialized object in the background, and then get the object through deserialization.

In the url, we can see that it automatically adds an encoding to the object:

As for the sort binder method mentioned by garden friends, the bloggers thought it was a little complicated. If you are interested, try again. You can choose which method to use to transfer objects.

3. array as a parameter

Generally, arrays are not recommended as parameters for get requests, because we know that the size of parameters transmitted in get requests is limited. The maximum value is 1024 bytes, and there are many contents in the array, passing it as a parameter may result in loss of parameter exceeding the limit.

4. Weird get requests

Why is the get request "weird? Let's take a look at the two comparison methods below.

(1) The method name of WebApi starts with get
    $.ajax({        type: "get",        url: "http://localhost:27221/api/Charging/GetByModel",        contentType: "application/json",        data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) },        success: function (data, status) {            if (status == "success") {                $("#div_test").html(data);            }        }    });
        [HttpGet]        public string GetByModel(string strQuery)        {            TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery);            return "ChargingData" + oData.ID;        }

This is a standard writing method.[HttpGet]The parameters are normal:

For comparison, I will[HttpGet]Remove and then call

        //[HttpGet]        public string GetByModel(string strQuery)        {            TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery);            return "ChargingData" + oData.ID;        }

It seems that there are no problems! Someone may wonder if all get requests can omit the [HttpGet] annotation. Let's try it.

(2) The method name of WebApi does not start with get

We set the previous method name fromGetByModelChangeFindByModelThis is normal again, but many people do not want to start with Get for queries, or directly start with Query. Is there any relationship between this? It doesn't matter. Let's talk about it as a fact.

    $.ajax({        type: "get",        url: "http://localhost:27221/api/Charging/FindByModel",        contentType: "application/json",        data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) },        success: function (data, status) {            if (status == "success") {                $("#div_test").html(data);            }        }    });
        [HttpGet]        public string FindByModel(string strQuery)        {            TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery);            return "ChargingData" + oData.ID;        }

It seems feasible and there is no problem. Based on the above inference, we remove[HttpGet]It is also feasible. Well, let's comment out [HttpGet] and try it out.

The result is no breakpoint.Some people do not believe it. Let's look at the http request in the browser:

That's strange. I changed the method name. Is that true? So far!

The bloggers understand the following:The method name starts with Get, and WebApi automatically defaults this request to a get request. If you start with another name and do not mark the Method Request Method, at this time, the server finds this method, but the request method is uncertain, so it returns 405 to you directly-the error that the method is not allowed.

Conclusion:It is best to add the Request Method ([HttpGet]/[HttpPost]/[HttpPut]/[HttpDelete]) to all WebApi methods. Do not be lazy. This prevents similar errors, it is also conducive to the maintenance of methods, and others will know what request this method is.

This is why many people ask in the garden why the method name cannot be called without [HttpGet!

Ii. post requests

In the RESETful style of WebApi, the addition, deletion, modification, and query of API services correspond to the http post/delete/put/get requests respectively. Next we will talk about the transmission method of post request parameters.

1. Basic type parameters

The parameters of the basic type of the post request are a little different from those of the get request. We know that the parameters of the get request are transmitted through the url, while the post request is transmitted through the http Request body, webApi post requests also need to retrieve parameters from the http Request body.

(1) incorrect syntax
    $.ajax({        type: "post",        url: "http://localhost:27221/api/Charging/SaveData",        data: { NAME: "Jim" },        success: function (data, status) {            if (status == "success") {                $("#div_test").html(data);            }        }    });
        [HttpPost]        public bool SaveData(string NAME)        {            return true;        }

This is a seemingly correct method, but the actual situation is:

(2) correct usage
    $.ajax({        type: "post",        url: "http://localhost:27221/api/Charging/SaveData",        data: { "": "Jim" },        success: function (data, status) {}    });
        [HttpPost]        public bool SaveData([FromBody]string NAME)        {            return true;        }

This is another way of writing that many people have a headache, but there is no way to get our results:

Generally, the url-based parameter fetch Mechanism is a key-value pair, that is, a key is equal to a value, while the FromBody here is different from the url-based parameter fetch mechanism, its mechanism is = value, there is no key concept, and if you write the key (for example, your ajax parameter is written {NAME: "Jim "}), the NAME obtained in the background is null. If you don't believe it, try it.

All of the above is about passing a basic type parameter. What if we need to pass multiple basic types? According to the above inference, can I write it like this ([FromBody] string NAME, [FromBody] string DES. Try it.

(1) incorrect syntax
$. Ajax ({type: "post", url: "http: // localhost: 27221/api/Charging/SaveData", data: {"": "Jim ","": "Remarks"}, success: function (data, status ){}});
        [HttpPost]        public bool SaveData([FromBody]string NAME, [FromBody] string DES)        {            return true;        }

Expected result

This means that we cannot use multiple [FromBody] values. This method fails.

(2) correct usage

Since the above method does not work, how can we transmit multiple basic types of data? Many solutions are to create a class to include the passed parameters. The blogger thinks this is not flexible enough, because if we create a class for each post request that passes multiple parameters in the front and back end, how many such parameter classes will our system have at that time? It is quite troublesome to maintain it! Therefore, bloggers think that using dynamic is a good choice. Let's try it.

$. Ajax ({type: "post", url: "http: // localhost: 27221/api/Charging/SaveData", contentType: 'application/json', data: json. stringify ({NAME: "Jim", DES: "Remarks"}), success: function (data, status ){}});
        [HttpPost]        public object SaveData(dynamic obj)        {            var strName = Convert.ToString(obj.NAME);            return strName;        }

The dynamic type can be used to smoothly obtain multiple parameters, eliminating the hassle of [FromBody]. In addition, you do not need to use {"of" No Response Header "for the transmission of ajax parameters {"": "value"} is there any small fresh feeling in this way ~~ Note that the parameter type in the ajax request must be Json, that is, contentType: 'application/json.

(3) recommended usage

Through the transmission of the post request basic type parameters, we have learned the convenience of dynamic, in order to avoid the [FromBody] cumbersome and {"": "value. It is recommended that dynamic be used for transmission of all basic types to facilitate the transmission of one or more parameters of the basic types, as shown in the preceding example. If you have a better solution, you are welcome to discuss it.

2. object as a parameter (1) a single object as a parameter

Above, the dynamic type is used to solve the problem of transmission of post request basic data. How can we solve this problem when we need to pass an object as a parameter? Let's take a look at the following code:

    $.ajax({        type: "post",        url: "http://localhost:27221/api/Charging/SaveData",        data: { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" },        success: function (data, status) {}    });
        [HttpPost]        public bool SaveData(TB_CHARGING oData)        {            return true;        }

Expected result

Principles:When an object is used as a parameter, the front-end directly transmits the common json, and the background directly receives the object using the corresponding type without the FromBody. However, you must note that the contentType cannot be set to appplication/json. Otherwise, the parameter cannot be passed to the background. Let's take a look at its default contentType:

To find out the cause, the blogger checked the http Content-Type. See the following description:

  • Application/x-www-form-urlencoded: <form encType = ""> default encType, form data is encoded in the key/value format and sent to the server (the default format of form data submission );
  • Application/json: JSON Data Format

That is to say, the post request sends the key/value form of the data in the form to the service by default, and our server only needs to receive the object with the corresponding key/value attribute value. If application/json is used, the front-end data is transmitted to the backend in serialized json format. The backend needs to convert the data into an object, and a deserialization process is required. According to this logic, if we specify contentType as application/json, it is also possible to pass serialized objects. The blogger is curious and intends to try it out, so he has the following code:

    var postdata = { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" };    $.ajax({        type: "post",        url: "http://localhost:27221/api/Charging/SaveData",        contentType: 'application/json',        data: JSON.stringify(postdata),        success: function (data, status) {}    });
        [HttpPost]        public bool SaveData(TB_CHARGING lstCharging)        {            return true;        }

Expected result:

The attempt is successful. That is to say, both methods are feasible. If you specify contentType as application/json, you must pass the serialized object. If you use the default parameter type of the post request, the front-end directly transmits the json type object. 

(2) objects and basic types are passed as parameters together.

Sometimes, we need to pass the basic types and entities together to the background. At this time, our magical dynamic will come in handy.

    var postdata = { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" };    $.ajax({        type: "post",        url: "http://localhost:27221/api/Charging/SaveData",        contentType: 'application/json',        data: JSON.stringify({ NAME:"Lilei", Charging:postdata }),        success: function (data, status) {}    });
        [HttpPost]        public object SaveData(dynamic obj)        {            var strName = Convert.ToString(obj.NAME);            var oCharging = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(Convert.ToString(obj.Charging));            return strName;        }

Expected result:

The principle is also needless to say, the same as above.

3. array as parameter (1) basic type array
    var arr = ["1", "2", "3", "4"];    $.ajax({        type: "post",        url: "http://localhost:27221/api/Charging/SaveData",        contentType: 'application/json',        data: JSON.stringify(arr),        success: function (data, status) { }    });
        [HttpPost]        public bool SaveData(string[] ids)        {            return true;        }

Expected result:

(2) entity set
    var arr = [        { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" },        { ID: "2", NAME: "Lilei", CREATETIME: "1990-12-11" },        { ID: "3", NAME: "Lucy", CREATETIME: "1986-01-10" }    ];    $.ajax({        type: "post",        url: "http://localhost:27221/api/Charging/SaveData",        contentType: 'application/json',        data: JSON.stringify(arr),        success: function (data, status) {}    });
        [HttpPost]        public bool SaveData(List<TB_CHARGING> lstCharging)        {            return true;        }

Expected result:

4. Transmission of request parameters sent in the background

All the above are done through front-end ajax requests. We know that if the caller is not a web project, such as an Android client, you may need to send an http request from the background to call our interface method. Is it feasible if we send a request through the background? Let's use an object as a parameter to pass the write code.

Public void TestReques () {// request path string url =" http://localhost:27221/api/Charging/SaveData "; // Define the request and set the request Path WebRequest request = WebRequest. create (url); request. method = "post"; // initialize the request parameter string postData = "{ID: \" 1 \ ", NAME: \" Jim \ ", CREATETIME: \ "1988-09-11 \"} "; // sets the parameter Encoding format to solve Chinese garbled byte [] byteArray = Encoding. UTF8.GetBytes (postData); // you can specify the MIME type and content length of a request. contentType = "application/json"; request. contentLength = byteArray. length; // open the request processing Stream dataStream = request. getRequestStream (); dataStream. write (byteArray, 0, byteArray. length); dataStream. close (); // define response as the previous request response WebResponse response = request. getResponse (); // obtain the corresponding status code Console. writeLine (HttpWebResponse) response ). statusDescription); // defines the response stream dataStream = response. getResponseStream (); StreamReader reader = new StreamReader (dataStream); string responseFromServer = reader. readToEnd (); // read all the consoles. writeLine (responseFromServer );}

When the code runs to the request. GetResponse () sentence, the API enters the breakpoint.

The attempt is successful.

Iii. put requests

Put requests in webapis are generally used for object updates. It is basically the same as the post request. It also supports [FromBody] and dynamic.

1. Basic type parameters
    $.ajax({        type: "put",        url: "http://localhost:27221/api/Charging/Update",        contentType: 'application/json',        data: JSON.stringify({ ID: "1" }),        success: function (data, status) {}    });
        [HttpPut]        public bool Update(dynamic obj )        {            return true;        }

2. entities as parameters

The request is the same as the post request.

3. array as a parameter

The request is the same as the post request.

Iv. delete request

As the name suggests, a delete request must be used for a delete operation. The parameter transfer mechanism is basically the same as that of post. The following is a simple example. For other cases, refer to post requests.

    var arr = [        { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" },        { ID: "2", NAME: "Lilei", CREATETIME: "1990-12-11" },        { ID: "3", NAME: "Lucy", CREATETIME: "1986-01-10" }    ];    $.ajax({        type: "delete",        url: "http://localhost:27221/api/Charging/OptDelete",        contentType: 'application/json',        data: JSON.stringify(arr),        success: function (data, status) {}    });
        [HttpDelete]        public bool OptDelete(List<TB_CHARGING> lstChargin)        {            return true;        }

V. Summary

The above details the parameter transfer of various WebApi requests. In each case, the actual code of the blogger has been tested and the content is not difficult. However, it still takes some time to get familiar with such things. Here is a summary, hope to help those who are new to WebApi. If this article can help youRecommendationNext, your recommendations are the motivation for the bloggers to continue to summarize!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.