C# 为什么可以';t我们添加一个Web API作为";服务参考“;在VisualStudio中,我们可以使用WCF或ASMX使用相同的方法吗?
我决定将Web API(作为中间层)用于我正在开发的应用程序,但似乎不知道如何将其“绑定”到前端(前端是ASP.NET MVC4项目)。通常,我只需右键单击前端的服务,选择“添加服务引用”,然后将我的服务的URL放入。但是有了WebAPI,我就不能这么做了。在我的前端使用Web API创建客户端代理类有哪些选项,为什么Web API不支持以与添加WCF或ASMX相同的方式添加为引用 为什么Web API不支持添加为引用,就像添加WCF或ASMX一样C# 为什么可以';t我们添加一个Web API作为";服务参考“;在VisualStudio中,我们可以使用WCF或ASMX使用相同的方法吗?,c#,asp.net-mvc-4,service,asp.net-web-api,C#,Asp.net Mvc 4,Service,Asp.net Web Api,我决定将Web API(作为中间层)用于我正在开发的应用程序,但似乎不知道如何将其“绑定”到前端(前端是ASP.NET MVC4项目)。通常,我只需右键单击前端的服务,选择“添加服务引用”,然后将我的服务的URL放入。但是有了WebAPI,我就不能这么做了。在我的前端使用Web API创建客户端代理类有哪些选项,为什么Web API不支持以与添加WCF或ASMX相同的方式添加为引用 为什么Web API不支持添加为引用,就像添加WCF或ASMX一样 基于WCF或ASMX的web服务是基于SOAP
基于WCF或ASMX的web服务是基于SOAP的,通常有一个关联的WSDL。WSDL允许围绕生成代理类和所有这些构建工具,但ASP.NET Web API旨在构建REST(或基于HTTP的)服务,并且没有WSDL或任何类似形式的元数据,因此通过VS添加服务引用不适用于ASP.NET Web API。WADL(Web应用程序描述语言)本应是REST的WSDL,但该规范没有达到任何目的。您是指REST Web服务吗?对于Rest,没有服务定义页面,就像WCF或ASMX一样。通常人们希望将RESTAPI与JSON结合使用。。然而。。如果您正在寻找JSON输出,并且希望客户端快速连接到您的服务,则应该考虑ODATA。它非常容易创建,并且可以让大量客户端语言访问您的数据层。他们为大量语言移植了OData客户端库。按要求作为答复提交。:) 这里有一个通用的WebAPI客户端: 它不是一个代理,但它确实填补了这个空白 以下是源代码:
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;
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统配置;
使用System.Linq;
Net系统;
使用System.Net.Http;
使用System.Web;
名称空间CamTheGeek
{
公共类GenericWebApicClient:IDisposable其中T:class
{
HttpClient=新的HttpClient();
uriservicebaseuri;
公共GenericWebApicClient(Uri服务Uri)
{
if(ServiceUri==null)
{
抛出新的UriFormatException(“需要有效的URI”);
}
ServiceBaseUri=ServiceUri;
}
公共列表GetAll()
{
var response=client.GetAsync(ServiceBaseUri).Result;
if(响应。IsSuccessStatusCode)
{
返回response.Content.ReadAsAsync()。结果为列表;
}
else if(response.StatusCode!=HttpStatusCode.NotFound)
{
抛出新的InvalidOperationException(“获取失败,返回“+response.StatusCode.ToString()”);
}
返回null;
}
公共T GetById(I Id)
{
if(Id==null)
返回默认值(T);
var response=client.GetAsync(ServiceBaseUri.AddSegment(Id.ToString()).Result;
if(响应。IsSuccessStatusCode)
{
返回response.Content.ReadAsAsync()。结果为T;
}
else if(response.StatusCode!=HttpStatusCode.NotFound)
{
抛出新的InvalidOperationException(“获取失败,返回“+response.StatusCode.ToString()”);
}
返回null;
}
公共无效编辑(T,I Id)
{
var response=client.PutAsJsonAsync(ServiceBaseUri.AddSegment(Id.ToString()),t);
如果(!response.issucessStatusCode)
抛出新的InvalidOperationException(“编辑失败,带有“+response.StatusCode.ToString()”);
}
公共无效删除(I Id)
{
var response=client.deleteAncy(ServiceBaseUri.AddSegment(Id.ToString()).Result;
如果(!response.issucessStatusCode)
抛出新的InvalidOperationException(“删除失败,带有“+response.StatusCode.ToString()”);
}
公共无效创建(T)
{
var response=client.PostAsJsonAsync(ServiceBaseUri,t).Result;
如果(!response.issucessStatusCode)
抛出新的InvalidOperationException(“创建失败,带有“+response.StatusCode.ToString()”);
}
公共无效处置(bool处置)
{
如果(处置)
{
client=null;
ServiceBaseUri=null;
}
}
公共空间处置()
{
本.处置(假);
总干事(本);
}
~GenericWebApiClient()
{
本.处置(假);
}
}
静态类扩展
{
公共静态Uri AddSegment(此Uri源代码,字符串段)
{
UriBuilder ub=新的UriBuilder(OriginalUri);
ub.Path=ub.Path+((ub.Path.EndsWith(“/”)):“/”)+段;
返回ub.Uri;
}
}
}
要使用或使用REST服务,您只需要调用api和方法
将API_库放在一个位置(变量或配置文件)是一种很好的做法,以防您需要测试发布到另一台服务器上的API_库
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;
}
}
公共类ProductosDAL
{
公共静态字符串API_BASE=”http://localhost:54234/api/" ;
私有静态字符串路径(字符串方法)
{
返回string.Format(“{0}{1}”,API_基,方法);
}
公共静态异步任务GetProductosAsync()
{
List lstProd=新列表();
使用(var httpClient=new httpClient())
{
使用(var response=wait-httpClient.GetAsync(apiPath(“productos”))
{
字符串apiResponse=等待响应