检查开机自检的 MVC 3 路由约束
本文关键字:路由 约束 MVC 开机自检 检查 | 更新日期: 2023-09-27 17:56:51
所以我有一个接受一些JSON数据并将数据绑定到一些变量的方法。路由中只有方法名称,没有其他内容。
是否可以有一个路由约束来查看 POST 数据并检查一些变量以确定它是否是正确的路由?
方法:
public ActionResult GetDataV1(string userId)
{
// Do stuff one way
}
public ActionResult GetDataV2(string userId)
{
// Do stuff another way
}
路线:
routes.MapRoute(
"API GetData V1",
"GetData",
new { controller = "API", action = "GetDataV1" },
new { version = new APIVersionRoutingConstraint("1") }
);
routes.MapRoute(
"API GetData V2",
"GetData",
new { controller = "API", action = "GetDataV2" },
new { version = new APIVersionRoutingConstraint("2") }
);
客户端会将{ "version":"1", "userId":"mrjohn" }
发布到/GetData
,并将得到GetDataV1
的响应。APIVersionRoutingConstraint
将确保根据version
变量调用正确的方法。
尝试在约束中反序列化请求流是否是一种好的做法? 也许最好将版本放在 URL 中,例如 /GetData/1
和其他变量放在 JSON 正文中?
与其尝试将版本作为路由约束进行检查,不如转到一个操作,然后检查版本以执行适当的工作?
我还没有测试过这个,但这个想法是:
public ActionResult GetData(string userId, int version)
{
switch(version)
{
case 1:
return GetDataV1(userId);
case 2:
return GetDataV2(userId);
// You could always add more cases here as you get more versions,
// and still only have the one route
default:
// Probably more appropriate to return a result that contains error info,
// but you get the idea
throw new ArgumentOutOfRangeException("version");
}
}
// Made these private since they are called from the public action
private ActionResult GetDataV1(string userId)
{
// Do stuff one way
}
private ActionResult GetDataV2(string userId)
{
// Do stuff another way
}
然后你只需要一条路线
routes.MapRoute(
"GetData",
"GetData",
new { controller = "API", action = "GetData" },
new { version = "'d+" } // Require a numeric version
);
使APIVersionRoutingConstraint
如下所示:
public class APIVersionRoutingConstraint : IRouteConstraint
{
private string _versionNumber;
public APIVersionRoutingConstraint(string versionNumber)
{
_versionNumber = versionNumber;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
string version = null;
if (httpContext.Request.ContentType.Contains("application/json"))
{
string body = new StreamReader(httpContext.Request.InputStream).ReadToEnd();
httpContext.Request.InputStream.Position = 0;
var vals = new JavaScriptSerializer().DeserializeObject(body) as Dictionary<string, object>;
if (vals.ContainsKey("version"))
version = vals["version"].ToString();
}
// Must have version to pass constraint
return !string.IsNullOrEmpty(version) && version == _versionNumber;
}
}
我猜这不是超级高效,但它可以完成工作。仅使用与 POST 正文中的版本匹配的路由。