ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OrchardCore XML-RPC 模块深度解析:从 `/xmlrpc` 端点到 MetaWeblog 远程发布

OrchardCore XML-RPC 模块深度解析:从 `/xmlrpc` 端点到 MetaWeblog 远程发布 CMS后端Web框架【免费下载链接】OrchardCoreOrchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.项目地址https://gitcode.com/gh_mirrors/or/OrchardCore点击查看免费下载OrchardCore.XmlRpc是 OrchardCore 中为站点提供 XML-RPC 协议支持的模块它让桌面博客客户端如 Open Live Writer能够通过标准 XML-RPC 调用远程创建、编辑、发布内容并上传媒体。本文以该模块为核心完整讲解其两个功能XML-RPC 核心端点与 Remote Publishing/MetaWeblog API的启用方式、端点路由、请求处理全链路并结合仓库源码剖析 XML 编解码的类型映射、IXmlRpcHandler与IMetaWeblogDriver扩展机制以及认证与权限控制的实际实现帮助你既能在站点上快速开通远程发布能力也能深入理解其可扩展架构。模块概览两个功能、一条链路OrchardCore.XmlRpc模块源码位于 src/OrchardCore.Modules/OrchardCore.XmlRpc本身是纯协议层实现它负责把 HTTP POST 请求体中的 XML-RPC 方法调用解析为强类型模型、分发给处理程序、再把处理结果序列化回 XML 响应。真正懂业务的部分MetaWeblog 的博客文章、媒体上传等语义则由其他模块通过扩展点注入。模块在 Manifest.cs 中声明了两个功能Feature二者都是Infrastructure类别Feature说明OrchardCore.XmlRpc提供核心 XML-RPC 端点与协议支持/xmlrpc。OrchardCore.RemotePublishing在 XML-RPC 之上叠加 MetaWeblog API支持远程创建与编辑内容/xmlrpc/metaweblog依赖OrchardCore.XmlRpc。从清单源码可以看到依赖关系被显式声明Dependencies [OrchardCore.XmlRpc]也就是说开启 Remote Publishing 时 XML-RPC 会自动随之启用。端点路由模块通过 Startup.cs 中的StartupBase.Configure注册了两条区域控制器路由路由控制器/动作用途/xmlrpcHomeController.IndexServiceEndpointXML-RPC 入口点接收所有方法调用。/xmlrpc/metaweblogMetaWeblogController.ManifestMetaWeblog API 的客户端能力清单manifest端点需启用 Remote Publishing 功能。路由模式在源码中分别写作xmlrpc与xmlrpc/metaweblog均映射到OrchardCore.XmlRpc区域routes.MapAreaControllerRoute( name: XmlRpc, areaName: OrchardCore.XmlRpc, pattern: xmlrpc, defaults: new { controller Home, action Index }); routes.MapAreaControllerRoute( name: MetaWeblog, areaName: OrchardCore.XmlRpc, pattern: xmlrpc/metaweblog, defaults: new { controller MetaWeblog, action Manifest });MetaWeblog 能力清单端点/xmlrpc/metaweblog返回的是一份符合 Windows Live Writer manifest 命名空间http://schemas.microsoft.com/wlw/manifest/weblog的 XML 能力声明文档供客户端自动探测站点能力。核心能力由 MetaWeblogController.Manifest 生成默认值如下supportsAutoUpdateYesclientTypeMetaWeblogsupportsKeywordsNosupportsCategoriesNosupportsFileUploadNosupportsCustomDateNo该动作标注了[ResponseCache(Duration 0, NoStore true)]确保每次请求都返回最新能力声明。更重要的是控制器会遍历所有IXmlRpcHandler并调用其SetCapabilities(options)方法让各模块按需改写这些能力值——例如OrchardCore.Media模块的 MediaMetaWeblogDriver 会把supportsFileUpload改为YesOrchardCore.Autoroute模块的 AutorouteMetaWeblogDriver 会追加supportsSlug Yes。使用方式从桌面客户端发布内容官方文档给出的接入步骤本模块 README可直接照做启用功能在站点后台或通过 recipe启用Remote Publishing功能它会自动启用XML-RPC。配置客户端在桌面博客客户端如 Open Live Writer中新建账户协议选择 MetaWeblog API服务端点填写站点根地址 /xmlrpc/metaweblog。认证使用具备创建与发布相关内容权限的站点用户账户登录。MetaWeblog API 支持博客客户端常用的典型操作获取最近文章、创建与编辑文章、上传媒体。前置条件远程发布依赖 List 类型需要说明的是MetaWeblog 的博客语义在 OrchardCore 中与OrchardCore.Lists模块的列表类型ListPart绑定。从 MetaWeblogHandler 的实现可以看到blogger.getUsersBlogs会遍历所有内容类型定义只挑选包含ListPart的类型再列出其中的内容项作为博客metaWeblog.newPost则通过列表的ListPartSettings.ContainedContentTypes决定新建文章使用哪种内容类型。因此要让远程发布真正可用站点通常还需要启用OrchardCore.Lists以及负责承载文章字段的OrchardCore.Title、OrchardCore.Html或OrchardCore.Markdown等模块并定义一个包含列表部件的博客内容类型。请求处理链路一段 XML 的完整旅程一个 XML-RPC 请求从到达/xmlrpc到返回响应经历了下面这条可完整从源码验证的调用链模型绑定MethodCallModelBinder 读取请求体StreamReader.ReadToEndAsync用XElement.Parse解析 XML再交给IXmlRpcReader映射为XRpcMethodCall。源码注释提示这里选择整读而非XElement.LoadAsync是因为后者在大请求体作者测试过约 2 MB 的图片上传下会失败同时注释也提醒超大 XML 请求存在内存风险。入口控制器HomeController.ServiceEndpoint标注[HttpPost]且[IgnoreAntiforgeryToken]把XRpcMethodCall组装进XmlRpcContext然后逐个调用容器中注册的所有IXmlRpcHandler.ProcessAsync(context)。业务处理处理程序如 Lists 模块的MetaWeblogHandler根据RpcMethodCall.MethodName分派到具体逻辑把结果写入context.RpcMethodResponse。序列化响应控制器用IXmlRpcWriter.MapMethodResponse把XRpcMethodResponse转为XElement通过XmlWriter写入临时MemoryStream保留 UTF-8 编码声明最终以text/xml返回。异常处理方面DispatchAsync捕获任何异常并构造XRpcFault(0, e.Message)写入methodResponse由 Writer 按 XML-RPC 规范输出标准的fault结构源码注释明确指向http://xmlrpc.scripting.com/spec.html的 fault 格式如果响应整体为空则返回 HTTP 500。XmlRpcContext贯穿全链路的上下文对象处理程序之间通过 XmlRpcContext 共享状态public class XmlRpcContext { public ControllerContext ControllerContext { get; set; } public HttpContext HttpContext { get; set; } public IUrlHelper Url { get; set; } public XRpcMethodCall RpcMethodCall { get; set; } public XRpcMethodResponse RpcMethodResponse { get; set; } public ICollectionIXmlRpcDriver Drivers { get; set; } []; }Drivers集合用于把结果广播给后续感兴趣的扩展点——IXmlRpcDriver.Process(object item)会在文章创建、编辑、删除、读取后收到对应的事件载荷例如新文章的ContentItemId、编辑后的Id适合做关联数据的同步。扩展点一IXmlRpcHandlerIXmlRpcHandler 是协议层的核心扩展接口任何模块都可以实现它以处理特定的 XML-RPC 方法public interface IXmlRpcHandler { void SetCapabilities(XElement element); Task ProcessAsync(XmlRpcContext context); }OrchardCore.Lists模块的 MetaWeblogHandler标注[RequireFeatures(OrchardCore.RemotePublishing)]就是最典型的实现它按方法名分发并实现了完整的 MetaWeblog 方法集方法名语义关键行为来自源码blogger.getUsersBlogs列出用户可编辑的博客遍历含ListPart的内容类型校验CommonPermissions.EditContent权限返回 url/blogid/blogName。metaWeblog.getRecentPosts获取最近文章校验EditContent权限按CreatedUtc倒序取指定数量经CreateBlogStructAsync与各 Driver 组装为结构体。metaWeblog.newPost新建文章校验PublishContent/EditContent权限读取列表允许的内容类型创建草稿按publish参数与date_created_gmt/dateCreated决定发布或保存草稿返回ContentItemId。metaWeblog.getPost获取单篇文章按VersionOptions.Latest读取校验权限经 Driver 填充字段。metaWeblog.editPost编辑文章按VersionOptions.DraftRequired读取校验权限更新后按publish决定发布或保存草稿。blogger.deletePost删除文章校验DeleteContent权限后RemoveAsync删除。metaWeblog.newMediaObject上传媒体校验MediaPermissions.ManageMedia含目录级权限经IMediaFileStore规范化路径、校验扩展名MediaOptions.AllowedFileExtensions/RestrictedFileExtensions返回 file/url/type 三元组。注意blogger.getUsersBlogs的参数顺序在源码中使用Params[1]用户名与Params[2]密码metaWeblog.newMediaObject使用Params[1]/Params[2]/Params[3]这与 MetaWeblog 协议的参数约定一致。扩展点二IMetaWeblogDriver 与字段映射IMetaWeblogDriver定义于 OrchardCore.MetaWeblog.Abstractions基类实现见 MetaWeblogDriver.cs负责把站点内容类型的字段映射为 MetaWeblog 文章结构体反之亦然public interface IMetaWeblogDriver { void SetCapabilities(Actionstring, string setCapability); void BuildPost(XRpcStruct rpcStruct, XmlRpcContext context, ContentItem contentItem); void EditPost(XRpcStruct rpcStruct, ContentItem contentItem); }BuildPost读取ContentItem字段写入XRpcStruct出站方向。EditPost从XRpcStruct取字段值回写ContentItem入站方向。SetCapabilities向 manifest 声明额外能力。仓库中现成的 Driver 实现即是字段 ↔ 协议字段映射的活教材Driver模块映射的协议字段 / 能力TitleMetaWeblogDriverTitletitle↔TitlePart.Title/DisplayText出站时经HtmlEncoder编码。HtmlBodyMetaWeblogDriverHtmldescription↔HtmlBodyPart.Html。MarkdownBodyMetaWeblogDriverMarkdowndescription↔MarkdownBodyPart.Markdown。AutorouteMetaWeblogDriverAutoroutewp_slug↔AutoroutePart.Path能力supportsSlug Yes。MediaMetaWeblogDriverMedia能力supportsFileUpload Yes。这些 Driver 在各自模块的RemotePublishingStartup中按需注册例如 Html 模块的 RemotePublishingStartup.cs[RequireFeatures(OrchardCore.RemotePublishing)] public sealed class RemotePublishingStartup : StartupBase { public override void ConfigureServices(IServiceCollection services) { services.AddScopedIMetaWeblogDriver, HtmlBodyMetaWeblogDriver(); } }MetaWeblogHandler构造时注入IEnumerableIMetaWeblogDriver因此在BuildPost/EditPost中会自动聚合所有已注册 Driver——这正是协议层不依赖具体字段、字段语义由各模块自由扩展的分层设计。XML-RPC 数据类型编解码Reader 与 Writer 的实现细节XML-RPC 协议定义了有限的标量与复合类型模块通过两个对称的映射表在 XML 与 C# 对象之间转换实现位于 XmlRpcReader.cs 与 XmlRpcWriter.cs。入站解析IXmlRpcReaderXmlRpcReader 以 XML 元素局部名为键分派XML-RPC 类型映射目标说明i4/intXRpcDataint直接强转。booleanXRpcDatabool字符串1视为true。stringXRpcDatastring直接取值。doubleXRpcDatadouble直接强转。dateTime.iso8601XRpcDataDateTime先按常规格式DateTime.TryParse失败再按 Open Live Writer 使用的yyyyMMddTHH:mm:ss精确格式解析两者都不行则回退为DateTime.Now。base64XRpcDatabyte[]Convert.FromBase64String。structXRpcStruct遍历member递归映射。arrayXRpcArray遍历data/value递归映射。遇到未知类型会抛出InvalidOperationException(Unknown XmlRpc value type ...)。MapToMethodCall负责提取methodName与params/param序列产出XRpcMethodCall模型定义见 XRpcMethodCall.cs。出站序列化IXmlRpcWriterXmlRpcWriter 以 CLR 类型为键分派覆盖范围更广CLR 类型输出 XML 类型说明intint—boolbooleantrue输出1。stringstring—doubledouble—DateTime/DateTime?dateTime.iso8601格式yyyyMMddTHH:mm:ssZInvariantCulture。DateTimeOffset/DateTimeOffset?dateTime.iso8601同上。byte[]base64Convert.ToBase64String。XRpcStructstruct递归输出member。XRpcArrayarray递归输出data。XRpcData是编解码两端的通用载体见 XRpcData.csXRpcDataT通过Type属性暴露运行时类型Writer 据此选择序列化分支XRpcStruct提供SetT写入成员与OptionalT安全读取缺失返回默认值两个便捷方法XRpcMethodResponse提供链式AddT见 XRpcMethodResponse.csXRpcArray提供AddT见 XRpcArray.cs。这两个服务在 Startup.cs 中以 Scoped 生命周期注册AddScopedIXmlRpcReader, XmlRpcReader()、AddScopedIXmlRpcWriter, XmlRpcWriter()接口定义分别在 IXmlRpcReader.cs 与 IXmlRpcWriter.cs。认证与权限控制虽然/xmlrpc端点本身标注了[IgnoreAntiforgeryToken]但这不代表匿名可写——所有业务方法都在处理程序中完成用户校验与授权。以MetaWeblogHandler为例身份校验ValidateUserAsync(userName, password)调用IMembershipService.CheckPasswordAsync核对用户名/邮箱与密码失败抛出用户名或邮箱或密码不正确成功后通过CreateClaimsPrincipal构造声明主体。内容权限按操作分别校验CommonPermissions.EditContent读取/编辑、PublishContent发布、DeleteContent删除——这些权限来自OrchardCore.Contents模块的 CommonPermissions.cs对应核心实现可参见 OrchardCore.Contents 模块。媒体权限metaWeblog.newMediaObject额外校验MediaPermissions.ManageMedia以及针对目标目录的ManageMediaFolder权限并受MediaOptions.AllowedFileExtensions/RestrictedFileExtensions约束未授权或扩展名不允许都会抛出异常并最终以 XML-RPC fault 形式返回。因此官方文档中使用具备创建和发布相关内容权限的站点用户这一条要求对应到源码就是这套CheckPasswordAsyncAuthorizeAsync的强制校验链。从源码结构看如何扩展你自己的 XML-RPC 方法综合上面的源码证据向 OrchardCore 增加新的远程调用能力遵循清晰的四步模式实现IXmlRpcHandler在ProcessAsync中按context.RpcMethodCall.MethodName分发处理完成后把结果写入context.RpcMethodResponse可用XRpcMethodResponse().Add(result)组装参数若你的功能需要向客户端 manifest 声明能力同时实现SetCapabilities。可选实现IMetaWeblogDriver当你的内容类型字段需要映射为博客文章字段时实现BuildPost/EditPost/SetCapabilities三个方法继承抽象基类MetaWeblogDriver即可只覆写需要的部分。注册服务在模块的StartupBase.ConfigureServices中注册services.AddScopedIXmlRpcHandler, YourHandler()或services.AddScopedIMetaWeblogDriver, YourDriver()若该扩展只在 Remote Publishing 下生效给Startup类加上[RequireFeatures(OrchardCore.RemotePublishing)]特性。路由如需独立端点如自定义协议方法在Configure中仿照 Startup.cs 用routes.MapAreaControllerRoute追加路由纯方法扩展则无需新增路由直接复用/xmlrpc入口。仓库中 ListsHandler 层与 Title/Html/Markdown/Autoroute/MediaDriver 层的组合实现即是这套扩展机制最小可用的完整范例。小结OrchardCore.XmlRpc模块用约十个文件就把 XML-RPC 协议层做成了高度可扩展的基座/xmlrpc负责协议收发/xmlrpc/metaweblog负责能力探测IXmlRpcHandler承载方法语义IMetaWeblogDriver承载字段语义Reader/Writer 的表驱动编解码保证了类型覆盖的完整与对称。对于使用者而言只需要在站点启用Remote Publishing功能、准备一个基于ListPart的博客内容类型再用任意支持 MetaWeblog 协议的桌面客户端如 Open Live Writer指向/xmlrpc/metaweblog即可完成远程写作闭环对于开发者而言同一套接口也可以用来扩展出完全自定义的 XML-RPC 方法实现与其他系统之间的 RPC 集成。赞分享CMS后端Web框架【免费下载链接】OrchardCoreOrchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.项目地址https://gitcode.com/gh_mirrors/or/OrchardCore点击查看免费下载相关推荐Hyperf RPC客户端远程过程调用客户端深度解析Hyperf RPC客户端远程过程调用客户端深度解析 引言微服务通信的核心利器 在现代微服务架构中服务间的通信是系统设计的核心挑战之一。你是否曾面临这样的后端Web框架微服务RPC框架异步编程Alluxio Assembly 模块深度解析从 Maven 构建到发布 Tarball 的全流程指南Alluxio Assembly 模块深度解析从 Maven 构建到发布 Tarball 的全流程指南 导读本文聚焦 Alluxio 代码库中的 assem存储分布式文件系统缓存大数据DokuWiki API与远程访问JSON-RPC和XML-RPC完整指南DokuWiki API与远程访问JSON RPC和XML RPC完整指南 DokuWiki作为一款强大的开源Wiki引擎提供了完善的远程访问API支持J后端CMS知识管理上一篇Angular架构与高级特性实战解析下一篇freeCodeCamp Slice and Splice 挑战解析用 slice 与 splice 实现不可变数组合并创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表