We are wrapping a Viewmodel inside a ApiRequestModel
and pass it as a parameter to the DoAuditModel
web Api method.DoAuditModel
calls the DoAudit
generic method.
Since there are multiple Viewmodels we had to create a ApiRequestModel for each Viewmodel type.
But we don't want to create a Api method/endpoint for each model.
We want to create a single Api method that can do this DoAuditModel
task.
Below is our simplified model structure for API Method call.
It has some common data like Token
AppCode
and a Model
(ViewModel).
These models (ModelA
,ModelB
etc) don't have a base class or implements an interface.
// Api Request Base
public class ApiRequest : IApiRequest
{
public string Token { get; set; }
public string AppCode { get; set; }
...
}
// Api Request For ModelA
public class ApiRequestForModelA : ApiRequest
{
public ModelA MyModel { get; set; }
...
}
// Api Request For ModelB
public class ApiRequestForModelB : ApiRequest
{
public ModelB MyModel { get; set; }
...
}
API Controller has multiple methods for each model type that calls a generic method.
public class MyAuditController : ApiController
{
[HttpPost]
public Task DoAuditModelA(ApiRequestForModelA modelReq)
{
// Generic Method
DoAudit<ApiRequestForModelA>(modelReq.MyModel);
...
}
[HttpPost]
public Task DoAuditModelB(ApiRequestForModelB modelReq)
{
// Generic Method
DoAudit<ApiRequestForModelB>(modelReq.MyModel);
...
}
}
I want to avoid this web method duplication (DoAuditModelA
) and creating ApiRequest models (ApiRequestForModelA
) for each model type since all I want is to call that generic DoAudit<T>(T model){...}
I want to create a single Api method as AuditModel
.
So I created a generic Api Request as below.
// Generic API Request
public class ApiRequest<T> : ApiRequest
{
public ApiRequest(T model)
{
this.MyModel = model;
}
public T MyModel { get; set; }
...
}
Now the problem is that Web Api method doesn't know the model type and how to bind/deserialize data.
I ended up using ApiRequest<dynamic>
.
Below is my new Api Method.
[HttpPost]
public Task DoAuditModel(ApiRequest<dynamic> modelReq)
{
var myModelObj = modelReq.GetType().GetProperty("MyModel").GetValue(modelReq);
// Get model Type
var typeData = auditReq.ModelAssemblyQualifiedName;
Type t = Type.GetType(typeData);
// how to use this t to create model instance or convert/deserialize data
var myModel = //myModelObj should cast to the original model type.(I'm stuck here)
DoAudit(myModel);
...
}
// DoAudit Generic method
private void DoAudit<T>(T myModel)
{
...
}
So this is my approach to pass these ViewModels to DoAudit generic method in the web api and avoid multiple web api endpoints. I'm also concern about what type of overhead that Api will have to handle is this approach. Generic controller will not work for me here.
Summery
I want to create a single API Endpint for DoAuditModel task which calls DoAudit generic method