我可以看到您的问题的答案有两个部分。
跨多个请求维护用户信息
通常,MVC API 应用程序将是无状态的,即您不保留请求之间的当前用户会话状态。嗯,这就是我在编写 RESTFul API 时学到或被多次宣扬的。
话虽如此,您可以通过将以下内容添加到 global.asax.cs 来启用 MVC Web API 中的会话状态
protected void Application_PostAuthorizeRequest()
{
// To enable session state in the WebAPI.
System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
在请求中授权客户
正如您在请求 URL 中所示,您可以添加客户名称,然后捕获该名称并将其传递给当前 http 模块调用以根据请求进行授权的同一例程。您可以使用 MVC 过滤器来做到这一点。
首先做一个类似的 URL 模式来在 WebApiConfig.cs 中捕获您的客户名称,类似这样;
config.Routes.MapHttpRoute(
name: "WithCustomerApi",
routeTemplate: "api/{customername}/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
然后将 ActionFilter 添加到您的 API 控制器,该控制器处理每个请求,检查当前会话信息,并在需要时调用您的授权/客户查找代码,然后保存到会话状态以供以后使用。或者如果客户没有好的信息可以发送到新的 MVC 路由
因此,您将添加一个类似这样的属性;
[WebApiAuthentication]
public class BaseApiController : ApiController
{
}
然后创建一个可能看起来像这样的操作过滤器(注意我没有测试过这个,只是为了一个如何做的模式)。
public class WebApiAuthenticationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var routeData = actionContext.ControllerContext.Request.GetRouteData();
var currentContext = HttpContext.Current;
if (routeData.Route.RouteTemplate.Contains("customername"))
{
try
{
var authenticated = currentContext.Request.IsAuthenticated;
if (!authenticated)
{
var customer = routeData.Values["customername"];
// do something with customer here and then put into session or cache
currentContext.Session.Add("CustomerName", customer);
}
}
catch (Exception exception)
{
var error = exception.Message;
// We dont like the request
actionContext.Response = new HttpResponseMessage(HttpStatusCode.BadRequest);
}
}
else
{
// No customer name specified, send bad request, not found, what have you ... you *could* potentially redirect but we are in API so it probably a service request rather than a user
actionContext.Response = new HttpResponseMessage(HttpStatusCode.NotFound);
}
}
}
如果您创建一个新的 MVC 5 Web API 应用程序并添加这些附加功能并将过滤器放在默认值控制器上,那么您应该能够看到它作为可能解决方案的演示运行。
如果一切正常,这将回显客户名称。
[WebApiAuthentication]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
var session = HttpContext.Current.Session;
if (session != null)
{
return new string[] {"session is present", "customer is", session["CustomerName"].ToString()};
}
return new string[] { "value1", "value2" };
}
}
正如我所说,我将其作为一种可能的解决方案提供,关于在 API 中存储会话和授权存在宗教争论,但这些不是问题所在。希望有帮助,史蒂夫