[英]Get the Attribute tag from a Controller Method in MVC?
I'm trying to get the Attribute tag from an API Controller so that I can see what HTTP verb it allows at runtime. 我正在尝试从API控制器获取属性标记,以便我可以看到它在运行时允许的HTTP谓词。 From the sample code below, I want to be able to get the
[HttpGet]
tag. 从下面的示例代码中,我希望能够获得
[HttpGet]
标记。
[HttpGet]
public void MyResource()
{
// Controller logic
}
I am currently using System.Reflection
to gather other information about my API while it is running, but so far I have been unable to retrieve the [HttpGet
tag and other Http
verb tags. 我目前正在使用
System.Reflection
来收集有关我的API运行时的其他信息,但到目前为止我一直无法检索[HttpGet
标记和其他Http
动词标记。 I've tried each of the solutions below with no luck: 我已经尝试了下面的每个解决方案而没有运气:
public void GetControllerMethodHttpAttribute()
{
MethodInfo controllerMethod = typeof(TestController).GetMethods().First();
// Solution 1
var attrs = controllerMethod.Attributes;
// Solution 2
var httpAttr = Attribute.GetCustomAttributes(typeof(HttpGetAttribute));
// Solution 3
var httpAttr2 = Attribute.GetCustomAttribute(controllerMethod, typeof(HttpGetAttribute));
// Solution 4
var httpAttr3 = Attribute.IsDefined(controllerMethod, typeof(HttpGetAttribute));
}
All of the previous questions that I've researched about this topic only related to Custom Attribute tags
and pulling values out of those, but I couldn't find any information about getting the framework-included Attribute tags
. 我之前研究过的关于这个主题的所有问题只涉及
Custom Attribute tags
和从中提取值,但我找不到任何有关获取包含框架的Attribute tags
。
Does anyone know how I can get the [HttpGet]
Attribute tag? 有谁知道如何获得
[HttpGet]
属性标签?
Thanks! 谢谢!
The proposed solutions 3 and 4 work. 建议的解决方案3和4工作。
You must look out that you are referencing the correct HttpGetAttribute
. 您必须注意您正在引用正确的
HttpGetAttribute
。 There is one in System.Web.Http.HttpGetAttribute
and there is one in System.Web.Mvc.HttpGetAttribute
. 有一个在
System.Web.Http.HttpGetAttribute
并有一个在System.Web.Mvc.HttpGetAttribute
。
The following code lists the public methods of the ValuesController
API controller with the information on whether they have HttpGet or HttpPost attributes. 以下代码列出了
ValuesController
API控制器的公共方法,以及有关它们是否具有HttpGet或HttpPost属性的信息。
var methods = typeof(ValuesController).GetMethods();
string infoString = "";
foreach(var method in methods)
{
// Only public methods that are not constructors
if(!method.IsConstructor && method.IsPublic)
{
// Don't include inherited methods
if(method.DeclaringType == typeof(ValuesController))
{
infoString += method.Name;
if(Attribute.IsDefined(method, typeof(System.Web.Http.HttpGetAttribute)))
{
infoString += " GET ";
}
if(Attribute.IsDefined(method, typeof(System.Web.Http.HttpPostAttribute)))
{
infoString += " POST ";
}
infoString += Environment.NewLine;
}
}
}
You need to exchange System.Web.Http.
您需要交换
System.Web.Http.
with System.Web.Mvc.
使用
System.Web.Mvc.
when the controller is an MVC controller instead of an API controller. 当控制器是MVC控制器而不是API控制器时。
This is how I ended up doing it: 这就是我最终做到的方式:
public static IEnumerable<Attribute> GetSupportedVerbsForAction<T>(
Expression<Func<T, IActionResult>> expression)
where T : Controller
{
//only consider a list of attributes
var typesToCheck = new[] { typeof(HttpGetAttribute), typeof(HttpPostAttribute),
typeof(HttpPutAttribute), typeof(HttpDeleteAttribute), typeof(HttpPatchAttribute)};
var method = ((MethodCallExpression)expression.Body).Method;
var matchingAttributes = typesToCheck
.Where(x => method.IsDefined(x))
.ToList();
//if the method doesn't have any of the attributes we're looking for,
//assume that it does all verbs
if (!matchingAttributes.Any())
foreach(var verb in typesToCheck)
yield return verb;
//else, return all the attributes we did find
foreach (var foundAttr in matchingAttributes)
{
yield return method.GetCustomAttribute(foundAttr);
}
}
Say you have the following Controller and Actions: 假设您有以下控制器和操作:
public class HomeController : Controller
{
// implicit get
public IActionResult Index() => View();
// explicit get
[HttpGet]
public IActionResult GetAction() => View();
// extra info
[HttpPost(Name = "some name", Order = 5)]
public IActionResult PostAction() => View();
[HttpPut]
[HttpDelete]
[HttpPatch("my template", Name = "patch name", Order = 333)]
public IActionResult MultiAction() => View();
}
You can call them like this: 你可以像这样打电话给他们:
var indexVerbs = GetSupportedVerbsForAction<HomeController>(x => x.Index()).ToList();
var getVerbs = GetSupportedVerbsForAction<HomeController>(x => x.GetAction()).ToList();
var postVerbs = GetSupportedVerbsForAction<HomeController>(x => x.PostAction()).ToList();
var multiVerbs = GetSupportedVerbsForAction<HomeController>(x => x.MultiAction()).ToList();
This will return the full attribute that you've set in case you've added any custom data. 如果您添加了任何自定义数据,这将返回您设置的完整属性。
Two things to note: 有两点需要注意:
GetSupportedVerbsForAction<HomeController>(x => x.Index)
. GetSupportedVerbsForAction<HomeController>(x => x.Index)
。 Attribute
, so use the is
keyword to figure out if it's the type you want. Attribute
列表,因此使用is
关键字来确定它是否是您想要的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.