如何解决WCF Rest 4.0,动态路由和OutputCache
| 我在将OutputCaching与Output0ѭ一起用于WCF 4.0 WebHttp服务时遇到问题。 我的服务已本地化。想法是您这样调用URL:/languageCode/ServiceName/Method
e.g.
/en/MyService/GetItems
它将返回本地化为正确语言的结果。
我的计划基于本文。这个想法是创建RouteBase的派生类,该派生类创建到真实服务的唯一“私有”路由。当用户发出请求时,语言代码会从URL中解压缩并设置为当前线程的区域性,然后使用“ 0”来加载实际的服务。
为了我的一生,我无法弄清楚如何将OutputCaching应用于混合。我已经用AspNetCacheProfile
装饰了我的服务方法,并且看到了我自己的varyByCustom
覆盖被调用。但是,尽管收到来自varyByCustom
的重复结果,.NET仍然继续成为我的服务方法。
下面有很多代码,对转储感到抱歉,但我怀疑这一切都相关。
我如何在Global.asax.cs中添加路线
RouteTable.Routes.Add(new CulturedServiceRoute(
\"devices\",new StructureMapServiceHostFactory(),typeof(DeviceService)));
Global.asax.cs中的varyByCustom覆盖:
public override string GetvaryByCustomString(
HttpContext context,string custom)
{
// This method gets called twice: Once for the initial request,then a
// second time for the rewritten URL. I only want it to be called once!
if (custom == \"XmlDataFreshness\")
{
var outputString = String.Format(\"{0}|{1}|{2}\",XmlDataLoader.LastUpdatedTicks,context.Request.RawUrl,context.Request.HttpMethod);
return outputString;
}
return base.GetvaryByCustomString(context,custom);
}
这是动态服务路由类。
public class CulturedServiceRoute : RouteBase,IRouteHandler
{
private readonly string _virtualPath = null;
private readonly ServiceRoute _innerServiceRoute = null;
private readonly Route _innerRoute = null;
public CulturedServiceRoute(
string pathPrefix,ServiceHostFactoryBase serviceHostFactory,Type serviceType)
{
if (pathPrefix.IndexOf(\"{\") >= 0)
{
throw new ArgumentException(
\"Path prefix cannot include route parameters.\",\"pathPrefix\");
}
if (!pathPrefix.StartsWith(\"/\")) pathPrefix = \"/\" + pathPrefix;
pathPrefix = \"{culture}\" + pathPrefix;
_virtualPath = String.Format(\"Cultured/{0}/\",serviceType.FullName);
_innerServiceRoute = new ServiceRoute(
_virtualPath,serviceHostFactory,serviceType);
_innerRoute = new Route(pathPrefix,this);
}
public override RouteData GetRouteData(
HttpContextBase httpContext)
{
return _innerRoute.GetRouteData(httpContext);
}
public override VirtualPathData GetVirtualPath(
RequestContext requestContext,RouteValueDictionary values)
{
return null;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
// This method is called even if varyByCustom
// returns a duplicate response!
var culture = requestContext.RouteData.Values[\"culture\"].ToString();
var ci = new CultureInfo(culture);
Thread.CurrentThread.CurrentUICulture = ci;
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(ci.Name);
requestContext.HttpContext.RewritePath(\"~/\" + _virtualPath,true);
return _innerServiceRoute.RouteHandler.GetHttpHandler(requestContext);
}
}
最后,服务本身的相关部分:
[ServiceContract]
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class DeviceService
{
[AspNetCacheProfile(\"MyCacheProfile\")]
[WebGet(UriTemplate = \"\")]
public IEnumerable<DeviceListItemmodel> GetDevices()
{
// This is called AFTER the first varyByCustom override is called.
// I\'d expect it not to be called unless varyByCustom changes!
var devices =
from d in _deviceRepository.GetAll()
where d.ReleaseDate < DateTime.Now
orderby d.Id descending
select new DeviceListItemmodel(d);
return devices;
}
更新:我的缓存配置文件:
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name=\"MyCacheProfile\" varyByCustom=\"XmlDataFreshness\"
varyByHeader=\"accept\" varyByParam=\"*\" location=\"Server\"
duration=\"3600\" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
解决方法
嗯,对我来说似乎是一种有效的方法。缓存配置文件是否配置正确?是否需要多次调用variableByCustom并确定在不需要更新缓存时会返回相同的结果?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。