2013-08-13 31 views
23

Trong các dự án web hiện đại sử dụng RESTful API, chúng ta thường thấy các cuộc gọi AJAX giống như các tệp dưới đây rải rác xung quanh các tệp JavaScript của chúng tôi.Tạo một JS-client dựa trên ASP.NET WebAPI Controller

$.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 
}); 

Tôi yêu WebAPI, tôi yêu Knockout và tôi yêu buộc hai người lại với nhau. Tuy nhiên những AJAX cuộc gọi khá dài dòng và chứa tất cả các loại chi tiết mà tôi không thực sự quan tâm đến việc Vì vậy, thay vào đó, tôi có thể tạo một wrapper xung quanh các phương pháp:.

myapp.api.saveNote(note) 

Tuy nhiên điều này vẫn đòi hỏi tôi phải thực sự viết một wrapper có chứa cuộc gọi AJAX. Tôi đã tự hỏi nếu bạn thực sự có thể tạo ra các wrappers. Về bản chất, tôi sẽ tạo ra một máy khách dựa trên JS cho WebAPI của tôi, tương tự như cách Java và .NET có thể tạo ra các máy khách dựa trên WSDL.

  1. Điều này đã được thực hiện trước chưa?
  2. Có cách nào khác để kết hợp ASP.NET WebAPI và JavaScript với nhau mà không cần viết một loạt mã soạn sẵn AJAX không?
  3. Nói cách khác, có các khuôn khổ để tạo các giao diện JS dựa trên các giao diện phía máy chủ như ASP.NET WebAPI không?

Tôi đã xem amplifyJS nhưng điều này chỉ giải quyết được một phần vấn đề. Tôi đang tìm một giải pháp thực sự tạo ra một giao diện dựa trên các bộ điều khiển WebAPI trong giải pháp của tôi. Nếu điều này không tồn tại, tôi sẽ bắt đầu tự nhủ mình. Tôi đã có một ý tưởng cho một WebAPIClientGenerator sử dụng phản ánh để lặp qua tất cả các ApiController của.

Trả lời

30

Chỉ cần tìm thấy một dự án có tên: ProxyApi

ProxyApi là một thư viện tự động tạo Proxy Javascript đối tượng cho ASP.NET MVC của bạn và điều khiển WebAPI.

GitHub: https://github.com/stevegreatrex/ProxyApi

Blog: http://blog.greatrexpectations.com/2012/11/06/proxyapi-automatic-javascript-proxies-for-webapi-and-mvc/

ProxyApi tạo không hợp lệ JavaScript cho giải pháp của tôi trong đó có hơn một trăm hành động WebAPI riêng biệt. Điều này có thể do ProxyApi không bao gồm tất cả các tính năng WebApi như các thuộc tính ActionName tùy chỉnh. Hơn nữa các thư viện ProxyApi là một chút về phía cồng kềnh theo khẩu vị của tôi. Phải có một cách hiệu quả hơn để thực hiện việc này ...

Vì vậy, tôi quyết định xem xét mã nguồn ASP.NET WebAPI và hóa ra WebAPI có chức năng tự mô tả được tích hợp sẵn trong đó. Bạn có thể sử dụng mã sau từ bất kỳ đâu trong ASP của mình.NET giải pháp để truy cập WebAPI metadata:

var apiExplorer = GlobalConfiguration.Configuration.Services.GetApiExplorer(); 

Dựa trên sản lượng từ apiExplorer.ApiDescriptions, tôi cuộn cung cấp dịch vụ siêu dữ liệu của riêng tôi:

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; 
     } 
    } 
} 

Sử dụng điều khiển này kết hợp với quan điểm sau đây:

@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> 

Bộ điều khiển sẽ sử dụng ApiExplorer để tạo siêu dữ liệu về tất cả các hành động WebAPI có sẵn. Khung nhìn sẽ hiển thị dữ liệu này dưới dạng JSON và sau đó thực hiện một số JavaScript để chuyển đổi dữ liệu này thành các hàm JavaScript thực thi thực tế.

Để sử dụng chút phép thuật này, hãy chèn dòng sau vào đầu trang Bố cục của bạn sau tham chiếu jQuery của bạn.

@Html.Action(MVC.Metadata.WebApiDescription()) 

Từ giờ trở đi, bạn có thể thực hiện cuộc gọi WebAPI của bạn trông như thế này:

// 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  
}); 

Proxy đơn giản này sẽ tự động phân biệt các thông số chuỗi truy vấn từ các thông số yêu cầu cơ thể. Thiếu tham số hoặc nhiều thông số cơ thể sẽ tạo ra lỗi để ngăn lỗi phát triển WebAPI phổ biến của typo hoặc phổ biến khác.

+1

Làm thế nào tôi sẽ lấy Danh sách sử dụng phương thức GET? Có vẻ như Luôn luôn mong đợi thông số ID –

+1

Hoạt động awsome bằng cách này! –

+1

Tôi đã tìm ra, tôi vừa thêm 'if (typeof parameters! = 'Undefined' && parameters!= null) {' câu lệnh xung quanh khối kiểm tra tham số và thêm ' url = url.replace ("" {"" + tham số.Name + ""} "", ''); ' trong phần khác –

-1

Tôi đang làm việc trên Swagger mã nguồn mở toolchain NSwag cho NET: Với công cụ này bạn có thể tạo ra client nguyên cảo cho một hoặc nhiều bộ điều khiển Web API.

Trong giao diện người dùng chỉ

  1. Chọn DLL Web API
  2. Chọn các lớp điều khiển
  3. Tạo mã nguyên cảo của khách hàng (trong trường hợp của bạn, chọn JQueryCallbacks hoặc JQueryPromises mẫu)

Hãy xem http://nswag.org

FYI: TypeScript là ngôn ngữ được chuyển thành JavaScript

0

Dự án tuyệt vời khác này cho phép bạn làm những gì bạn yêu cầu. Bài viết này tự động tạo các proxy JavaScript cho các bộ điều khiển MVC và WebApi. Và, dự án này bao gồm các tính năng WebApi chẳng hạn như thuộc tính ActionName tùy chỉnh. Với dự án này, bạn cũng sẽ có Intellisense.
http://jsnet.codeplex.com/

Example of Intellisense

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); 

}); 
} 
Các vấn đề liên quan