Всплывающее сообщение Mvc3 с проблемой обработки PostSharp OnException - PullRequest
1 голос
/ 06 ноября 2011
  1. У меня проблемы с возвратом всплывающего сообщения в mvc3, когда выдается какое-то исключение.
  2. Я использую PostSharp в качестве глобальной инфраструктуры AOP, чтобы перехватывать исключения и обрабатывать их, создавая текст всплывающего окна.
  3. Я расширил ActionResult для пользовательского объекта, который в ExecuteResult реализует метод RenderViewToString, который создает правильный HTML-код для messagePopup.
  4. MessagePopup отображается на странице, но Действие продолжает выполняться самостоятельно.

Как я могу остановить его дальнейшее выполнение?

Когда происходит сбой, я ловлю его глобально на

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 после обработки содержимого сообщения

открытый класс 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 для mvc для отображения данных.)

1 Ответ

1 голос
/ 06 ноября 2011

Чтобы метод не работал как обычно, используйте args.FlowBehavior.Return.Метод должен делать это уже, если только не существует какого-либо другого механизма, использующего try / catch, но ваш аспект должен применяться сам в качестве самого внешнего try / catch.Вам действительно нужно посмотреть свой финальный IL сборки с использованием ILSpy (ни один из других декомпиляторов не увидит постшарных изменений в данный момент), тогда вы сможете увидеть, что происходит.Если у вас есть атрибут action, то я уверен, что он как-то связан с ним, поскольку postsharp изменит метод, а атрибут action - нет, поэтому он остается самым внешним контроллером потока.Сначала попробуйте FlowBehavior.

...