elviuz
elviuz

Reputation: 639

Get the result object types from an action in MVC using reflection

I would like to retrieve the result object type of a Controller Action.

Generally, the structure of an action in my project is this:

[ServiceControllerResult(typeof(MyControllerResult))]
public ActionResult MyMethod(MyControllerRequest request)
{
    var response = new ServiceResponse<MyControllerResult>();
    // do something
    return ServiceResult(response);
}

Now, how can I get the MyControllerResult object type using reflection?

I write this code but I don't know how to retrieve the object type and the object Name:

var attributes = method.GetCustomAttributes(); // list of attributes
var resultAttribute =  attributes.Where(x => x.ToString().Contains("ServiceControllerResultAttribute")).FirstOrDefault();

P.S. I write the Contains method to retrieve the attribute because the decorator ServiceControllerResult is optional.

Thanks

Upvotes: 1

Views: 671

Answers (1)

Igor
Igor

Reputation: 62248

You could create a static extension method on Type (extension part optional) and call it. You still need to pass in the method name but this can be made typesafe using nameof. The only possible issue is if you have methods with the conflicting (same) names, in that case you would have to change the implementation to pass in the MethodInfo type or pick the first available method that matches and has the attribute applied to it.

// your existing method
[ServiceControllerResult(typeof(MyControllerResult))]
public ActionResult MyMethod(MyControllerRequest request)
{/*some code here*/}

Added code:

public void SomeMethodYouWrote()
{
    var fullTypeOfResult = typeof(YourControllerYouMentionAbove).GetServiceControllerDecoratedType("MyMethod");
}

// added helper to do the work for you so the code is reusable
public static class TypeHelper
{
    public static Type GetServiceControllerDecoratedType(this Type classType, string methodName)
    {
        var attribute = classType.GetMethod(methodName).GetCustomAttributes(typeof(ServiceControllerResultAttribute), false).FirstOrDefault() as ServiceControllerResultAttribute;
        return attribute == null ? null : attribute.ResultType;
    }
}

I added this although it was implied in your question just so it would compile

public class ServiceControllerResultAttribute : Attribute
{
    public ServiceControllerResultAttribute(Type someType)
    {
        this.ResultType = someType;
    }
    public Type ResultType { get; set; }
}

Upvotes: 1

Related Questions