HttpCallbacks 允许插件直接响应 HTTP 请求。
为什么要使用 HttpCallback?
HttpCallbacks 是 HttpHandlers 的平台替代支持方案。此外,该平台还会对跨站点请求来验证请求,并将用户身份验证保存到 HttpCallbacks 中。
创建 HttpCallback
若要创建回调,必须实现 IHttpCallback 接口,此接口需要对 Limyee.Components.dll 的引用。IHttpCallback 接口扩展了 IPlugin,增加了对处理 HTTP 请求的支持。
首先,我们将使用 SetController 方法来获取对 IHttpCallbackController 的引用并设置一个私有变量。这将使我们能够访问控制器,并能够为我们的回调插件生成 URL。
IHttpCallbackController _callbackController; void IHttpCallback.SetController(IHttpCallbackController controller) { _callbackController = controller; }
其次,ProcessRequest 方法将处理回调 URL 的请求。在这种情况下,我们将查找一个名为“value”的查询字符串变量,如果找到,代码将返回 javascript,该 javascript 将值写入浏览器的控制台。如果回调 URL 中不存在 “value” 变量,则将返回 404。
void IHttpCallback.ProcessRequest(System.Web.HttpContextBase httpContext) { var value = string.Empty; if (httpContext.Request.QueryString["value"] != null) value = httpContext.Request.QueryString["value"].ToString(CultureInfo.InvariantCulture); if (!string.IsNullOrEmpty(value)) { httpContext.Response.ContentType = "text/javascript"; httpContext.Response.Write("alert('" + Apis.Get<IHtml>().EnsureEncoded(value) + "');"); } else { httpContext.Response.StatusCode = 404; return; } }
下面是我们的示例 HttpCallback 的源代码:
using System; using System.Globalization; using Limyee.Extensibility; using Limyee.Extensibility.Api.Version1; using Limyee.Extensibility.UI.Version1; namespace Limyee.Examples { public class SampleCallback : IHttpCallback { #region IHttpCallback Members void IHttpCallback.ProcessRequest(System.Web.HttpContextBase httpContext) { var value = string.Empty; if (httpContext.Request.QueryString["value"] != null) value = httpContext.Request.QueryString["value"].ToString(CultureInfo.InvariantCulture); if (!string.IsNullOrEmpty(value)) { httpContext.Response.ContentType = "text/javascript"; httpContext.Response.Write("alert('" + Apis.Get<IHtml>().EnsureEncoded(value) + "');"); } else { httpContext.Response.StatusCode = 404; return; } } IHttpCallbackController _callbackController; void IHttpCallback.SetController(IHttpCallbackController controller) { _callbackController = controller; } #endregion #region IPlugin Members string Extensibility.Version1.IPlugin.Description { get { return "使用 IHttpCallback 在浏览器控制台中显示消息。"; } } void Extensibility.Version1.IPlugin.Initialize() { } string Extensibility.Version1.IPlugin.Name { get { return "回调示例"; } } #endregion } }
就其本身而言,HttpCallback 可以生成 URL 并处理对这些 UR L的请求,但是我们需要添加更多功能来使用该插件。通过添加 IHtmlHeaderExtension,我们可以在页面标头中将回调 URL 作为脚本标记输出。然后,我们的 HttpCallback 插件可以响应该请求。
GetHeader() 使用 IHttpCallbackController 变量为 HttpCallback 插件生成正确的 URL。示例代码将呈现一个带有“value”查询字符串的脚本标记和第二个不带查询字符串的脚本标记。
string IHtmlHeaderExtension.GetHeader(RenderTarget target) { var javascript1 = new NameValueCollection(); javascript1["value"] = "回调响应示例"; var sb = new StringBuilder(); sb.AppendFormat(@"<script src=""{0}""></script>", _callbackController.GetUrl(javascript1)); sb.AppendFormat(@"<script src=""{0}""></script>", _callbackController.GetUrl()); return sb.ToString(); } bool IHtmlHeaderExtension.IsCacheable { get { return true; } } bool IHtmlHeaderExtension.VaryCacheByUser { get { return false; } }
以下是包含 HttpCallback 和 HtmlHeaderExtension 实现的完整源代码:
using System; using System.Collections.Specialized; using System.Globalization; using System.Text; using Limyee.Extensibility; using Limyee.Extensibility.Api.Version1; using Limyee.Extensibility.UI.Version1; namespace Limyee.Examples { public class SampleCallback : IHttpCallback, IHtmlHeaderExtension { #region IHttpCallback Members void IHttpCallback.ProcessRequest(System.Web.HttpContextBase httpContext) { var value = string.Empty; if (httpContext.Request.QueryString["value"] != null) value = httpContext.Request.QueryString["value"].ToString(CultureInfo.InvariantCulture); if (!string.IsNullOrEmpty(value)) { httpContext.Response.ContentType = "text/javascript"; httpContext.Response.Write("alert('" + Apis.Get<IHtml>().EnsureEncoded(value) + "');"); } else { httpContext.Response.StatusCode = 404; return; } } IHttpCallbackController _callbackController; void IHttpCallback.SetController(IHttpCallbackController controller) { _callbackController = controller; } #endregion #region IHtmlHeaderExtension Members string IHtmlHeaderExtension.GetHeader(RenderTarget target) { var javascript1 = new NameValueCollection(); javascript1["value"] = "回调响应示例"; var sb = new StringBuilder(); sb.AppendFormat(@"<script src=""{0}""></script>", _callbackController.GetUrl(javascript1)); sb.AppendFormat(@"<script src=""{0}""></script>", _callbackController.GetUrl()); return sb.ToString(); } bool IHtmlHeaderExtension.IsCacheable { get { return true; } } bool IHtmlHeaderExtension.VaryCacheByUser { get { return false; } } #endregion #region IPlugin Members string Extensibility.Version1.IPlugin.Description { get { return "Uses an IHttpCallback to display messages in the browser console."; } } void Extensibility.Version1.IPlugin.Initialize() { } string Extensibility.Version1.IPlugin.Name { get { return "Sample Callback"; } } #endregion } }
将此代码部署到我们的 Limyee 电商平台站点并启用回调示例插件后,浏览到页面应会引起站点上显示 javascript 警报,并显示消息“回调响应示例”。没有查询字符串的第二个回调请求应导致 404 错误,而不是第二条警报消息。