自從開始使用ASP.NET Web API,各種路由的蛋疼問題一直困擾著我,相信大家也都一樣。
Web API的路由配置與ASP.MVC類似,在App_Start文件夾下,有一個WebApiConfig類文件config.Routes.MapHttPRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional });以上為一個空Web API項目的路由配置。我們新建一個Controllerpublic class TestRouteController : ApiController{ public HttpResponseMessage GetUser(int id) { return Request.CreateResponse(HttpStatusCode.OK, new { status = "success", data = new { Id = id, Name = "用戶" + id } }); }}按照msdn所述To find the action, Web API looks at the HTTP method, and then looks for an action whose name begins with that HTTP method name. For example, with a GET request, Web API looks for an action that starts with "Get...", such as "GetContact" or "GetAllContacts". This convention applies only to GET, POST, PUT, and DELETE methods. You can enable other HTTP methods by using attributes on your controller. We’ll see an example of that later.Web API 約定了,如果方法名帶有Get,則為Get請求,其他請求方式同樣道理當然,我們也可以使用HttpGet、HttpPost等特性,或者AcceptVerbs("GET","POST",...)等等,來控制我們的請求方式。根據(jù)路由配置,我們可以理解,我們的訪問地址應(yīng)為:api/TestRoute/123,請求方式為GET 毫無疑問的,我們拿到了想要的結(jié)果:{"status":"success","data":{"Id":123,"Name":"用戶123"}}按照我們之前MVC路由的理解,路由中,new { id = RouteParameter.Optional }表示id參數(shù)是可選參數(shù),我們期望的,在沒有id傳入的情況下,地址可以正常訪問,id為默認值0。很遺憾,直接404了。我們簡單改動一下代碼public HttpResponseMessage GetUser(int id = 0){ return Request.CreateResponse(HttpStatusCode.OK, new { status = "success", data = new { Id = id, Name = "用戶" + id } });}我們將方法參數(shù)id設(shè)定了一個默認值,居然成功了我們再變一種訪問方式,api/TestRoute/?id=123在有參數(shù)的情況下,是可以正常訪問的。而訪問api/TestRoute/?id=,則會出現(xiàn) {"Message":"請求無效。","MessageDetail":"對于“WebApiTest.Controllers.TestRouteController”中方法“System.Net.Http.HttpResponseMessage GetUser(System.DateTime)”的不可以為 null 的類型“System.DateTime”的參數(shù)“time”,參數(shù)字典包含一個 null 項。可選參數(shù)必須為引用類型、可以為 null 的類型或聲明為可選參數(shù)。"}的400錯誤。將id參數(shù)設(shè)定為int?類型,我們訪問http://localhost:62488/api/TestRoute/?id=則可正常訪問,并且此時id為null。經(jīng)過以上的測試,我們是否可以得出結(jié)論:在ASP.NET Web API中,并且我們熟知的C# int未賦值時默認0,bool未賦值時默認false等在此都是不適用的如果請求的參數(shù)在方法上定義,則參數(shù)名必須拼接在訪問地址上我們再試一種情況,我們將需要傳入的參數(shù)放到一個類中,在方法上直接傳入這個參數(shù)對象public class QueryParams{ public int Id { get; set; } public string Name { get; set; }}public HttpResponseMessage GetUser(QueryParams queryParams){ return Request.CreateResponse(HttpStatusCode.OK, new { status = "success", data = new { Id = queryParams.Id, Name = "用戶:" + queryParams.Name } }); }直接訪問api/TestRoute/,我們會發(fā)現(xiàn),不管我們是否傳入?yún)?shù),我們的參數(shù)對象都是null。這時候我們需要為我們的參數(shù)對象添加一個FromUri的特性,來告訴web api,我們這個對象的中屬性都是從url鏈接上傳過來的這時候依舊不傳入任何參數(shù),卻驚奇的發(fā)現(xiàn),我們的對象參數(shù)不再是null,其中屬性的值也與我們料想的一致(C# int未賦值時默認0,string默認null)經(jīng)過這進一步的嘗試,我們可以完善我們的結(jié)論通過queryString方法拼接參數(shù)時如果請求的參數(shù)為C#語法定義的類型,且在方法上定義,則參數(shù)名必須拼接在訪問地址上如果請求的參數(shù)為一個實體類,則需要為該參數(shù)添加[FromUri]的特性。
|
新聞熱點
疑難解答