【问题标题】:How to specify attribute on call of method如何在方法调用时指定属性
【发布时间】:2014-11-21 05:46:53
【问题描述】:

我有一种操作方法。 有 2 个属性

[Authorization]
[OutputCache]
ActionResult LoadImage()

我从两个方法调用 LoadImage 动作 说 1:索引 2:创建

当我从 Index 调用 LoadImage 操作时,我希望 LoadImage 的两个属性都执行。 当我从 Create 调用 LoadImage 操作时,我只想执行 Authorization 属性。 我不想使用 VaryByParam。

【问题讨论】:

  • 你能不能简单地有两个不同的方法,每个方法调用一个通用的方法来做实际的工作?
  • 那么这将是 redendent 代码。并且不会被接受。
  • 我不相信这是可能的。 ASP.NET 不执行堆栈跟踪反射来确定调用者。
  • @HemantMalpote 如果你把它放在另一个方法中,这两个方法都调用,这不是多余的。

标签: c# asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


【解决方案1】:

请查看我之前的回答,看看是否满足您的要求。如果你真的必须实现你在问题中所说的,这里是如何......

定义自定义授权属性。检查 Request.Params 中的值以决定是应用该属性还是跳过类似于您通过AllowAnonymous 属性实现的授权。

示例代码(需要根据您的需要进行一些更改):

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class ProspectProfileAuthorizationAttribute : AuthorizeAttribute
{
   /// <summary>
   /// Special authorization check based on whether request contain valid data or not.
   /// </summary>
   /// <param name="filterContext"></param>
   public override void OnAuthorization(AuthorizationContext filterContext)
   {
       Guard.ArgumentNotNull(filterContext, "filterContext");
       Guard.ArgumentNotNull(filterContext.Controller, "filterContext.Controller");

       bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(
           typeof(CustomAllowAnonymous), inherit: true)
                                || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(
                                    typeof(CustomAllowAnonymous), inherit: true);

       if (skipAuthorization)
       {
           return;
       }

       var request = filterContext.RequestContext.HttpContext.Request;

       NameValueCollection parameterCollection = ReadQueryStringData(filterContext, request);

       if (parameterCollection.Count < 3)
       {
           throw new InvalidOperationException("Request with invalid number of parameter");
       }

       // Check 1: Is request authenticated i.e. coming from browser by a logged in user
       // No further check required.
       if (request.IsAuthenticated)
       {
           return;
       }

       // Check 2: Request is coming from an external source, is it valid i.e. does it contains
       // valid download code.
       if (string.IsNullOrEmpty(downloadCode))
       {
           throw new InvalidOperationException(Constants.Invalid_Download_Code);
       }

       if (!userType.Equals(Constants.SystemIntegrationUserName))
       {
           var exportReportService = DependencyResolver.Current.GetService<IExportReportService>();

           if (exportReportService != null)
           {
               if (!exportReportService.VerifyDownloadCode(downloadCode))
               {
                   // Invalid partner key
                   throw new InvalidOperationException(Constants.Invalid_Download_Code);
               }
           }
       }
   }

   private static NameValueCollection ReadQueryStringData(AuthorizationContext filterContext, HttpRequestBase request)
   {
       // Obtain query string parameter from request
       //original
       //var encryptedData = request.Params["data"];

       // Applying the replace for space with + symb
       var encryptedData = request.Params["data"].Replace(" ","+");

       var decryptedData = EncryptionHelper.DecryptString(encryptedData);

       // Validate the parameter
       var dict = HttpUtility.ParseQueryString(decryptedData);

       return dict;

   }
}

【讨论】:

    【解决方案2】:

    正如 Peter Duniho 所指出的,在这种情况下,您应该将两个具有不同属性的操作方法应用于每个操作方法(如果适用)。

    就冗余而言,您可以在私有方法中使用通用逻辑。可以从公共操作方法调用此私有方法。

    我在这里没有为您的问题提供直接解决方案,但我认为澄清有时您必须决定选择一个原则而不是其他原则很重要。在这种情况下,我认为KISS VS DRY

    这里的建议是保持简单并有两种方法。无论如何,它并没有直接违反 DRY。

    【讨论】:

    • 这个动作被这么多人调用,所以我不能去改变每个人对这个动作的调用。
    • @HemantMalpote:您的问题说该方法被另外两个调用。如果它被“这么多人”调用,你怎么会知道什么时候不应用OutputCache 属性?如果这种情况不常见,为什么不将当前方法名称保留为默认名称,并更改您只需要Authorization 的少数(或一个)位置? (当然,两者都调用一个共享的实现......命名任何你喜欢的名字)。
    猜你喜欢
    • 1970-01-01
    • 2015-11-12
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    • 2018-03-03
    • 2020-07-03
    • 1970-01-01
    相关资源
    最近更新 更多