2016-11-10 3 views
0

Ich habe verschiedene Web-API-Controller, die mit Ansprüchen gesichert sind. In meinen Controllern verwende ich die asp.net-Identität und die User.Identity ist vom Typ ClaimsIdentity.Wie binden Sie eine Eigenschaft an ein komplexes Objekt mit WebApi und einem benutzerdefinierten Wertordner?

Einer dieser Ansprüche ist die aktuelle userId, die in der Anwendung protokolliert wird.

Wenn ich ein komplexes Objekt wie einen Auftrag für Beispiel posten und dass Auftrag eine Eigenschaft UserId wie das folgende Beispiel hat, möchte ich, dass diese Eigenschaft mit dem Wert gefüllt wird, der in dem Anspruch ist.

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(); 
    } 
} 

Also, was ich will, ist die Menge und ProducId Eigenschaften hat mit Werten gefüllt werden aus dem Körper des Antrags kommen, und der Benutzer-ID aus den Ansprüchen.

Ich habe versucht, einen benutzerdefinierten Wert Provider wie folgt zu erstellen:

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); 
    } 
} 

Ich habe auch das meine config:

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

Aber das funktioniert nicht. Wenn ich einen Beitrag zu machen, habe ich die Menge und ProductId Eigenschaften gefüllt, aber nicht die UserId

Antwort

0

Sie müssen die Signatur der Aktion ändern:

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

Wenn Sie den Wert von useId haben wollen in Bestellung Eigentum, müssen Sie die Klasse IdentityClaimsValueProviderFactory

Grüße ändern.

Verwandte Themen