How do you “stop” activating a feature within the feature receiver?
-
16-10-2019 - |
문제
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.