我在同一个ASP.NET项目中有一个ApiController和一个Controller。我的想法是,我想向第三方公开REST API,并在我公开的REST API之上构建网站。
我想从我的MVC控制器(在ProfileController中)使用REST API(在ProfileApiController中)。这两个控制器都需要进行身份验证,并且ProfileApiController的响应取决于活动的User.Identity。
我该如何实现?
代码如下:
namespace Controllers
{
[Authorize]
public class ProfileApiController : ApiController
{
[Route("api/profile/{param}")]
[HttpGet]
public async Task<IHttpActionResult> GetProfile(string param)
{
return this.Ok<IEnumerable<TransferObject>>( /* business logic */ );
}
}
[Authorize]
public class ProfileController : Controller
{
public async Task<ActionResult> GetProfile()
{
//Pseudocode -- this is what I'm looking for
var api = (reference_to_profileapicontroller);
api.Authenticate(User.Identity);
var m = api.GetProfile("myparameter");
//End Pseudocode
return View(m):
}
}
}
我已经尝试了两种方法:
通过HttpClient调用WebApi
HttpClientHandler h = new HttpClientHandler();
var client = new HttpClient(h);
var response = client.GetAsync("http://localhost:4827/api/profile/param/").Result;
var m = await response.Content.ReadAsAsync<List<TransferObject>>();
return View(m);
但是在这里,我坚持将身份从Controller传递到ApiController
直接调用控制器
var pc = DependencyResolver.Current.GetService<ProfileController>();
var r = await pc.GetTenseProfile("param");
var rr = await r.ExecuteAsync(System.Threading.CancellationToken.None);
var m = await rr.Content.ReadAsAsync<List<TransferObject>>();
return View(m);
但这变成一团糟,因为需要配置pc.Configuration和pc.Request。这不应该很难吗?
我会按此顺序走3条路线中的一条。
将Controller
和通用的逻辑ApiController
移到一个类中,然后在控制器中使用该类。
[Authorize]
public class ProfileApiController : ApiController
{
[Route("api/profile/{param}")]
[HttpGet]
public async Task<IHttpActionResult> GetProfile(string param)
{
// have all business logic in this class
ProfileClass = newClass = new ProfileClass();
IList<TransferObject> vm = newClass.GetData(); // from bus rules
return this.Ok<IList<TransferObject>>(vm);
}
}
[Authorize]
public class ProfileController : Controller
{
public async Task<ActionResult> GetProfile()
{
// have all business logic in this class
ProfileClass = newClass = new ProfileClass();
IList<TransferObject> vm = newClass.GetData(); // from bus rules
return View(vm):
}
}
通过AJAX使用您的API。这是更多的服务器往返,但是使用了您设计的API。使用视图中的参数对API控制器进行AJAX调用。
[Authorize]
public class ProfileController : Controller
{
public async Task<ActionResult> GetProfile()
{
return View("myparameter"):
}
}
使用基于声明的身份验证,其中包括请求中的标头。如果您要保护自己的API,那么您可能已经在这样做了。使用上面列出的HttpClient,然后仅根据MVC中的用户在标题中添加承载令牌。
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
这也可能会有所帮助:http : //www.asp.net/web-api/overview/security/individual-accounts-in-web-api
选项2和3中有很多冗余代码。对于您的控制器来说,最好不要使用业务逻辑,而让您的代码使用它。我认为在每个Action的MVC代码中的各处都必须创建HttpRequest并不是一个好习惯。当您必须重构时,这将导致很多麻烦。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句