如何在调用方法时指定属性

本文关键字:属性 方法 调用 | 更新日期: 2023-09-27 18:31:15

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

[Authorization]
[OutputCache]
ActionResult LoadImage()

我从两个方法调用加载图像操作假设 1:索引 2:创建

当我从索引调用 LoadImage 操作时,我希望执行 LoadImage 的两个属性。当我从创建调用 LoadImage 操作时,我只想执行授权属性。我不想使用VaryByParam。

如何在调用方法时指定属性

请看我之前的回答,看看这是否满足您的要求。如果您真的必须实现您在问题中所说的内容,那么方法如下......

定义自定义授权属性。检查 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;
   }
}

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

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

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

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