我决定为我正在开发的应用程序使用 Web API(作为中间层),但似乎无法弄清楚如何将它“绑定”到前端(前端是 ASP.NET MVC4项目)。通常,我只需右键单击前端的服务,选择“添加服务引用”,然后将我的服务的 URL 放入其中。但是使用 Web API,我不能这样做。有哪些选项可以从我的 Web API 创建客户端代理类以在我的前端使用,为什么不添加 Web API 支持作为参考,就像添加 WCF 或 ASMX 一样?
4 回答
你的意思是一个 Rest Web 服务?使用 Rest,没有服务定义页面,就像使用 WCF 或 ASMX。通常人们希望使用带有 JSON 的 Rest API。但是。如果您只是在寻找 JSON 输出,并且希望您的客户端能够快速连接到您的服务,您应该考虑使用 OData。它非常容易创建,它使您的数据层可用于大量客户端语言。他们为大量语言移植了 OData 客户端库。按要求作为答案提交。:)
为什么不以与添加 WCF 或 ASMX 相同的方式添加 Web API 支持作为参考
基于 WCF 或 ASMX 的 Web 服务是基于 SOAP 的,并且通常有一个关联的 WSDL。WSDL 允许构建工具以生成代理类和所有这些,但 ASP.NET Web API 旨在构建 REST(或基于 HTTP)服务,并且没有 WSDL 或任何类似形式的元数据,因此添加了服务引用通过 VS 不适用于 ASP.NET Web API。WADL(Web 应用程序描述语言)应该是 REST 的 WSDL,但该规范没有去向。
这里有一个通用的 WebAPI 客户端:
https://github.com/CamSoper/CamTheGeek
根据要求,它不是代理,但它确实填补了空白。
这是源代码:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
namespace CamTheGeek
{
public class GenericWebApiClient<T> : IDisposable where T : class
{
HttpClient client = new HttpClient();
Uri ServiceBaseUri;
public GenericWebApiClient(Uri ServiceUri)
{
if(ServiceUri == null)
{
throw new UriFormatException("A valid URI is required.");
}
ServiceBaseUri = ServiceUri;
}
public List<T> GetAll()
{
var response = client.GetAsync(ServiceBaseUri).Result;
if(response.IsSuccessStatusCode)
{
return response.Content.ReadAsAsync<List<T>>().Result as List<T>;
}
else if (response.StatusCode != HttpStatusCode.NotFound)
{
throw new InvalidOperationException("Get failed with " + response.StatusCode.ToString());
}
return null;
}
public T GetById<I>(I Id)
{
if (Id == null)
return default(T);
var response = client.GetAsync(ServiceBaseUri.AddSegment(Id.ToString())).Result;
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsAsync<T>().Result as T;
}
else if (response.StatusCode != HttpStatusCode.NotFound)
{
throw new InvalidOperationException("Get failed with " + response.StatusCode.ToString());
}
return null;
}
public void Edit<I>(T t, I Id)
{
var response = client.PutAsJsonAsync(ServiceBaseUri.AddSegment(Id.ToString()), t).Result;
if (!response.IsSuccessStatusCode)
throw new InvalidOperationException("Edit failed with " + response.StatusCode.ToString());
}
public void Delete<I>(I Id)
{
var response = client.DeleteAsync(ServiceBaseUri.AddSegment(Id.ToString())).Result;
if (!response.IsSuccessStatusCode)
throw new InvalidOperationException("Delete failed with " + response.StatusCode.ToString());
}
public void Create(T t)
{
var response = client.PostAsJsonAsync(ServiceBaseUri, t).Result;
if (!response.IsSuccessStatusCode)
throw new InvalidOperationException("Create failed with " + response.StatusCode.ToString());
}
public void Dispose(bool disposing)
{
if (disposing)
{
client = null;
ServiceBaseUri = null;
}
}
public void Dispose()
{
this.Dispose(false);
GC.SuppressFinalize(this);
}
~GenericWebApiClient()
{
this.Dispose(false);
}
}
static class UriExtensions
{
public static Uri AddSegment(this Uri OriginalUri, string Segment)
{
UriBuilder ub = new UriBuilder(OriginalUri);
ub.Path = ub.Path + ((ub.Path.EndsWith("/")) ? "" : "/") + Segment;
return ub.Uri;
}
}
}
要使用或使用 REST 服务,您只需要调用 api 和方法
将 API_BASE 放在一个地方(变量或配置文件)是一个很好的做法,以防您需要测试发布到另一台服务器的相同内容
public class ProductosDAL
{
public static string API_BASE = "http://localhost:54234/api/" ;
private static string apiPath(string method)
{
return string.Format("{0}{1}", API_BASE, method);
}
public static async Task<List<ProductoEntity>> GetProductosAsync()
{
List<ProductoEntity> lstProd = new List<ProductoEntity>();
using (var httpClient = new HttpClient())
{
using (var response = await httpClient.GetAsync(apiPath("productos")))
{
string apiResponse = await response.Content.ReadAsStringAsync();
lstProd = JsonConvert.DeserializeObject<List<ProductoEntity>>(apiResponse);
}
}
return lstProd;
}
}
我的例子是对这个伟大的指南https://www.yogihosting.com/aspnet-core-consume-api/的一点改进