2016-10-20 4 views
2

Какова наилучшая практика для размещения бизнес-логики в дизайне сообщений?(ServiceStack) Местоположение бизнес-логики в архитектуре на основе сообщений

Я использую служебную программу для строительства своего ави.

The wiki показывает пример размещения атрибута RequiredRole в сообщении вместо службы, обрабатывающей его.

В некотором смысле это [RequiredRole]/[Authenticate] - это бизнес-логика/безопасность, прилагаемая к сообщению.

Конкретный пример

Скажем, например, я хотел бы добавить DeleteAddress сообщение:

public class DeleteAddress : IReturn<bool> 
{ 
    public int AddressId { get; set; } 
} 

Но для этого, чтобы быть должным образом обеспечить я хочу проверить, либо роли администратора, разрешение на ManageAllAddresses или что AddressID связано для этого пользователя (возможно, в сеансе, возможно, через вызов db).

Как мне лучше всего поступить?

Предложение

Является ли следующий код хорошая практика, и если да, то как бы я это осуществить? рекомендация

[RequiredRole("Admin")] 
[RequiredPermission("ManageAllAddresses ")] 
[RequiredAddressLinkedToAccount] 
public class DeleteAddress : IReturn<bool> 
{ 
    public int AddressId { get; set; } 
} 
+0

thx для указателя на устаревшие документы в вики, мы обновим их до соответствия – mythz

ответ

1

ServiceStack является держать ServiceModel свободным от зависимостей поэтому мы рекомендуем, чтобы аннотировать службы классов реализации вместо которых вы можете аннотировать либо в классе обслуживания применяются ко всем операциям или по отдельным методам применения только к этой операции, например:

[RequiredRole("Admin")] 
public class AddressServices : Service 
{ 
    [RequiredPermission("ManageAllAddresses ")] 
    [RequiredAddressLinkedToAccount] 
    public object Any(DeleteAddress request) 
    { 
    } 
} 

Обратите внимание ServiceStack требует ваших услуг для возврата ссылочных типов, который обычно представляет собой DTO ответа, но также может быть a string, например:

public class DeleteAddress : IReturn<string> 
{ 
    public int AddressId { get; set; } 
} 
0

Чтобы закончить этот вопрос. Я могу создать фильтр запросов и добавить его в службу.

Либо наследовать от AuthenticateAttribute или непосредственно от RequestFilterAttribute.

public class RequiredAddressLinkedToAccount : AuthenticateAttribute 
{ 
    public RequiredRoleAttribute(ApplyTo applyTo) 
    { 
     this.ApplyTo = applyTo; 
     this.Priority = (int)RequestFilterPriority.RequiredRole; 
    } 



    public override void Execute(IRequest req, IResponse res, object requestDto) 
    { 
     var dto = requestDto as ILinkedToAccount; 
     var session = req.GetSession(); 
     if(dto.AccountId == session.Id) 
      return; //we dont want anything to be blocked if the account Id is there. 

     //Implement like RequireRoleAttribute 
     if (DoHtmlRedirectIfConfigured(req, res)) 
      return; 

     res.StatusCode = (int)HttpStatusCode.Forbidden; 
     res.StatusDescription = "Address does not belong to you"; 
     res.EndRequest(); 

    } 
}