所以我有一个接受一些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体中的其他变量?
答案 0 :(得分:3)
为什么不去检查版本以执行适当的工作呢?
我没有测试过这个,但想法是:
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
);
答案 1 :(得分:0)
像这样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正文中的版本匹配的路由。