- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在使用这种方法一段时间后,我发现自己只是在每个 Controller 中添加了完全相同的样板代码,所以我决定做一些反射魔术。与此同时,我放弃了使用 MVC 来处理我的 View - Razor 是如此乏味和丑陋 - 所以我基本上将我的处理程序用作 JSON 后端。我目前使用的方法是用 Route
装饰我的查询/命令位于某些常见程序集中的属性,如下所示:
[Route("items/add", RouteMethod.Post)]
public class AddItemCommand { public Guid Id { get; set; } }
[Route("items", RouteMethod.Get)]
public class GetItemsQuery : IQuery<GetItemsResponse> { }
// The response inherits from a base type that handles
// validation messages and the like
public class GetItemsResponse : ServiceResponse { }
然后我实现了一个 MVC 主机,它提取带注释的命令/查询并在启动时为我生成 Controller 和处理程序。有了这个,我的应用程序逻辑终于摆脱了 MVC 的束缚。查询响应也会自动填充验证消息。我的 MVC 应用程序现在看起来像这样:
+ MvcApp +- Global.asax +- Global.asax.cs - Startup the host and done +- Web.config
After realizing I really don't use MVC outside the host - and constantly having issues with the bazillion dependencies the framework has - I implemented another host based on NServiceKit. Nothing had to be changed in my application logic and the dependencies are down to System.Web
, NServiceKit
and NServiceKit.Text
that takes good care of the model binding. I know it's a very similar approach to how NServiceKit/ServiceStack
does their stuff but I'm now totally decoupled from the web framework in use so in case a better one comes along I just implement another host and that's it.
I'm currently working on an ASP.NET MVC site that's implementing the businesslogic-view separation via the IQueryHandler and ICommandHandler abstractions (using the almighty SimpleInjector for dependency injection).
I've got to attach some custom validation logic to a QueryHandler
via a decorator and that's working pretty well in and of itself. The problem is that in the event of validation errors I want to be able to show the same view that the action would have returned but with information on the validation error of course. Here is a sample for my case:
public class HomeController : Controller
{
private readonly IQueryHandler<SomeQuery, SomeTransport> queryHandler;
public ActionResult Index()
{
try
{
var dto = this.queryHandler.Handle(new SomeQuery { /* ... */ });
// Doing something awesome with the data ...
return this.View(new HomeViewModel());
}
catch (ValidationException exception)
{
this.ModelState.AddModelErrors(exception);
return this.View(new HomeViewModel());
}
}
}
在这种情况下,我有一些由 queryHandler
处理的业务逻辑装饰有 ValidationQueryHandlerDecorator
抛出 ValidationException
在适当的时候。
我想要的是:
public class HomeController : Controller
{
private readonly IQueryHandler<SomeQuery, SomeTransport> queryHandler;
public ActionResult Index()
{
var dto = this.queryHandler.Handle(new SomeQuery { /* ... */ });
// Doing something awesome with the data ...
// There is a catch-all in place for unexpected exceptions but
// for ValidationExceptions I want to do essentially the same
// view instantiation but with the model errors attached
return this.View(new HomeViewModel());
}
}
我一直在想一个特别的ValidationErrorHandlerAttribute
但后来我失去了上下文,我无法真正返回正确的 View 。我只是包装 IQueryHandler<,>
的方法也是如此。使用装饰器...我看到了一些奇怪的代码片段,它们在路由上进行了一些字符串嗅探,然后通过 Activator.CreateInstance
实例化了一个新的 Controller 和 View 模型。 - 这似乎不是个好主意。
所以我想知道是否有一个很好的方法来做到这一点……也许我只是没有从树上看到木头。谢谢!
最佳答案
我不认为有什么方法可以让 action 方法忽略这一点,因为 action 方法控制着返回的 View 模型,并且在验证异常的情况下,您需要返回一个包含所有实际数据(以防止用户丢失他的更改)。但是,为了使这更方便,您可以做的是添加一个扩展方法来在操作中执行查询:
public ActionResult Index()
{
var result = this.queryHandler.ValidatedHandle(this.ModelState, new SomeQuery { });
if (result.IsValid) {
return this.View(new HomeViewModel(result.Data));
}
else
{
return this.View(new HomeViewModel());
}
}
ValidatedHandle
扩展方法可能如下所示:
public static ValidatedResult<TResult> ValidatedHandle<TQuery, TResult>(
this IQueryHandler<TQuery, TResult> handler,
TQuery query, ModelStateDictionary modelState)
{
try
{
return new ValidatedResult<TResult>.CreateValid(handler.Handle(query));
}
catch (ValidationException ex)
{
modelState.AddModelErrors(ex);
return ValidatedResult<TResult>.Invalid;
}
}
请注意,如果验证是针对用户输入的数据,您应该只捕获此类验证异常。如果您发送带有以编程方式设置的参数的查询,则验证异常仅意味着编程错误,您应该写博客、记录异常并向用户显示友好的错误页面。
关于c# - 如何将验证处理从 Controller 操作转移到装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24010538/
我有这些 ViewModel:RecordViewModel、ComponentViewModel,其中 RecordViewModel 本质上是几个 ComponentViewModel 的容器。
我正在尝试为我的 Controller 设置一个装饰器。我的目的是在我的应用程序中的所有 Controller 中引入一些常见的行为。 我已将其配置为在 Angular 1.2.x 中工作,但从 1.
我想用角上的时间戳装饰我生成的所有 JFreeCharts。 JFreeChart 框架中是否有一种方法可以在生成图表后在图像上绘制? 编辑:请注意,这些图表是在后台线程中生成并通过 servlet
在grails应用程序中,我想用自定义数据装饰每个日志。当前的需要只是在日志消息前添加当前用户名 我对如何解决此问题有一些想法: -Adding custom field to log4j patte
我有一个form-el,它只是一个容器,必须将所有子元素包装在具有特定类的div 中。我希望允许 from-el 来包装它们,而不是在每个表单元素中重复这个 div 。我可以循环所有元素并将它们包装在
我遵循以下约定来装饰 Python 类中的某些方法。我想知道是否有一些更好的方法可以做到同样的事情。我的方法看起来当然不太好;对原始成员函数的调用看起来一点也不直观。 from threading i
我的 DTO 看起来像这样 public class SomeDTO { public string last_name{ get; set; } public string ac
这可能是一个远景,但 .NET 的灵 active 一直让我惊叹不已,所以开始吧。 我正在开发一个 MVC 应用程序,它需要在一组程序集中搜索派生自公共(public)基类的类类型。 即我有几个程序集
在我正在进行的项目中,我正在按照项目负责人的要求实现开发人员通知系统。它的工作方式是,如果发生前端错误,开发团队会收到一封错误电子邮件。 但是,在我当前的实现中,我似乎有以下循环依赖: $rootSc
我需要一些关于如何取消装饰和装饰 JInternalFrame 的帮助。我的框架类是这样的: package com; import java.awt.BorderLayout; import jav
假设我们有可能需要长时间运行的任务: public class LongRunningTask { public ReturnType doSomething() { ...
我正在尝试创建一个装饰器方法,它将一些默认的生命周期方法添加到 react 组件中。我的目标是向组件中添加一些默认功能,例如,所有组件都应该能够在 componentWillMount 上执行特定操作
我正在尝试将 DBUS 的异步方法调用与 Twisted 的 Deferred 相结合,但我在调整常用的 DBUS 服务方法装饰器来执行此操作时遇到了麻烦。 要使用 DBUS 异步回调方法,您需要:
是否可以设置表格中一行的背景颜色?当条件适用时,我需要突出显示一行。效果为 ...我可以在其中指定“字体”属性。 (我需要突出显示整行)。 最佳答案 您必须子类化 qooxdoo 默认行渲染器才能做到
我正在开发一个具有不同视角的基于 Java Swing 的应用程序。对于“主菜单”视角,我不希望装饰窗口 (JFrame),而在其他视角中,我确实希望装饰窗口。换句话说,我需要动态更 retrofit
我想做一些类似下面代码所示的事情: class foo { private: std::fstream* m_stream; public: foo(std::fstream* str
我的数据源提供了一个 ObservableList ,但是对于我的 ListView,我需要一个 ObservableList . A Warning基本上只是字符串的装饰器,添加一个 boolean
我一直在纠结于装饰+接口(interface)。假设我有以下“行为”接口(interface): interface IFlyable { void Fly();} interface ISwimma
有没有人为 iOS 6 UICollectionView 实现过装饰 View ?不可能 查找有关在网络上实现装饰 View 的任何教程。基本上在我的应用程序中,我有多个部分,我只想在每个部分后面显示
我有一个简单的 Controller ,例如: function MyController($scope, $http) { ... $http.post(url).success(f
我是一名优秀的程序员,十分优秀!