Displaying results of an SPLongOperation - sharepoint

I am using SPLongOperation to run a lengthy operation. After completing, the gears page redirects back to the original page from which the long operation was launched. I am not able to write anything to the oriignal page using SPLongOperation.Endscript. Here is the code I am using
using (SPLongOperation operation = new SPLongOperation(this.Page))
{
//.......................
//.......................
StringBuilder endScript = new StringBuilder();
endScript.Append("document.write('Success!!');");
operation.End(Request.Url.ToString(), SPRedirectFlags.UseSource, HttpContext.Current, String.Empty, endScript.ToString());
}

You won't be able to write anything to the calling page, a new http request has been made to show you the page with the spinning wheel while your operation is under progress and then you're redirected back to the specified url (using a new request).
The easiest way to show a success message is to pass a specific querystring to your calling url by replacing your string.empty parameter with something like
operation.End(Request.Url.ToString(), SPRedirectFlags.UseSource, HttpContext.Current, "success=1");
http://msdn.microsoft.com/en-us/library/ms450341.aspx
and then on the load event, check if you have this parameter and display the relevant message (it would be better to add an item to the HttpContext.Items or doing a post instead of a get to remove the querystring but the suggested implementation will prevent you from changing your long operation call and behaviour)
Hope this will help.

Try an alert - that worked for me..
Script.Append("alert('Success!!');");

This might be of help: http://www.sharepoint-tips.com/2012/07/reporting-code-errors-when-running-code.html
SPLongOperation longOp = new SPLongOperation(this.Page);
StringBuilder sbErrors = new StringBuilder();
longOp.Begin();try
{
throw new Exception("Sample");
}
catch(Exception ex)
{
sbErrors.Append("An error occurred: " + ex.MEssage);
}
if
(sbErrors.Length > 0)
{
longOp.EndScript("document.getElementById('s4-simple-card-content').innerHTML = \"Errors have occurred during the submission. Details: " + sbErrors.ToString() + " \";");
}
//close the dialog if there were no errors
longOp.EndScript("window.frameElement.commitPopup();");

Related

Docusign Listener Argument Null (dev Sandbox)

