Search code examples
model-view-controllerwebapi

Web Api <T> Method


My problem is very interesting. My code:

public JsonResult<ResultStatus> Post<T>(string query, [FromBody]T value) where T: GelYikaBase
    {
       
        return Json(new ResultStatus());
    }

I want to do with me, the only method to save any object of that database, but I do not know how to insert a function of the URLs in this way.

Error:

{"Message": "An error has occurred." 
"ExceptionMessage": "Cannot call action method 'System.Web.Http.Results.JsonResult`1[GelYikaFreamwork.Data.ResultStatus] Post[T](System.String, T)' on controller 'Gel_Yıka_Servis.Controllers.ServisController' because the action method is a generic method."
"ExceptionType": "System.InvalidOperationException"
"StackTrace": " konum: System.Web.Http.Controllers.ReflectedHttpActionDescriptor.InitializeActionExecutor(MethodInfo methodInfo) konum: System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<InitializeProperties>b__4() konum: System.Lazy`1.CreateValue() konum: System.Lazy`1.LazyInitValue() konum: System.Lazy`1.get_Value() konum: System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- Özel durumun oluşturulduğu önceki konumdan başlayan yığın izlemesinin sonu --- konum: System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) konum: System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) konum: System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() konum: System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext() --- Özel durumun oluşturulduğu önceki konumdan başlayan yığın izlemesinin sonu --- konum: System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) konum: System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) konum: System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() konum: System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- Özel durumun oluşturulduğu önceki konumdan başlayan yığın izlemesinin sonu --- konum: System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) konum: System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) konum: System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() konum: System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}

Solution

  • The problem with this approach is that the Web API does not know how to deserialize the object:

    A common usage of generic could be like this :

    // My generic method
    void GenericMethod<T>(){}
    ... 
    // Call the generic method by specifying the type of T:
    GenericMethod<string>()
    

    In your case, you call the Post Method from an Http request so you are not supplying the type of T when invoking the request.

    Rather than having a generic method, you can have a generic controller. Let's say you have these models defined :

    public abstract class GelYikaBase { }
    
    public class GelYika1 : GelYikaBase{}
    
    public class GelYika2 : GelYikaBase { }
    

    you can write a generic controller to deal with classes that inherits from GelYikaBase:

    public class GelYikaBaseController<T> : ApiController where T : GelYikaBase
    {
        public JsonResult<ResultStatus> Post(string query, T value)
        {
            return Json(new ResultStatus());
        }
    }
    
    public class GelYika1Controller<T> : GelYikaBaseController<GelYika1> { }
    
    public class GelYika2Controller<T> : GelYikaBaseController<GelYika2> { }
    

    Doing this, the Web Api knows how to deserialize the GelYikaBase object.