문제

I have a feature receiver with some long running code, hence I use SPLongOperation and delegate for better visual appearance. Basically my feature receiver looks like so:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    SPLongOperation.Begin("Header",
                          "Caption",
                          delegate(SPLongOperation longOperation)
    {
        //custom code here
        longOperation.End("http://url", SPRedirectFlags.Static,
                          HttpContext.Current, null);
    });
}

My problem is that when an error occurs within my custom code, the feature still is "activated" - in the features list it still displays as being activated, even though an exception occurred.

How do I throw the exception back to FeatureActivated or how do I stop the feature from appearing as "activated" even though it ran into an error?


Update:

I know already that the exception thrown inside the delegate is just not passed to the FeatureActivated method, hence the feature activated already while the delegate might still be running.

I could get around using the delegate, but to instantiation a SPLongOperation I need a Page to pass - how would I get a Page without having this.Page inside a feature receiver?

The following should work:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    //Here I need to pass the ManageFeatures.aspx page? Any page? The LongRunningOperation.aspx page?
    Page page = new Page();
    SPLongOperation operation = new SPLongOperation(page);
    operation.Begin();

    //custom code here

    operation.End("http://url", SPRedirectFlags.Static,HttpContext.Current, null);
    });
}

When a feature is thrown within my custom code the exception will be passed to the feature activation and the feature will not be activated - only problem: What page to pass?

도움이 되었습니까?

해결책

Found the answer:

The problem really was that the exception was being thrown within the delegate. Hence the FeatureActivated just ran smoothly and the feature seemed activated.

Fortunately SPLongOperation can be instantiated with a Page: new SPLongOperation(Page page) - problem is that in a Feature Receiver i don't have this.Page.

I found the beautiful HttpContext.Current.Handler though which can be casted as Page.
The following does the trick:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    Page page = HttpContext.Current.Handler as Page;
    SPLongOperation operation = new SPLongOperation(page);
    operation.Begin();
    try
    {
        //custom code here

        operation.End("http://url", SPRedirectFlags.Static,HttpContext.Current, null);
    }
    catch (ThreadAbortException) {}
    catch (Exception ex) {throw ex;}
}

When an Exception is thrown within the long operation, it is still thrown back to the feature receiver (FeatureActivated) and the feature fails gracefully - meaning it doesn't get activated.

다른 팁

FeatureActivated is an asynchronous event that happens after the feature was activated. I know of no way to change the activation status except deactivating (SPFeature.Remove(id)) the feature programmatically, but not sure thats what you want...

Take a look at this blog. In the section marked SharePoint Exception Handling:

If you only catch and log the exception without throwing the SPException then the feature will complete the requested feature activation or de-activation (which ever the user is currently requesting) instead of aborting the feature activation or de-activation.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 sharepoint.stackexchange
scroll top