WebAPI从入门到精通.docx

上传人:b****6 文档编号:6316115 上传时间:2023-01-05 格式:DOCX 页数:27 大小:158.20KB
下载 相关 举报
WebAPI从入门到精通.docx_第1页
第1页 / 共27页
WebAPI从入门到精通.docx_第2页
第2页 / 共27页
WebAPI从入门到精通.docx_第3页
第3页 / 共27页
WebAPI从入门到精通.docx_第4页
第4页 / 共27页
WebAPI从入门到精通.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

WebAPI从入门到精通.docx

《WebAPI从入门到精通.docx》由会员分享,可在线阅读,更多相关《WebAPI从入门到精通.docx(27页珍藏版)》请在冰豆网上搜索。

WebAPI从入门到精通.docx

WebAPI从入门到精通

第1章.实例快速上手-ASP.NET4.5新特性WebAPI从入门到精通

在新出的MVC4中,增加了WebAPI,用于提供REST风格的WebService,新生成的WebAPI项目和典型的MVC项目一样,包含主要的Models、Views、Controllers等文件夹和Global.asax文件。

Views对于WebAPI来说没有太大的用途,Models中的Model主要用于保存Service和Client交互的对象,这些对象默认情况下会被转换为Json格式的数据迚行传输,Controllers中的Controller对应于WebService来说是一个Resource,用于提供服务。

和普通的MVC一样,Global.asax用于配置路由规则。

(1)环境准备

建议使用VS2012以上版本创建WebAPI,如果是使用VS2010,需要安装VS2010SP1升级包,MVC4升级包,打开VS2012创建如下:

第一步:

新建ASP.NETWeb应用程序

第二步:

建议WebAPI

新生成的WebAPI项目和典型的MVC项目一样,包含主要的Models,Views,Controllers等文件夹和Global.asax文件

注意:

再次强调Views对于WebAPI来说没有太大的用途,Models中的Model主要用于保存Service和Client交互的对象,这些对象默认情况下会被转换为Json格式的数据进行传输,Controllers中的Controller对应于WebService来说是一个Resource,用于提供服务。

和普通的MVC一样,Global.asax用于配置路由规则

(二)Models

和WCF中的数据契约形成鲜明对比的是,MVCWebAPI中的Model就是简单的POCO,没有任何别的东西,如,你可以创建如下的Model

publicclassUserModel

{

publicintId{get;set;}

publicstringUserName{get;set;}

publicstringPassWord{get;set;}

}

注意:

Model必须提供public的属性,用于json或xml反序列化时的赋值

(三)Controllers

MVCWebAPI中的Controllers和普通MVC的Controllers类似,不过不再继承于Controller,而改为继承API的ApiController,一个Controller可以包含多个Action,这些Action响应请求的方法与Global中配置的路由规则有关,在后面结束Global时统一说明

(四)Global

默认情况下,模板自带了两个路由规则,分别对应于WebAPI和普通MVC的Web请求,默认的WebAPI路由规则如下

1routes.MapHttpRoute(

2name:

"DefaultApi",

3routeTemplate:

"api/{controller}/{id}",

4defaults:

new{id=RouteParameter.Optional}

5);

可以看到,默认路由使用的固定的api作为Uri的先导,按照微软官方的说法,用于区分普通Web请求和WebService的请求路径:

可以看到,默认的路由规则只指向了Controller,没有指向具体的Action,因为默认情况下,对于Controller中的Action的匹配是和Action的方法名相关联的:

具体来说,如果使用上面的路由规则,对应下面的Controller:

publicclassUserController:

ApiController

{

publicListallModeList=newList(){

newUserModel(){Id=1,UserName="zhang",PassWord="123"},

newUserModel(){Id=2,UserName="lishi",PassWord="123456"},

newUserModel(){Id=3,UserName="wang",PassWord="1234567"}

};

//Getapi/User/

publicIEnumerableGetAll()

{

returnallModeList;

}

//Getapi/User/1

publicIEnumerableGetOne(intid){

returnallModeList.FindAll((m)=>{returnm.Id==id;});

}

//POSTapi/User/

publicboolPostNew(UserModeluser)

{

try

{

allModeList.Add(user);

returntrue;

}

catch{

returnfalse;

}

}

//Deleteapi/User/

publicintDeleteAll()

{

returnallModeList.RemoveAll((mode)=>{returntrue;});

}

//Deleteapi/User/1

publicintDeleteOne(intid){

returnallModeList.RemoveAll((m)=>{returnm.Id==id;});

}

//Putapi/User

publicintPutOne(intid,UserModeluser)

{

ListupDataList=allModeList.FindAll((mode)=>{returnmode.Id==id;});

foreach(varmodeinupDataList)

{

mode.PassWord=user.PassWord;

mode.UserName=user.UserName;

}

returnupDataList.Count;

}

}

则,会有下面的对应关系:

URLHttpMethod对应的Action名

/api/UserGETGetALL

/api/User/1GETGetOne

