コントローラでモデル検証を実行しますが、サービス/ビジネスレベルで2番目のビジネス検証が必要です。これは通常、ユーザー権限に関係します。現在のユーザーは、取得または投稿しようとしている顧客/注文情報にアクセスできますか?コントローラからサービス層へのすべての呼び出しに現在のユーザーを含める
User
インスタンス全体(User.Identity.GetUserId()
を呼び出すことによって)Id
のいずれかを渡すのが最初の(やはり効果的な)アプローチです。これはすべてではありません。だから私はこのようなものがあります:
public IHttpActionResult Get(int id)
{
try
{
var customer = customerService.GetById(id, userId);
return Ok(customer);
}
catch (BusinessLogicException e)
{
return CreateErrorResponse(e);
}
}
をしかし、私は本当にこのアプローチで、私はかなりの私のサービス層へのすべての呼び出しを追加のパラメータを含めるする必要がありますするつもりだという事実が好きではありません。 GetById()
メソッドを呼び出す場合は、ユーザーIDであるとではなく、IDを指定して何かを取得したいと考えています。
簡単な回避策も働くこれらの線に沿って何か、次のようになります。
public IHttpActionResult Get(int id)
{
customerService.SetCurrentUser(User.Identity.GetUserId());
try
{
var customer = customerService.GetById(id);
return Ok(customer);
}
catch (BusinessLogicException e)
{
return CreateErrorResponse(e);
}
}
しかし、その代わりに現在のユーザーを設定するための別の呼び出しを行うために持つのを、私はこれがで自動的に行うことがしたいのですがサービスへのすべての呼び出し。どうしたらいいですか?
public class CustomerService : EntityService<Customer>, ICustomerService
{
public string UserId;
IContext context;
public CustomerService(IContext context) : base(context)
{
this.context = context;
this.dbSet = context.Set<Customer>();
}
public void SetCurrentUser(string userId)
{
UserId = userId;
}
public DTO.Customer GetById(int id)
{
if (!IsAccessibleByUser(id))
{
throw new BusinessLogicException(ErrorCode.UserError, "UserId: " + UserId);
}
return dbSet.FirstOrDefault(x => x.Id == id).ToDto<Customer, DTO.Customer>();
}
public bool IsAccessibleByUser(int id)
{
return context.UsersAPI.Any(a => a.AspNetUsersID == UserId);
}
}
トークンが有効でない場合、またはユーザーが必要な役割を持っていない場合には、私はすでに、特定のエラーメッセージを返すように 'CustomAuthorizeAttribute'を使用しています。このアプローチは、私のビジネスロジック層で検証ロジックの*トン*を取り除くので非常に興味深いようですが、私のアプリケーションのどこか他の場所で多くの検証ロジックを持つのはちょっと変です。それ以外に、あなたは最後の段落に展開できますか?私のデータコンテキスト(私のサービス、この場合)を認証フィルタに注入することは、このアプローチを使用するために解決しなければならない別の問題のように思えます。 – Antrim
依存性注入が必要な場合は私の答えで既に述べたように、あなたが使用する必要があるのはカスタムフィルタプロバイダだけです。したがって、いくつかの検索の後で、あなたが見つけるかもしれません:http://haacked.com/archive/2011/04/25/conditional-filters.aspx/あなたのコントローラのアクションのマーカー属性は、必要に応じてカスタムフィルタプロバイダで検出することができます承認ロジックを適用します。そしてあなたは自分自身に尋ねるべきです:私は気にしなければならない私のMVCアプリケーションの外にこの*ビジネス層*を使用していますか?もしそうなら、おそらくこのビジネスレイヤーはすでにRESTfulファサードの後ろに包まれています。 –
私はあなたのためにすべてのコードを書いて、周りを見て、実験して、特定の質問を持っている場合は戻ってくるのを待つだけではありません。 –