我正在创建一个通用 JSON API 来处理任何对象,每个对象所需的额外编码很少。这是所有其他控制器(EmployeeController、ProductController 等)继承的 BaseController:
public partial class BaseController<T> : Controller where T : ModelBase<T>, new()
{
[RestHttpVerbFilter]
public ActionResult Index (long? Id, string Property, long? PropertyId, T Model, string Format, string HttpVerb)
{
switch (HttpVerb)
{
case "GET":
return Json(Get(Id.Value, Property, PropertyId), JsonRequestBehavior.AllowGet);
case "POST":
return Json(Post(Id, Property, PropertyId, Model));
case "PUT":
return Json(Put(Id.Value, Property, PropertyId, Model));
case "DELETE":
return Json(Delete(Id, Property, PropertyId));
}
return Json(new { error = "Unknown HTTP verb" });
}
internal object Post (long? Id, string Property, long? PropertyId, T Model)
{
if (!Id.HasValue && string.IsNullOrEmpty(Property) && !PropertyId.HasValue && Repository.Add(Model))
{
return Get(Model.ID);
}
return new { error = "Unable to save new " + typeof(T).Name };
}
internal object Put (long? Id, string Property, long? PropertyId, T Model)
{
if (Id.HasValue)
{
Model.ID = Id.Value;
if (string.IsNullOrEmpty(Property) && !PropertyId.HasValue && Repository.Update(Model))
{
return Get(Id.Value);
}
}
return new { error = "Unable to update " + typeof(T).Name };
}
我删除了一些不相关的代码(获取、删除)。现在,我已经设置好了,所以你可以GET
向类似的东西发出请求http://example.com/API/Venue/43/Events
,这将返回 ID 为 43 指定的地点的所有事件。你还可以POST
创建http://example.com/API/Venue
一个新的地点。我希望能够POST
为该http://example.com/API/Venue/43/Events
场地创建一个新活动。
在Index
动作的参数中,现在Model
对象在发布时会拾取 Venue。当我POST
将 Event 对象添加到操作时,Model
参数仍然会拾取它。我尝试用T Model
以下内容替换,导致以下问题:
object Model
,然后根据它被POST
编辑到的 URL 进行转换。这给出了一个System.InvalidCastException
dynamic Model
,然后用(T)Model
. 这也给出了一个System.InvalidCastException
dynamic Model
,然后用Model as T
.Model
is thennull
,意味着演员阵容失败IModelBase Model
, 一个接口,它不起作用,因为模型绑定器试图实例化它
我原以为 adynamic
会起作用,但我似乎无法避免InvalidCastException
. 顺便说一句,上面的代码适用于控制器的对象(POST
ing a Venue to http://example.com/API/Venue
)。