I have created a webmethod in a C# webservice that listens for Docusign to call when an Envelope status changes:
[WebMethod]
public void DocuSignConnectUpdate(DocuSignEnvelopeInformation DocuSignEnvelopeInformation)
{
//Check if null
if (DocuSignEnvelopeInformation == null)
{
File.WriteAllText("C:\\websites\\DataAPI\\datalog.txt", "Data: " + "Data is null");
}
else
{
string envelopeId = "";
try
{
//Write a line in a file
File.WriteAllText("C:\\websites\\DataAPI\\datalog.txt", "Data: " + DocuSignEnvelopeInformation.ToString());
//Get some data out
envelopeId = DocuSignEnvelopeInformation.EnvelopeStatus.EnvelopeID;
//Write Data to a file
File.WriteAllText("C:\\websites\\DataAPI\\innerdatalog.txt", "Data: " + DocuSignEnvelopeInformation.ToString());
}
catch (Exception ex)
{
// could not serialize
File.WriteAllText("C:\\websites\\DataAPI\\errorlog.txt", "Exception: " + ex.Message);
throw new SoapException(ex.Message, SoapException.ClientFaultCode);
}
}
The issue I am having is that DocuSignEnvelopeInformation argument is not being set when called, so the code keeps terminating at the if==null statement. When I run the envelope data to the API using SoapUI everything works correctly. Any ideas what I'm missing would be appreciated.
EDIT: I wanted to Add the Interface here too since I forgot it originally
[ServiceContract(ConfigurationName = "IOperations", Namespace = "https://www.docusign.net/API/3.0")]
public interface IOperations
{
[OperationContract(Action = "DocuSignConnectListener/Operations/DocuSignConnectUpdate")]
[XmlSerializerFormat]
string DocuSignConnectUpdate(DocuSignEnvelopeInformation DocuSignEnvelopeInformation);
}
When a DocuSign webhook is set to use SOAP mode, the notification is sent as a SOAP request to your server (your listener).
If SOAP mode is off, then the notification is sent as a regular POST request with an XML body.
In your question, you say that
When I run the envelope data to the API using SoapUI everything works correctly
So it sounds like everything is worked as designed.
Ok I finally figured this out, turns out it just wasn't pretty enough so I added a decoration specifically:
[SoapDocumentMethod("http://tempuri.org/DocuSignConnectUpdate",
RequestNamespace = "http://tempuri.org",
ResponseNamespace = "http://tempuri.org",
Use = System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
on the method and now everything works like its supposed too. Now that I look at it, it makes a lot more sense.

How to get string query params from URL in Domino

After some time I managed to make a redirect from some API.
However, now I'm facing a different problem.
It seems, that there's just no way to get a query param from URL.
The button looks like that:
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:
var redirectUrl = context.getUrl().toString();
var errorRedirectUrl = context.getUrl().toString();
var EGRZAuthObject = new ru.iteko.egrz.requestprocessors.EGRZAuthorization();
//auth which redirects
EGRZAuthObject.initializeAuthProcess(redirectUrl, errorRedirectUrl);
print("marker param is " + param.get("marker"));
print("marker param is " + facesContext.getExternalContext().getRequest().getQueryString());
print("url " + context.getUrl().toString());
}]]></xp:this.action>
</xp:eventHandler>
The method which redirects is as follows:
public static void initializeAuthProcess(String redirectUrl, String apiRedirectUrl) throws ClientProtocolException, IOException
{
CloseableHttpClient httpclient = HttpClients.createDefault();
try
{
HttpContext context = new BasicHttpContext();
String urlToGoTo = AuthURLs.ESIALoginURL(redirectUrl, apiRedirectUrl);
HttpGet httpGet = new HttpGet(urlToGoTo);
HttpResponse response1 = httpclient.execute(httpGet, context);
HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(
HttpCoreContext .HTTP_REQUEST);
HttpHost currentHost = (HttpHost) context.getAttribute(
HttpCoreContext .HTTP_TARGET_HOST);
String redirectURLEsia = (currentReq.getURI().isAbsolute()) ? currentReq.getURI().toString() : (currentHost.toURI() + currentReq.getURI());
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext externalContext = fc.getExternalContext();
externalContext.redirect(redirectURLEsia);
}
finally
{
httpclient.close();
}
}
Here's what happens:
In a browser the user initializes auth process by pressing the button
Then initializeAuthProcess executes a request to the system A
System A takes us to the system B, we redirect the user there
The user goes through authorization process in the system B
System B (after auth) redirects the user to our system
And it appends some sort of token in our system's URL called marker
Later on, we should do something with the marker...
The problem is that we don't know how to get the marker. It's always either null or empty. In a browser, however, we always can see it after auth in the system B successfully completed.
I get the following output:
marker param is null
marker param is
url https://oursystem.com/Nav2.xsp
We also wondering how to remove it from the URL after processing is completed. But as of now, we need to get it at least.
How can we do that?
Thanks in advance.
EDIT:
Obviously the thing is that the code gets executed immediately without waiting for the user authorization in the system B.
For instance if we press the button again we'll have marker param.
So we need a different approach there we should define marker and do something with it
You looking at the wrong end. There are 2 options: pick the marker from the returned response1 calling the other systems or move that code to the page you redirect to
If you click the button, you are redirected to the other page. Testing for the marker should therefore be in the callback step between 5 & 6. Check in the beforeRenderResponse event if the marker is there and then you can react to that.

Xamarin: Issues with transitioning between controllers and storyboard views

I realize this might come across as a very basic question, but I just downloaded Xamarin three days ago, and I've been stuck on the same issue for two days without finding a solution.
Here is what I am trying to do:
Get user input, call API, parse JSON and pass data to another controller, and change views.
Here is what I have been able to do so far: I get the user input, I call the API, I parse the response back, write the token to a file, and I want to pass the remaining data to the second controller.
This is the code I am trying:
var verifyCode = Storyboard.InstantiateViewController("verify") as VerifyCodeController;
if (verifyCode != null)
{
this.NavigationController.PushViewController(verifyCode, true);
}
My storyboard setup:
Navigation controller -> routesTo -> FirstController
I have another UI Controller View set up with the following properties set:
storyboardid: verify
restorationid: verify
and I am trying to push that controller view onto the navigation controller.
Right now this line is erroring out:
var verifyCode = Storyboard.InstantiateViewController("verify") as VerifyCodeController;
giving me this error, which I don't know what it means: Could not find an existing managed instance for this object, nor was it possible to create a new managed instance.
Am I way off in my approach?
p.s: I cannot use the ctrl drag thing like the tutorial suggests because I have an asynchronous call. And I cannot under no circumstances make it synchronous. So all the page transition has to be manual.
EDIT
to anyone requesting more code or more info:
partial void registerButton_TouchUpInside (UIButton sender)
{
phone = registrationNumber.Text;
string url = url;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
request.Method = "GET";
Console.WriteLine("Getting response...");
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
{
Console.Out.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
}
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string content = reader.ReadToEnd();
if (string.IsNullOrWhiteSpace(content))
{
//Console.WriteLine(text);
Console.Out.WriteLine("Response contained empty body...");
}
else
{
var json = JObject.Parse (content);
var token = json["token"];
var regCode = json["regCode"];
var aURL = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments);
var filename = Path.Combine (aURL, "app.json");
File.WriteAllText(filename, "{token: '"+token+"'}");
// transition to main view. THIS IS WHERE EVERYTHING GETS MESSED UP
var verifyCode = Storyboard.InstantiateViewController("verify") as VerifyCodeController;
if (verifyCode != null)
{
this.NavigationController.PushViewController(verifyCode, true);
}
}
}
}
}
Here is all the info for every view in my storyboard:
1- Navigation controller:
- App starts there
- The root is the register pager, which is the page we are currently working on.
2- The register view.
- The root page
- class RegisterController
- No storyboard id
- No restoration id
3- The validate view
- Not connected to the navigation controller initially, but I want it to be connected eventually. Do I have to connect it either way? Through a segue?
- class VerifyCodeController
- storyboard id : verify
- restoration id : verify
If you guys need more information I'm willing to post more. I just think I posted everything relevant.

