如何使用属性参数调用方法

时间:2016-04-14 11:51:39

标签: c# asp.net methods attributes

我有一个名为GetRole()的静态方法,它返回一个字符串值。
现在我想在使用属性参数时调用它 例如:

[Authorize(Roles = GetRole())]
public ActionResult Get()
{
}

public static string GetRole()
{
   return "Admin";
}

但是编译器得到以下错误:

  

属性参数必须是属性参数类型

的常量表达式,typeof表达式或数组创建表达式

请帮我调用属性中的方法。

4 个答案:

答案 0 :(得分:5)

编译错误非常清楚,在声明属性时无法调用任何方法(因为它的值必须在编译时知道),但您可以派生自己的自定义属性,派生自NameAttribute以执行您需要的所有逻辑。不是我们都做了什么来本地化class DynamicAuthorizeAttribute : AuthorizeAttribute { protected bool AuthorizeCore(HttpContextBase context) { // Perform your logic here, eventually update Roles property } } &在花哨的长期等待本地化感知数据注释之前的朋友?

概念证明:

[DynamicAuthorize]
public ActionResult Get() {
    // ...
}

然后:

Roles

这只是一种可能的方式,在那里你可以放置自己的逻辑或简单地更新base.AuthorizeCore(context)属性并委托给通常的逻辑简单地调用[DynamicAuthorize(typeof(MyView), nameof(GetRole))] 。请注意,此处的所有代码都必须是线程安全的。

如果您正在使用静态方法,并且想要将该逻辑保留在控制器中,那么您可以使用它来接受(例如)类似这样的事情:

context.HttpContext.Request.RequestContext.RouteData

请注意,您可以从private void syncFullVideos() { new StreamFileTask().execute(); } private class StreamFileTask extends AsyncTask<Void,Integer,Void> { protected Void doInBackground(Void... params) { syncSucces2 = new boolean[syncVideos.size()]; Arrays.fill(syncSucces2, Boolean.FALSE); for (int i = 0; i < syncVideos.size(); i++) { Video video = syncVideos.get(i); String picturepath = video.getImage_path(); if (fileExists(picturepath)) { File sourceFile = new File(picturepath); String fileName = video.getDBImage_path(); int id = video.getId(); int index = syncVideos.indexOf(video); HttpURLConnection conn; DataOutputStream dos; int bytesRead, bytesAvailable, bufferSize; byte[] buffer; int maxBufferSize = 1024 * 1024; int serverResponseCode; Log.e("VideoUpload", "Uploading: sourcefileURI, " + fileName); if (!sourceFile.isFile()) { Log.e("uploadFile", "Source File not exist"); } else { try { FileInputStream fin = new FileInputStream(sourceFile); URL url = new URL("http://android.diggin.io/diggin/v1/vidUpload.php"); Log.v("VideoUpload", url.toString()); // Open a HTTP connection to the URL conn = (HttpURLConnection) url.openConnection(); conn.setDoInput(true); // Allow Inputs conn.setDoOutput(true); // Allow Outputs conn.setUseCaches(false); // Don't use a Cached Copy conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("ENCTYPE", "multipart/form-data"); conn.setRequestProperty("Content-Type", "multipart/form-data"); conn.setRequestProperty("X_FILE_NAME", fileName); conn.setRequestProperty("VID_ID", String.valueOf(id)); conn.setRequestProperty("VID_INDEX", String.valueOf(index)); conn.setRequestProperty("CONTENT_LENGTH", String.valueOf(sourceFile.length())); publishProgress(2, i); dos = new DataOutputStream(conn.getOutputStream()); bytesAvailable = fin.available(); int thirdOfBytes = bytesAvailable / 3; int state = 0; bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; bytesRead = fin.read(buffer, 0, bufferSize); while (bytesRead > 0) { dos.write(buffer, 0, bufferSize); bytesAvailable = fin.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fin.read(buffer, 0, bufferSize); Log.i("VideoUpload", "->"); if (bytesAvailable < thirdOfBytes && state == 1) { publishProgress(4, i); state = 2; } else if (bytesAvailable < (2 * thirdOfBytes) && state == 0) { publishProgress(3, i); state = 1; } } publishProgress(5, i); serverResponseCode = conn.getResponseCode(); String serverResponseMessage = conn.getResponseMessage(); Log.i("VideoUpload", "HTTP Response is : " + serverResponseMessage + ": " + serverResponseCode); publishProgress(9, i); DataInputStream inStream; HashMap<String,String> responseMap = new HashMap<>(); try { inStream = new DataInputStream(conn.getInputStream()); String str; while ((str = inStream.readLine()) != null) { Log.e("VideoUpload", "SOF Server Response: " + str); String[] responseItem = str.split(" - "); responseMap.put(responseItem[0], responseItem[1]); } inStream.close(); if (responseMap.get("ERROR").equals("FALSE")) { int index2 = Integer.parseInt(responseMap.get("INDEX")); syncSucces2[index2] = true; Log.e("AddSucces(" + (addCount + 1) + "/" + (syncVideos.size()) + ")", video.toString()); } } catch (IOException e) { Log.e("VideoUpload", "SOF error: " + e.getMessage(), e); } fin.close(); dos.flush(); dos.close(); publishProgress(10, i); } catch (MalformedURLException ex) { ex.printStackTrace(); Log.e("VideoUpload", "UL error: " + ex.getMessage(), ex); } catch (Exception e) { e.printStackTrace(); Log.e("UploadFileException", "Exception : " + e.getMessage(), e); } } } } return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); progressBar.setProgress(values[0] + (values[1] * 10)); } @Override protected void onPreExecute() { super.onPreExecute(); progressBar = new ProgressDialog(PictureActivity.this); progressBar.setMax(10 * syncVideos.size()); progressBar.setMessage("Uploading Video File(s)"); progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressBar.setCancelable(false); progressBar.show(); } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); progressBar.hide(); refreshPhotos(); } } 访问控制器和视图名称。

然后调用这样的静态方法。请注意,如果逻辑非常复杂并且变化很大,那么您可能希望集中此逻辑并使用其他MVC 工具来执行此操作。

答案 1 :(得分:1)

  

属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式。

这是事实。没有办法,属性参数必须是编译时间常量。你无法调用方法。

可以做的是定义一个常量:

public class MyClass
{
    public const string Role = "Admin";
    [Authorize(Roles = Role)]
    public ActionResult Get()
    {
    }    
}

常量是(顾名思义)编译时常量,所以你可能这个解决方法可以帮助你。

如果您想确定运行时的值,那么这不会起作用,因为属性是在编译时分配的。

答案 2 :(得分:0)

我使用自己的方法授权登录用户。

看看它,也许它会帮助你。

 public static bool GetRole(string Codename)
    {            
        if (LogInUser == null)
        {
            return false;
        }

        return true;
    } 

并检查用户是否有权访问,

if (!Utility.GetRole("Admin"))
            return View("AccessDenied");

我还有标准内置授权的代码,

如果您需要,请在下方发表评论。

答案 3 :(得分:0)

你可以这样做,

这种方法比较好,因为在这里你可以传递要授权的角色列表,而不是单个角色。(请看下面,我通过了管理员和掌握两者)

[Authorization(Roles = "admin,master")]
public class MyController : Controller
{
   //Your remaining code.
}

并授权它,我有这些方法。

public class Authorization : AuthorizeAttribute
{

public string Roles { get; set; }

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    if (User != null)
    {
        if (String.IsNullOrEmpty(Roles))
        {
            return true;
        }

        string[] split = Roles.Split(',');

        foreach (UserRole item in User)
        {
            if (split.Contains(item.Role.CodeName))
            {
                return true;
            }
        }
        return false;

    }
    else
        return false;
}

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    filterContext.Result = new HttpUnauthorizedResult();
}
}