当前位置:坤哥网-kungge-WebAPI介绍(一):四种Http请求方式参数分析

WebAPI介绍(一):四种Http请求方式参数分析

2017/7/31 11:20:25 kungge阅读(66) 评论(0)


WebAPI是基于Http协议的,借用了MVC设计理念,使用Controller形式定义服务,Action则代表具体的操作。


新增WebAPI


在.net中创建WebAPI有多种方式,常见的由主要有两种:直接新建一个WebAPI项目和在Web Mvc项目中添加WebAPI控制器。用VS新建ASP.NET Web应用程序时,选择模板的时候指定:88f5fec8-9432-4a12-84cb-61b823556bf2.png

在mvc项目中创建WebAPI选择API控制器即可:

93e53fbd-b98c-4a96-8258-624eda780dab.png

vs会自动添加api的依赖项,需要在Global.asax.cs文件Application_Start方法中添加一句代码GlobalConfiguration.Configure(WebApiConfig.Register)用来启用Web API:

052ebf50-fb64-4346-80b0-684855d690f7.png

954facdf-ece7-4ccf-91a4-dbadcc545ebb.png

在App_Start文件夹中会自动生成WebApiConfig.cs文件用来配置API路由:

2181e236-6a8f-4a43-b4ea-5f34cdee7bd1.png

和MVC一样通过使用路由配置来定位请求的资源,通过URL得到控制器,再根据路由对象,通过Http请求方式找到对应的action。在Web Api中CRUD(Create Retrieve Update Delete)分别对应HttpPost、HttpGet、HttpPut、HttpDelete请求方式,对于post是增还是改无所谓,微软默认模板中put是修改。

在实际开发中往往不会采用上面的默认的路由配置,而是在Controller后添加Action来定位,这样使用起来方便灵活:

482984ec-9304-481b-8458-a7f4f670eff8.png

下面演示Get请求和Post请求参数类型不一样的情况。


Get请求


新增一个CommodityController继承ApiController,新增一些方法用来获取商品信息:

public class CommodityController : ApiController
{
    private static IDBHelper iDbHelper = new SqlHelper();

    #region 获取商品
    /// <summary>
    /// 根据Id获取一个商品
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet]
    public Commodity GetCommodityById(int id)
    {
        return iDbHelper.QueryById<Commodity>(id, "GM_Commodity_001");
    }

    /// <summary>
    /// 根据Id和ProductId获取一个商品
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet]
    public Commodity GetCommodityByIdProductId(int id,long productId)
    {
        return iDbHelper.QueryById<Commodity>(id, "GM_Commodity_001");
    }

    /// <summary>
    /// 获取多个商品
    /// </summary>
    /// <returns></returns>
    [HttpGet]   
    public List<Commodity> GetCommodityList()
    {
        string sql = "select top 5 * from GM_Commodity_001";
        return iDbHelper.QueryList<Commodity>(sql);
    }

    /// <summary>
    /// 根据实体获取一个商品
    /// </summary>
    /// <param name="commodity"></param>
    /// <returns></returns>
    [HttpGet]
    public Commodity GetCommodityByModel(Commodity commodity)
    {
        return iDbHelper.QueryById<Commodity>(commodity.Id, "GM_Commodity_001");
    }

    /// <summary>
    /// 根据实体获取一个商品
    /// </summary>
    /// <param name="commodity"></param>
    /// <returns></returns>
    [HttpGet]
    public Commodity GetCommodityByModelUri([FromUri]Commodity commodity)
    {
        return iDbHelper.QueryById<Commodity>(commodity.Id, "GM_Commodity_001");
    }

    [HttpGet]
    public Commodity GetCommodityBySerialize(string stringifyStr)
    {
        var commodity = SerializeHelper.StringToObject<Commodity>(stringifyStr);
        return iDbHelper.QueryById<Commodity>(commodity.Id, "GM_Commodity_001");
    }

    //[HttpGet]
    public Commodity GetCommodityBySerializeWithoutGet(string stringifyStr)
    {
        var commodity = SerializeHelper.StringToObject<Commodity>(stringifyStr);
        return iDbHelper.QueryById<Commodity>(commodity.Id, "GM_Commodity_001");
    }

    //[HttpGet]
    public Commodity NoGetCommodityBySerializeWithoutGet(string stringifyStr)
    {
        var commodity = SerializeHelper.StringToObject<Commodity>(stringifyStr);
        return iDbHelper.QueryById<Commodity>(commodity.Id, "GM_Commodity_001");
    }


    #endregion   
}

在mvc控制器HomeController新增一个视图页Index用来测试不同的get请求:

