我有一个名为GetRole()
的静态方法,它返回一个字符串值。
现在我想在使用属性参数时调用它
例如:
[Authorize(Roles = GetRole())]
public ActionResult Get()
{
}
public static string GetRole()
{
return "Admin";
}
但是编译器得到以下错误:
属性参数必须是属性参数类型
的常量表达式,typeof表达式或数组创建表达式
请帮我调用属性中的方法。
答案 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();
}
}