带有 PostSharp OnException 处理问题的消息弹出 Mvc3
- 我在 mvc3 中返回消息弹出窗口时遇到一些问题 抛出一些异常。
- 我使用 PostSharp 作为全局 AOP 捕获异常并处理它们的框架构建文本 弹出窗口的 .
- 我已将 ActionResult 扩展为自定义对象 在 ExecuteResult 中实现了 RenderViewToString 方法 为 messagePopup 创建正确的 html 代码。
- MessagePopup 显示在页面上,但 Action 继续自行执行。
我怎样才能阻止它继续执行自己?
在全局捕获它比
namespace Aop
{
/// <summary>
/// Handles Aspect Object Programming in all the projects .
/// The attribute is being injected through Shared AssemblyInfo.cs to all the
/// relevant Assemblies in the project.
/// The code of the class is being added to project in compilation time
/// and by that improves the response time quality
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class |
AttributeTargets.Method | AttributeTargets.Constructor,
AllowMultiple = true, Inherited = false)]
[MulticastAttributeUsage(MulticastTargets.Method, AllowMultiple = true,
AllowExternalAssemblies = true)]
public sealed class TraceAttribute : OnMethodBoundaryAspect
{
[Inject]
public IReportBLImpl _reportBL { get; set; }
public TraceAttribute() { }
#region Runtime semantics
/// <summary>
/// Handles all exception in all the project Ness.DoarKamuti exceptions
/// </summary>
/// <param name="eventArgs"></param>
public override void OnException(MethodExecutionEventArgs eventArgs)
{
…
DefActionResult res = DefActionResult.Create("~/Views/Shared/MessagePopup.ascx",_report , DefConstants.MessageDesign.PopUp, "messagePopupBody");
eventArgs.ReturnValue = res;
}
}
当它失败时,我在处理消息内容之后
它正在构建我的 ActionResult public class DefActionResult : ActionResult {
public override void ExecuteResult(ControllerContext context)
{
DefJsonResult model = this.ActionModel;
/* If a view name has been specified, render it */
if (!string.IsNullOrEmpty(model.ViewName))
model.ViewHTML = controller.RenderViewToString(model.ViewName, model.ViewModel);
JsonResult res = new JsonResult() { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
res.ExecuteResult(context);
}
}
然后我正在构建响应
public static class MVCExtensions
{
public static string RenderViewToString(this Controller controller, string viewName, object viewData)
{
//Create memory writer
var sb = new StringBuilder();
var memWriter = new StringWriter(sb);
//Create fake http context to render the view
var fakeResponse = new HttpResponse(memWriter);
var fakeContext = new HttpContext(HttpContext.Current.Request, fakeResponse);
var fakeControllerContext = new ControllerContext(
new HttpContextWrapper(fakeContext),
controller.ControllerContext.RouteData,
controller.ControllerContext.Controller);
var oldContext = HttpContext.Current;
HttpContext.Current = fakeContext;
//Use HtmlHelper to render partial view to fake context
var html = new HtmlHelper(new ViewContext(fakeControllerContext,
new FakeView(), controller.ViewData, controller.TempData, memWriter),
new ViewPage());
html.ViewDataContainer.ViewData = controller.ViewData;
html.RenderPartial(viewName, viewData);
//Restore context
//HttpContext.Current = oldContext;
//Flush memory and return output
memWriter.Flush();
return sb.ToString();
}
在返回我的消息弹出窗口后,它会继续执行原始操作,就好像它没有压垮一样,当然压垮是因为数据源未初始化。
我不想使用 HandleErrorAttribute 处理错误,因为它不像 PostSharp 那样动态。
如何停止原始请求的剩余部分? (备注,我使用 Telerik grid for mvc 来显示数据。)
- I have some trouble with returning the message popup in mvc3 when
some exception is thrown . - I'm using PostSharp as a global AOP
framework to catch the exceptions and handle them building the text
of the popup . - I've extended the ActionResult to custom object that
in ExecuteResult implements the RenderViewToString method that
creates the right html code for the messagePopup. - The MessagePopup is shown on the page but the Action continues to perform itself.
How can i stop it from continuing to perform itself ?
When it fails I catch it globally at the
namespace Aop
{
/// <summary>
/// Handles Aspect Object Programming in all the projects .
/// The attribute is being injected through Shared AssemblyInfo.cs to all the
/// relevant Assemblies in the project.
/// The code of the class is being added to project in compilation time
/// and by that improves the response time quality
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class |
AttributeTargets.Method | AttributeTargets.Constructor,
AllowMultiple = true, Inherited = false)]
[MulticastAttributeUsage(MulticastTargets.Method, AllowMultiple = true,
AllowExternalAssemblies = true)]
public sealed class TraceAttribute : OnMethodBoundaryAspect
{
[Inject]
public IReportBLImpl _reportBL { get; set; }
public TraceAttribute() { }
#region Runtime semantics
/// <summary>
/// Handles all exception in all the project Ness.DoarKamuti exceptions
/// </summary>
/// <param name="eventArgs"></param>
public override void OnException(MethodExecutionEventArgs eventArgs)
{
…
DefActionResult res = DefActionResult.Create("~/Views/Shared/MessagePopup.ascx",_report , DefConstants.MessageDesign.PopUp, "messagePopupBody");
eventArgs.ReturnValue = res;
}
}
Than it’s building the ActionResult of mine , after handling the message content
public class DefActionResult : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
DefJsonResult model = this.ActionModel;
/* If a view name has been specified, render it */
if (!string.IsNullOrEmpty(model.ViewName))
model.ViewHTML = controller.RenderViewToString(model.ViewName, model.ViewModel);
JsonResult res = new JsonResult() { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
res.ExecuteResult(context);
}
}
Then I’m building the response
public static class MVCExtensions
{
public static string RenderViewToString(this Controller controller, string viewName, object viewData)
{
//Create memory writer
var sb = new StringBuilder();
var memWriter = new StringWriter(sb);
//Create fake http context to render the view
var fakeResponse = new HttpResponse(memWriter);
var fakeContext = new HttpContext(HttpContext.Current.Request, fakeResponse);
var fakeControllerContext = new ControllerContext(
new HttpContextWrapper(fakeContext),
controller.ControllerContext.RouteData,
controller.ControllerContext.Controller);
var oldContext = HttpContext.Current;
HttpContext.Current = fakeContext;
//Use HtmlHelper to render partial view to fake context
var html = new HtmlHelper(new ViewContext(fakeControllerContext,
new FakeView(), controller.ViewData, controller.TempData, memWriter),
new ViewPage());
html.ViewDataContainer.ViewData = controller.ViewData;
html.RenderPartial(viewName, viewData);
//Restore context
//HttpContext.Current = oldContext;
//Flush memory and return output
memWriter.Flush();
return sb.ToString();
}
After returning my Message Popup as it should , it continues to the original action as if it didn't crush , and of course crushing because the data source is not initialized .
I don’t want to handle the errors with the HandleErrorAttribute because it’s not as dynamic as PostSharp .
How can I stop the remains of the original Request ?
(A remark , I am using the Telerik grid for mvc to show the data .)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要停止该方法正常进行,请使用 args.FlowBehavior.Return。除非有其他机制使用 try/catch,否则该方法应该已经执行此操作,但您的方面应该将其自身应用为最外层的 try/catch。您确实需要使用 ILSpy 查看程序集的最终 IL(此时其他反编译器都不会看到 postsharp 修改),然后您将能够看到发生了什么。如果你有一个action属性,那么我敢打赌它与它有关,因为postsharp会修改该方法,但action属性不会,所以它仍然是流程的最外层控制器。首先尝试 FlowBehavior。
To stop the method from proceeding as normal use args.FlowBehavior.Return. The method should do this already unless there is some other mechanism using a try/catch, but your aspect should apply itself as the outer most try/catch. You really need to look at your finale IL of the assembly using ILSpy (none of the other decompilers will see postsharp modifications at this point in time) then you will be able to see what is going on. If you have an action attribute, then I bet it has something to do with it since postsharp will modify the method but the action attribute will not so it remains the outer most controller of flow. Try FlowBehavior first.