/api/UserPOSTPostNew

/api/User/1DELETEDeleteOne

/api/UserDELETEDeleteALL

/api/UserPUTPutOne

(5)客户端JS调用

functiongetAll(){

$.ajax({

url:

"api/User/",

type:

'GET',

success:

function(data){

document.getElementById("modes").innerHTML="";

$.each(data,function(key,val){

varstr=val.UserName+':

'+val.PassWord;

$('

  • ',{html:

    str}).appendTo($('#modes'));

    });

    }

    }).fail(

    function(xhr,textStatus,err){

    alert('Error:

    '+err);

    });

    }

    functionfind(){

    $.ajax({

    url:

    "api/User/1",

    type:

    'GET',

    success:

    function(data){

    document.getElementById("modes").innerHTML="";

    $.each(data,function(key,val){

    varstr=val.UserName+':

    '+val.PassWord;

    $('

  • ',{html:

    str}).appendTo($('#modes'));

    });

    }

    }).fail(

    function(xhr,textStatus,err){

    alert('Error:

    '+err);

    });

    }

     

    functionadd(){

    $.ajax({

    url:

    "api/User/",

    type:

    "POST",

    dataType:

    "json",

    data:

    {"Id":

    4,"UserName":

    "admin","PassWord":

    "666666"},

    success:

    function(data){

    getAll();

    }

    }).fail(

    function(xhr,textStatus,err){

    alert('Error:

    '+err);

    });

    }

    functionremoveUser(){

    $.ajax({

    url:

    "api/User/3",

    type:

    'DELETE',

    success:

    function(data){

    document.getElementById("modes").innerHTML="";

    getAll();

    }

    }).fail(

    function(xhr,textStatus,err){

    alert('Error:

    '+err);

    });

    }

    functionremoveAll(){

    $.ajax({

    url:

    "api/User/",

    type:

    'DELETE',

    success:

    function(data){

    document.getElementById("modes").innerHTML="";

    getAll();

    }

    }).fail(

    function(xhr,textStatus,err){

    alert('Error:

    '+err);

    });

    }

    functionudpate(){

    $.ajax({

    url:

    "api/User/1",

    type:

    'PUT',

    dataType:

    "json",

    data:

    {Id:

    1,"UserName":

    "admin","PassWord":

    "666666"},

    success:

    function(data){

    document.getElementById("modes").innerHTML="";

    getAll();

    }

    }).fail(

    function(xhr,textStatus,err){

    alert('Error:

    '+err);

    });

    }

    这样就实现了最基本的CRUD操作。

    扩展需求

    问题1:

    我想按照用户名称(UserName)进行查询,怎么办?

    办法:

    第一步:

    在UserController类中加一个方法名称叫:

    GetUserByName,如下所示:

    publicUserModelGetUserByName(stringuserName){

    returnallModeList.Find((m)=>{returnm.UserName.Equals(userName);});

    }

    第二步:

    在客户端index.cshtml中调用

    functiongetUserByName(){

    $.ajax({

    url:

    "api/User/zhang",

    type:

    'GET',

    success:

    function(data){

    document.getElementById("modes").innerHTML="";

    varstr=data.UserName+':

    '+data.PassWord;

    $('

  • ',{html:

    str}).appendTo($('#modes'));

    }

    }).fail(

    function(xhr,textStatus,err){

    alert('Error:

    '+err);

    });

    }

    如果URL是:

    url:

    "api/User/zhang",将会报错:

    BadRequest

    原因是他会自动调用我们的GetOne(intid)这个方法,类型转换出错

    解决办法:

    改变URL为:

    url:

    "api/User/?

    userName=zhang",

    问题2:

    我想按用户名称(UserName)和用户密码(PassWord)一起来进行查询,怎么办?

    解决办法

    第一步:

    UserController类中,可以重载一个GetUserByName的方法,如下所示:

    publicUserModelGetUserByName(stringuserName){

    returnallModeList.Find((m)=>{returnm.UserName.Equals(userName);});

    }

    第二步:

    客户端调用:

    functiongetUserByName(){

    $.ajax({

    url:

    "api/User/?

    userName=zhang&passWord=123",//这里尤其需要注意

    type:

    'GET',

    success:

    function(data){

    document.getElementById("modes").innerHTML="";

    varstr=data.UserName+':

    '+data.PassWord;

    $('

  • ',{html:

    str}).appendTo($('#modes'));

    }

    }).fail(

    function(xhr,textStatus,err){

    alert('Error:

    '+err);

    });

    }

    (6)路由规则扩展

    和普通的MVC一样,MVCWebAPI支持自定义的路由规则,如:

    在上面的操作中,路由规则使用

    "api/{controller}/{id}"

    则限定了使用GET方式利用URL来传值时,controller后面的接收参数名为id,但是在Controller中,如果GetOne方法的接收参数名为key,是不会被匹配的,这是只需要新增一个新的路由规则,或修改原先的路由规则为:

    "api/{controller}/{key}",如下所示:

    config.Routes.MapHttpRoute(

    name:

    "DefaultApi",

    routeTemplate:

    "api/{controller}/{key}",

    defaults:

    new{key=RouteParameter.Optional}

    );

    当然,可以对路由进行更深的扩展,如:

    扩展成和普通MVC一样的路由:

    "api/{controller}/{action}/{id}"

    这样,就要求同时使用Action和HTTP方法进行匹配

    当然,根据微软的说法,这种使用是不被推荐的,因为这不符合大家对WebService的一般认知:

    (7)使用Attribute声明HTTP方法

    [HttpGet]

    publicIEnumerableFindAll()

    [HttpGet]

    publicIEnumerableFindByKey(stringkey)

    [HttpPost]

    publicboolAdd(TestUseModemode)

    [HttpDelete]

    publicintRemoveByKey(stringkey)

    [HttpDelete]

    publicintRemoveAll()

    [HttpPut]

    publicintUpdateByKey(stringkey,stringvalue)

    [NonAction]

    publicstringGetPrivateData()

    当然,我只列出了方法名,而不是这些方法真的没有方法体...方法体是不变的,NoAction表示这个方法是不接收请求的,即使以GET开头。

    如果感觉常规的GET,POST,DELETE,PUT不够用,还可以使用AcceptVerbs的方式来声明HTTP方法,如:

    [AcceptVerbs("MKCOL","HEAD")]

    publicintUpdateByKey(stringkey,stringvalue)

    {

    ListupDataList=allModeList.FindAll((mode)=>{if(mode.ModeKey==key)returntrue;returnfalse;});

    foreach(varmodeinupDataList)

    {

    mode.ModeValue=value;

    }

    returnupDataList.Count;

    }

    附:

    什么是REST风格?

    参考:

    什么是REST风格

    hi.baidu./yankaiwei/item/1f0b37dd922d53ef3cc2cb69

    第二部分:

    综合示例:

    应用ASP.NETMVC4+WebAPI+FluentData开发Web应用

    第一步:

    创建数据库

    NorthWind数据库的Customers表

    CreateDataBaseNorthWind

    Go

    UseNorthWind

    Go

    CREATETABLE[dbo].[Customers](

    [CustomerID][nchar](5)NOTNULL,

    [CompanyName][nvarchar](40)NOTNULL,

    [ContactName][nvarchar](30)NULL,

    [ContactTitle][nvarchar](30)NULL,

    [Address][nvarchar](60)NULL,

    [City][nvarchar](15)NULL,

    [Region][nvarchar](15)NULL,

    [PostalCode][nvarchar](10)NULL,

    [Country][nvarchar](15)NULL,

    [Phone][nvarchar](24)NULL,

    [Fax][nvarchar](24)NULL,

    CONSTRAINT[PK_Customers]PRIMARYKEYCLUSTERED

    [CustomerID]ASC

    )WITH(PAD_INDEX=OFF,STATISTICS_NORECOMPUTE=OFF,IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS=ON,ALLOW_PAGE_LOCKS=ON)ON[PRIMARY]

    )ON[PRIMARY]

    GO

    第二步:

    创建FluentData.Entity层,创建Customer实体类

    namespaceFluentData.Entity

    {

    publicclassCustomer

    {

    publicstringCustomerID{get;set;}

    publicstringCompanyName{get;set;}

    publicstringContactName{get;set;}

    publicstringContactTitle{get;set;}

    publicstringAddress{get;set;}

    publicstringCity{get;set;}

    publicstringRegion{get;set;}

    publicstringPostalCode{get;set;}

    publicstringCountry{get;set;}

    publicstringPhone{get;set;}

    publicstringFax{get;set;}

    }

    }

    第三步:

    利用FluentData做数据的持久化

    首先引入FluentData.cs(见附件)

    其次:

    创建DBHelper类,代码如下:

    publicclassDBHelper

    {

    publicstaticIDbContextContext(){

    //returnnewDbContext().ConnectionString("server=127.0.0.1;uid=sa;pwd=sa;database=TestDB",newSqlServerProvider());

    returnnewDbContext().ConnectionStringName("connString",newSqlServerProvider());

    }

    }

    然后不要忘记修改ASP.NETMVC层所在的Web.config,加入数据库连结字符串:

    第三步:

    创建CustomerService数据持久化类,代码如下:

    publicclassCustomerService

    {

    privateIDbContextcontext=DBHelper.Context();

    publicCustomerSelect(stringcustomerId){

    returncontext.Select("*").From("Customers").Where("CustomerID=0").Parameters(customerId)

    .QuerySingle();

    }

    publicListSelectAll(){

    returncontext.Select("*").From("Customers").QueryMany();

    }

    publicListSelectAll(stringsortEx

  • 展开阅读全文
    相关资源
    猜你喜欢
    相关搜索

    当前位置:首页 > 表格模板 > 合同协议

    copyright@ 2008-2022 冰豆网网站版权所有

    经营许可证编号:鄂ICP备2022015515号-1