2016-11-10 105 views
0

我有不同的Web API控制器,使用声明进行保护。所以,在我的控制器中,我使用了asp.net Identity,而User.Identity是ClaimsIdentity类型。如何使用WebApi和自定义值绑定器将属性绑定到复杂对象?

其中一个声明是当前userId登录到应用程序。

当我发布像订单这样的复杂对象作为实例并且该订单具有如下例所示的属性UserId时,我希望该属性由索赔中的值填充。

class Order 
{ 
    public int Quantity { get; set; } 
    public int ProductId { get; set; } 
    public int UserId { get; set; } 
} 

class OrdersController : BaseApiController 
{ 
    [HttpPost] 
    public IHttpActionResult Post(Order order) 
    { 
    // do something 
    return Ok(); 
    } 
} 

所以,我要的是有数量和ProducId属性来填充来自请求的主体,以及从权利要求的用户ID来值。

我试图创建类似以下的自定义值提供商:

public class IdentityClaimsValueProvider : IValueProvider 
{ 
    private readonly Dictionary<string, string> _claims; 
    private readonly string[] _claimsKeys; 

    public IdentityClaimsValueProvider(Dictionary<string, string> claims) 
    { 
     _claims = claims; 
     _claimsKeys = claims.Keys.ToArray(); 
    } 

    public bool ContainsPrefix(string prefix) 
    { 
     if (prefix == null) 
      throw new ArgumentNullException(nameof(prefix)); 

     return _claimsKeys.Any(x => prefix.Equals(x, StringComparison.OrdinalIgnoreCase)); 
    } 

    public ValueProviderResult GetValue(string key) 
    { 
     if (key == null) 
      throw new ArgumentNullException(nameof(key)); 

     var claim = _claimsKeys.FirstOrDefault(x => key.Equals(x, StringComparison.OrdinalIgnoreCase)); 
     if (claim != null && _claims[claim] != null) 
     { 
      return new ValueProviderResult(_claims[claim], _claims[claim], CultureInfo.CurrentCulture); 
     } 

     return null; 
    } 
} 

public class IdentityClaimsValueProviderFactory : ValueProviderFactory 
{ 
    public override IValueProvider GetValueProvider(HttpActionContext actionContext) 
    { 
     var controller = actionContext.ControllerContext.Controller as WebApiBaseController; 
     if (controller == null) 
      return null; 

     var claims = controller.GetUserIdentity().Claims; 

     var claimsValues = new Dictionary<string, string> 
     { 
      { "userId", claims.First(x => x.Type == Common.Constants.ClaimTypes.USER_ID).Value } 
     }; 

     return new IdentityClaimsValueProvider(claimsValues); 
    } 
} 

我也添加到了我的配置:

config.Services.Add(typeof(ValueProviderFactory), new IdentityClaimsValueProviderFactory()); 

但是,这并不工作。当我做一个帖子,我有产品数量和产品编号性填充,而不是用户ID

回答

0

您必须更改操作的签名:

public IHttpActionResult Post([ValueProvider(typeof(IdentityClaimsValueProviderFactory))]string userId, Order order) 

如果你想有USEID的价值订单属性,您必须更改类IdentityClaimsValueProviderFactory

此致。