HTTP JVM: CLFAD0134E when performing getDocumentByKey method

On an xpage I run the following code:
function setPersonInfoCommon(x) {
//print("test printing to console value: " + x)
var serv = getPreferenceField("tx_server");
//e.g. "Development1";
var dbname = getPreferenceField("tx_loc_personal_common");
//e.g. "CustomerX\\Personnel.nsf"
var db:NotesDatabase = session.getDatabase(serv,dbname);
if (db == null) {
requestScope.status = "Database not found.";
return;
}
var vw:NotesView = db.getView("LookUpUsersUNID");
if (vw == null) {
requestScope.status = "View not found.";
return;
}
var doc:NotesDocument = vw.getDocumentByKey(x);
if (doc == null) {
requestScope.status = "Document not found.";
return;
}
else{
requestScope.status = "Document created:" + getCreated();
}
}
This freezes my XPage and in the log I see the following notation:
2014-08-19 12:46:11 HTTP JVM: com.ibm.xsp.webapp.FacesServlet$ExtendedServletException: com.ibm.xsp.FacesExceptionEx: java.io.NotSerializableException: lotus.domino.local.DateTime
2014-08-19 12:46:11 HTTP JVM: CLFAD0134E: Exception processing XPage request. For more detailed information, please consult error-log-0.xml located in E:/Domino/data/domino/workspace/logs
The XPage resides in a different NSF than the one I perform the getDocumentByKey method in. However I do not get any indication that the database (db) or view (vw) can not be found. If I check it by outputting the filepath or something I get the correct values returned.
I tested to run the code from within the NSF I perform the getDocumentByKey method and then the code runs just fine.
What can be the cause?
I am logged in via the web and have the proper rights.
Please always look at those more detailed logs in the location specified before posting a question. Those messages give much more information which will help identify the code causing the problem and usually a more detailed explanation.
In this particular case, the message on the console logs includes "java.io.NotSerializableException: lotus.domino.local.DateTime". Assuming this is relating to the line requestScope.status = "Document created:" + getCreated(); (the detailed logs will confirm) and that getCreated() is actually doc.getCreated(), that returns a NotesDateTime object.
NotesDateTime objects and any other Domino objects cannot be put in any scoped variable (there are various blogs explaining that Domino objects are not serializable).
If you want to put a date/time in a scope, you can get the Java date equivalent using NotesDateTime.toJavaDate(), so doc.getCreated().toJavaDate().

Primefaces progress bar live update

I am currently trying to incorporate a progress bar into my application to display the current progress of a task. The task, retrieves a file from a server using a web service. i do not have access to this web service and therefore cannot put any code inside it.
My code is as follows:
The method which I need to display progress of:
public URL checkout(String docCid, String fileCid)
{
String userId="aaaaaa";
FVConnectData fvData = new FVConnectData();
fvData.setWsKeyword("aaaaa");
fvData.setWsUrl("http://aaaaa.com");
FVConnector con = new FVConnector(fvData);
System.out.println("Method checkout called");
URL url = null;
try
{
//This is where the web service is called
url = con.checkoutFile(docCid, fileCid, userId, "aaaa", "aaaa", false);
System.out.println("URL: " + url.toString());
return url;
}
catch (Exception e)
{
System.out.println("ERROR: " + e.getMessage());
e.printStackTrace();
return null;
}
}
My question is this:
How can I adapt this method in order to provide my primefaces GUI with the live progress of the method to display to the user?
EDIT:
The only real examples I have found online use a random progress to display on the progress bar. I do not want this, I want the true (or close enough) progress. Also due to not being able to access the web service, I am unable to determine the size of the file before hand.

Resources