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

时间:2014-11-21 05:46:54

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

我有一种行动方法。 哪个有2个属性

[Authorization]
[OutputCache]
ActionResult LoadImage()

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

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

2 个答案:

答案 0 :(得分:2)

请参阅我之前的回答,看看是否满足您的要求。如果你真的必须实现你在问题中所说的话,那么这就是......

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

   }
}

答案 1 :(得分:1)

正如Peter Duniho指出的那样,在这种情况下,您应该有两种操作方法,其中不同的属性适用于每种操作方法。

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

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

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