Только что нашел проект под названием ProxyApi.
ProxyApi — это библиотека, которая автоматически создает прокси-объекты JavaScript для ваших контроллеров ASP.NET MVC и WebApi.
GitHub: https://github.com/stevegreatrex/ProxyApi
Блог: http:// blog.greatreexpectations.com/2012/11/06/proxyapi-automatic-javascript-proxy-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.
@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.
person
Martin Devillers
schedule
13.08.2013