@{
    ViewBag.Title = "Index";
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>

<p>获取记录</p>
<input type="text" id="txtCommodityId" value="2" /> <input type="text" id="txtProductId" value="9134570010" />
<input type="button" id="btnGetCommodity" value="根据Id获取一个商品" />
<input type="button" id="btnGetCommodityByIdProductId" value="根据Id和ProductId获取一个商品" />
<input type="button" id="btnGetCommodityList" value="获取多个个商品" />
<input type="button" id="btnGetCommodityByModel" value="根据Model获取一个商品" />
<input type="button" id="btnGetCommodityByModelUri" value="根据ModelUri获取一个商品" />
<input type="button" id="btnGetCommodityBySerialize" value="根据序列化数据获取一个商品" />
<input type="button" id="btnGetCommodityBySerializeWithoutGet" value="根据序列化数据获取一个商品(无HttpGet)" />
<input type="button" id="btnNoGetCommodityBySerializeWithoutGet" value="根据序列化数据获取一个商品(无HttpGet)不是Get开头" />

<script type="text/javascript">

    $(function () {

        var commodity = { Id: "2", ProductId: "9134570010", Title:"【国美自营】尼康(Nikon)D7100 单反套机( AF-S 18-140mmf/3.5-5.6G ED VR 镜头)"};

        //**************************************************************Get请求 start******************************************************************************************

        //单个参数:获取单个商品
        $("#btnGetCommodity").on("click", function () {
            $.ajax({ url: "/api/Commodity/GetCommodityById", type: "get", data: { "id": $("#txtCommodityId").val() }, success: function (data) { alert(data); }, datatype: "json" });
        });

        //多个参数:获取单个商品
        $("#btnGetCommodityByIdProductId").on("click", function () {
            $.ajax({ url: "/api/Commodity/GetCommodityByIdProductId", type: "get", data: { "id": $("#txtCommodityId").val(), "productId": $("#txtProductId").val() }, success: function (data) { alert(data); }, datatype: "json" });
        });

         //无参数:获取多个商品
        $("#btnGetCommodityList").on("click", function () {
            $.ajax({ url: "/api/Commodity/GetCommodityList", type: "get", data:"", success: function (data) { alert(data); }, datatype: "json" });
        });

        //实体参数(json):获取一个商品
        $("#btnGetCommodityByModel").on("click", function () {
            $.ajax({ url: "/api/Commodity/GetCommodityByModel", type: "get", data: commodity, success: function (data) { alert(data); }, datatype: "json" });
        });

        //实体参数(json):获取一个商品  ModelUri
        $("#btnGetCommodityByModelUri").on("click", function () {
            $.ajax({ url: "/api/Commodity/GetCommodityByModelUri", type: "get", data: commodity, success: function (data) { alert(data); }, datatype: "json" });
        });

        //实体参数(json序列化后):获取一个商品 
        $("#btnGetCommodityBySerialize").on("click", function () {
            $.ajax({ url: "/api/Commodity/GetCommodityBySerialize", type: "get", data: { stringifyStr: JSON.stringify(commodity) }, success: function (data) { alert(data); }, datatype: "json" });
        });

        //实体参数(json序列化后):获取一个商品 后台无get
        $("#btnGetCommodityBySerializeWithoutGet").on("click", function () {
            $.ajax({ url: "/api/Commodity/GetCommodityBySerializeWithoutGet", type: "get", data: { stringifyStr: JSON.stringify(commodity) }, success: function (data) { alert(data); }, datatype: "json" });
        });

        //实体参数(json序列化后):获取一个商品 方法名无Get
        $("#btnNoGetCommodityBySerializeWithoutGet").on("click", function () {
            $.ajax({ url: "/api/Commodity/NoGetCommodityBySerializeWithoutGet", type: "get", data: { stringifyStr: JSON.stringify(commodity) }, success: function (data) { alert(data); }, datatype: "json" });
        });

         //**************************************************************Get请求 end******************************************************************************************

    });
</script>

8acec3bd-e35e-41db-ba5c-95da59fbe5a3.png

测试不通过:根据Model获取一个商品、不是Get开头根据序列化数据获取一个商品(无HttpGet)。

根据序列化数据获取一个商品(无HttpGet)测试通过是因为方法名以Get开头,WebApi会自动默认这个请求就是get请求,而如果你以其他名称开头而又不标注方法的请求方式,那么这个时候服务器虽然找到了这个方法,但是由于请求方式不确定,所以直接返回给你405——方法不被允许的错误。


Post请求


在CommodityController下新增一些方法用于修改商品信息:

 #region 修改商品
/// <summary>
/// 修改商品
/// </summary>
/// <param name="commodity"></param>
/// <returns></returns>
public bool PostNoKey([FromBody]int id)
{
    string idStr=HttpContext.Current.Request.Form["id"];
    return true;
}
public bool PostKeyValue([FromBody]int id)
{
    string idStr = HttpContext.Current.Request.Form["id"];
    return true;
}
public bool PostJson(Commodity commodity)
{
    string idStr = HttpContext.Current.Request.Form["id"];
    return true;
}
public bool PostJsonSerialize(Commodity commodity)
{
    string idStr = HttpContext.Current.Request.Form["id"];
    return true;
}
public bool PostJObject(JObject jObject)
{
    string idStr = HttpContext.Current.Request.Form["id"];
    return true;
}
public bool PostDynamic(dynamic dynamicParam)
{
    string idStr = HttpContext.Current.Request.Form["id"];
    return true;
}
#endregion


在HomeController下新建一个PostTest视图测试,页面结构:

@{
    ViewBag.Title = "PostTest";
}

<script src="~/Scripts/jquery-1.10.2.min.js"></script>

<input type="text" id="txtCommodityId" value="2" /> <input type="text" id="txtProductId" value="9134570010" /><br />
<input type="button" id="btnPostNoKey" value="没有关键字参数Post提交" />
<input type="button" id="btnPostKeyValue" value="KeyValue参数Post提交" />
<input type="button" id="btnPostJson" value="Json参数Post提交" />
<input type="button" id="btnPostJsonSerialize" value="Json系列化参数Post提交" />
<input type="button" id="btnPostJObject" value="JObject参数Post提交" />
<input type="button" id="btnPostDynamic" value="Dynamic参数Post提交" />

<script type="text/javascript">
    $(function () {

        var commodity = { Id: "2", ProductId: "9134570010", Title: "【国美自营】尼康(Nikon)D7100 单反套机( AF-S 18-140mmf/3.5-5.6G ED VR 镜头)" };
        var procRemark = "这是post提交";

        //*************************************************************Post请求 start******************************************************************************************

        $("#btnPostNoKey").on("click", function () {
            $.ajax({ url: "/api/Commodity/PostNoKey", type: "post", data: { "": $("#txtCommodityId").val() }, success: function (data) { alert(data); }, datatype: "json" });
        });

        $("#btnPostKeyValue").on("click", function () {
            $.ajax({ url: "/api/Commodity/PostKeyValue", type: "post", data: { "id": $("#txtCommodityId").val() }, success: function (data) { alert(data); }, datatype: "json" });
        });

        $("#btnPostJson").on("click", function () {
            $.ajax({ url: "/api/Commodity/PostJson", type: "post", data: commodity, success: function (data) { alert(data); }, datatype: "json" });
        });

        $("#btnPostJsonSerialize").on("click", function () {
            $.ajax({ url: "/api/Commodity/PostJsonSerialize", type: "post", data: JSON.stringify(commodity), success: function (data) { alert(data); }, datatype: "json", contentType: 'application/json' });
        });

        $("#btnPostJObject").on("click", function () {
            $.ajax({ url: "/api/Commodity/PostJObject", type: "post", data: { "Commodtity": commodity, "ProcRemark": procRemark }, success: function (data) { alert(data); }, datatype: "json" });
        });

        $("#btnPostDynamic").on("click", function () {
            $.ajax({ url: "/api/Commodity/PostDynamic", type: "post", data: { "Commodtity": commodity, "ProcRemark": procRemark }, success: function (data) { alert(data); }, datatype: "json" });
        });

        //**************************************************************Post请求 end******************************************************************************************

    });
</script>

d6b923b5-a28a-49ca-9ad7-e7b8e38b08c8.png

post提交了6种形式的数据,特点如下:

  1. 没有关键字参数Post提交:传递单个值参数,若是json数据则不要key,这样后台才能获取。

  2. KeyValue参数Post提交:传递key-value形式参数,后台拿不到这个参数,但是可以直接访问。

  3. Json参数Post提交:传递json参数,后台可以直接用实体接收,框架会自动装配。

  4. Json系列化参数Post提交:传递json格式系列化的参数,后台可以用实体接收,但必须制定Content-Type。

  5. JObject参数Post提交:传递JObject参数,后台用JObject参数接收,可再转成强类型实体。

  6. Dynamic参数Post提交:传递Dynamic参数,后台用Dynamic参数接收。


Put请求和Delete请求


Put请求和Delete请求与Post请求一样,只是在WebAPI中定义了Put请求是属于新增,在配置api路由时,默认是没有action,要实现CRUD只能根据请求方式来判断功能。但是实际开发中往往会在api路由配置中加入action,因此CUD操作都是用post请求来实现。



WebAPI

发表评论 没有账号,注册评论

博主

  • 用户名:kungge
  • 昵称:kungge

文章标签