在使用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
。
答案 0 :(得分:30)
刚刚找到一个名为的项目: ProxyApi
ProxyApi是一个自动创建JavaScript代理的库 ASP.NET MVC和WebApi控制器的对象。
GitHub:https://github.com/stevegreatrex/ProxyApi
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函数。
要使用这一点魔法,请在
@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开发错误。
答案 1 :(得分:1)
我正在研究用于.NET的Swagger开源工具链 NSwag :使用此工具,您可以为单个或多个Web API控制器生成TypeScript客户端
在UI中
JQueryCallbacks
或JQueryPromises
模板)仅供参考:TypeScript是一种可以转换为JavaScript的语言
答案 2 :(得分:0)
这个优秀的另一个项目可以让你做你想要的。
此项目自动生成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);
});
}