[英]Generating a JS-client based on a ASP.NET WebAPI Controller
在使用RESTful API的現代Web項目中,我們經常會看到AJAX調用,就像下面的JavaScript文件一樣。
$.ajax({
type: "POST",
url: myapp.baseUrl + 'Api/Note',
data: ko.mapping.toJSON(note),
contentType: 'application/json',
}).done(function (response) {
// do something
}).fail(function (jqxhr) {
// do something else
});
我喜歡WebAPI,我喜歡Knockout,我喜歡將兩者結合在一起。 然而,這些AJAX調用非常冗長,包含了我並不感興趣的各種細節。相反,我創建了一個圍繞這些方法的包裝器:
myapp.api.saveNote(note)
但是,這仍然需要我實際編寫一個包含AJAX調用的包裝器。 我想知道你是否真的可以生成這些包裝器 。 本質上,我將為我的WebAPI生成一個基於JS的客戶端,類似於Java和.NET如何基於WSDL生成客戶端。
我已經看過amplifyJS,但這只能部分地解決問題。 我正在尋找一種解決方案,它實際上在我的解決方案中基於WebAPI控制器創建了一個接口。 如果這不存在,我會開始修補自己。 我已經有了一個WebAPIClientGenerator
的想法,它使用反射迭代所有的ApiController
。
剛剛找到一個叫做ProxyApi的項目
ProxyApi是一個自動為ASP.NET MVC和WebApi控制器創建JavaScript代理對象的庫。
GitHub: https : //github.com/stevegreatrex/ProxyApi
博客: http : //blog.greatrexpectations.com/2012/11/06/proxyapi-automatic-javascript-proxies-for-webapi-and-mvc/
ProxyApi為我的解決方案生成了無效的JavaScript,其中包含一百多個單獨的WebAPI操作。 這可能是因為ProxyApi未涵蓋所有WebApi功能,例如自定義ActionName屬性。 此外,ProxyApi庫對我來說有點笨重。 必須有一種更有效的方法來做到這一點......
所以我決定看一下ASP.NET WebAPI源代碼,結果發現WebAPI內置了自我描述功能。 您可以從ASP.NET解決方案的任何位置使用以下代碼來訪問WebAPI元數據:
var apiExplorer = GlobalConfiguration.Configuration.Services.GetApiExplorer();
根據apiExplorer.ApiDescriptions
的輸出,我推出了自己的元數據提供程序:
public class MetadataController : Controller { public virtual PartialViewResult WebApiDescription() { var apiExplorer = GlobalConfiguration.Configuration.Services.GetApiExplorer(); var apiMethods = apiExplorer.ApiDescriptions.Select(ad => new ApiMethodModel(ad)).ToList(); return PartialView(apiMethods); } public class ApiMethodModel { public string Method { get; set; } public string Url { get; set; } public string ControllerName { get; set; } public string ActionName { get; set; } public IEnumerable<ApiParameterModel> Parameters { get; set; } public ApiMethodModel(ApiDescription apiDescription) { Method = apiDescription.HttpMethod.Method; Url = apiDescription.RelativePath; ControllerName = apiDescription.ActionDescriptor.ControllerDescriptor.ControllerName; ActionName = apiDescription.ActionDescriptor.ActionName; Parameters = apiDescription.ParameterDescriptions.Select(pd => new ApiParameterModel(pd)); } } public class ApiParameterModel { public string Name { get; set; } public bool IsUriParameter { get; set; } public ApiParameterModel(ApiParameterDescription apiParameterDescription) { Name = apiParameterDescription.Name; IsUriParameter = apiParameterDescription.Source == ApiParameterSource.FromUri; } } }
將此控制器與以下視圖結合使用:
@model IEnumerable<Awesome.Controllers.MetadataController.ApiMethodModel> <script type="text/javascript"> var awesome = awesome || {}; awesome.api = { metadata: @Html.Raw(Json.Encode(Model)) }; $.each(awesome.api.metadata, function (i, action) { if (!awesome.api[action.ControllerName]) { awesome.api[action.ControllerName] = {}; } awesome.api[action.ControllerName][action.ActionName] = function (parameters) { var url = '/' + action.Url; var data; $.each(action.Parameters, function (j, parameter) { if (parameters[parameter.Name] === undefined) { console.log('Missing parameter: ' + parameter.Name + ' for API: ' + action.ControllerName + '/' + action.ActionName); } else if (parameter.IsUriParameter) { url = url.replace("{" + parameter.Name + "}", parameters[parameter.Name]); } else if (data === undefined) { data = parameters[parameter.Name]; } else { console.log('Detected multiple body-parameters for API: ' + action.ControllerName + '/' + action.ActionName); } }); return $.ajax({ type: action.Method, url: url, data: data, contentType: 'application/json' }); }; }); </script>
控制器將使用ApiExplorer
生成有關所有可用WebAPI操作的元數據。 該視圖將此數據呈現為JSON,然后執行一些JavaScript以將此數據轉換為實際的可執行JavaScript函數。
要使用這一點魔力,請在 jQuery引用之后在Layout頁面的頭部插入以下行。
@Html.Action(MVC.Metadata.WebApiDescription())
從現在開始,您可以使WebAPI調用如下所示:
// GET: /Api/Notes?id={id} awesome.api.Notes.Get({ id: id }).done(function () { // .. do something cool }); // POST: /Api/Notes awesome.api.Notes.Post({ form: formData }).done(function () { // .. do something cool });
這個簡單的代理將自動區分查詢字符串參數和請求主體參數。 缺少參數或多個正文參數將生成錯誤以防止拼寫錯誤或其他常見的WebAPI開發錯誤。
我正在使用Swagger開源工具鏈NSwag for .NET:使用此工具,您可以為單個或多個Web API控制器生成TypeScript客戶端 。
在UI中
JQueryCallbacks
或JQueryPromises
模板) 僅供參考: TypeScript是一種可以轉換為JavaScript的語言
這個優秀的另一個項目可以讓你做你想要的。 此項目自動生成MVC和WebApi控制器的JavaScript代理。 而且,該項目涵蓋了WebApi功能,例如自定義ActionName屬性。 通過這個項目,您還將擁有Intellisense。
http://jsnet.codeplex.com/
window.test = function test() {
/// <summary>
///This example works.
///You have the Intellisense. It's great!!!
///No hard coded url.
///</summary>
//-- settings of ajax request.
var a = $dpUrlSet.Customer.Create.$action0.$AjaxSettings();
//-- your parameters of action method
a.data.name = "Scott Gu";
a.data.address = "Somewhere in Redmond";
//-- stringify
a.data = JSON.stringify(a.data);
//-- send ajax request
var xhr = $.ajax(a);
xhr.success(function (id) {
/// <summary>Response of ajax request</summary>
//-- settings of ajax request.
var a = $dpUrlSet.Customer.Update.$action0.$AjaxSettings();
//-- your parameters of action method
a.data.id = id;
a.data.name = "Scott Gu";
a.data.address = "Somewhere in Seattle";
//-- stringify
a.data = JSON.stringify(a.data);
//-- send ajax request
var xhr = $.ajax(a);
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.