1

我正在构建一个自定义内容部分,它从外部存储库中获取其信息,主要遵循@如何更改 Orchard 记录存储库并使用自定义处理程序来获取数据的建议。

使用外部数据存储打开了各种网络异常等的可能性,这将导致底层记录无法保存。但是,如果在 中抛出异常ContentHandler,它会被该方法吞噬,Invoke<TEvents>因此(除非它是“致命”异常)用户不会知道该异常,并且会被AdminControllerthat通知"Your {0} has been saved.",而实际上它没有没去过。

对我来说显而易见的解决方法是以某种方式拦截错误并通知内容驱动程序我的内容部分,这会暴露正在执行的AdminController. 那时,我可以连接到控制器ModelState并引入一个错误,然后将其捕获,然后我会收到错误通知,而不会出现任何误报通知。

ModelStateOrchard 中是否还有其他可用的扩展点可以比通过内容驱动程序更改控制器更好地处理这种外部访问?

4

1 回答 1

1

最简单的方法是为这些错误实现您自己的、简单的、按请求的存储对象,即。

public interface IErrorLog : IDependency {
    public void Add(string message){ ... }
    public IEnumerable<string> List() { ... }
}

public class DefaultErrorLog : IErrorLog { ... }

注入IErrorLog您的控制器和处理程序。在处理程序中,捕获您需要捕获的所有错误并将它们添加到集合中Add(...)。然后,在控制器中,List()为每个条目调用并添加模型错误。

更新

如果您无法控制Controller更新您的内容项,那么您应该使用驱动程序。在项目保存期间捕获异常(具有 3 个参数的第二种方法)并使用提供的对象Editor推送一些错误信息。方法更简单,但您只能捕获保存项目时发生的错误。AddModelErrorIUpdateModel

更新 2

如果您无法控制Controller更新您的内容项目,但希望拥有一个纯粹的解决方案并获得对整个过程的控制,您可以使用自己的控制器来编辑项目。为了做到这一点:

  • 首先创建一个新控制器(或复制并更改在AdminController中找到的默认值Orchard.Core\Contents
  • 现在告诉 Orchard 使用此控制器,而不是包含您的自定义部件的所有类型的默认控制器。可以通过在您的处理程序中放置类似的内容来完成:

    OnGetContentItemMetadata<MyCustomPart>((context, part) =>
    {
        context.Metadata.AdminRouteValues = new RouteValueDictionary 
        {
            { "Area", "My.Module" },
            { "Controller", "Admin" },
            { "Action", "Edit" },
            { "id", context.ContentItem.Id }
        };
    });
    
于 2013-05-07T20:28:26.850 回答