We have an Exchange Server 2010 SP2 running here on premise.
I'm using the EWS Managed API (I've tried both API/DLL version 1.2 and 2.1) to connect to it. I'm able to retrieve calendar, EWS Service name and version info, but on line "var appointments = calendar.FindAppointments(calenderView);" I get a 501 - Not Implement exception (see image).
I've searched the net but can't find any info on this error, nor do I find info on MSDN.
Below is the code I use:
Main Method:
private void Main_Load(object sender, EventArgs e)
{
ConnectWithExchange();
GetCalendarItems();
}
Instantation
/// <summary>
/// http://msdn.microsoft.com/en-us/library/office/ff597939(v=exchg.80).aspx
/// </summary>
private void ConnectWithExchange()
{
// 01. Instantiate ExchangeService
_exchange = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
// 02. Connect with credentials
_exchange.UseDefaultCredentials = true;
// or pass through credentials of a service user:
// _exchange.Credentials = new WebCredentials("user#name", "password", "domain");
// 03. Set correct endpoint
// http://msdn.microsoft.com/en-us/library/office/gg274410(v=exchg.80).aspx
// _exchange.Url = new Uri("https://outlook.kdg.be/EWS/Exchange.asmx");
// or use autodiscover
_exchange.AutodiscoverUrl("name#domain.com"); // works ok
// 04. Display version and info
UxExchangeVersion.Text = _exchange.Url.ToString(); // works ok
}
Retrieving Calendar Items
/// <summary>
/// http://msdn.microsoft.com/en-us/library/office/dn439786(v=exchg.80).aspx
/// </summary>
private void GetCalendarItems()
{
// 01. Init calendar folder object with the folder ID
CalendarFolder calendar = CalendarFolder.Bind(_exchange, WellKnownFolderName.Calendar, new PropertySet(FolderSchema.DisplayName));
// 02. Set start and end time and number of appointments to retrieve
CalendarView calenderView = new CalendarView(DateTime.Now, DateTime.Now.AddDays(7), 150);
// 03. Limit the properties returned
calenderView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End);
// 04. Fetch the appointments
var appointments = calendar.FindAppointments(calenderView);
// var appointments = _exchange.FindAppointments(calendar.Id, new CalendarView(DateTime.Now, DateTime.Now.AddDays(7))); // **failure point**
// 05. Display appiontments in list
// 05A. Fetch calender name
uxCalenderName.Text = calendar.DisplayName + " (" + calendar.Id.Mailbox + ")";
// 05B. Fill list
uxAppointments.Items.Clear();
foreach (var appointment in appointments)
{
var appointmentString = new StringBuilder();
appointmentString.Append("Subject: " + appointment.Subject.ToString() + " ");
appointmentString.Append("Start: " + appointment.Start.ToString() + " ");
appointmentString.Append("End: " + appointment.End.ToString());
uxAppointments.Items.Add(appointmentString.ToString());
}
}
I ran GetCalendarItems() and it works fine for me. I noticed that you don't have the URL redirection callback in _exchange.AutodiscoverUrl. I'm surprised that you can get the URL without a redirection.
internal static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
Can you tell me about your target server? What version of Exchange are you targeting?
Related
I'm trying to get response from FedEx Tracking API by using developer account credentials (UserCredentials) and I do not own ParentCredentials because I'm not Compatible User.
The code looks like this:
TrackRequest request = new TrackRequest();
request.WebAuthenticationDetail = new WebAuthenticationDetail();
request.WebAuthenticationDetail.UserCredential = new WebAuthenticationCredential();
request.WebAuthenticationDetail.UserCredential.Key = "XXX"; // Replace "XXX" with the Key
request.WebAuthenticationDetail.UserCredential.Password = "XXX"; // Replace "XXX" with the Password
request.WebAuthenticationDetail.ParentCredential = null;
request.ClientDetail = new ClientDetail();
request.ClientDetail.AccountNumber = "XXX"; // Replace "XXX" with the client's account number
request.ClientDetail.MeterNumber = "XXX"; // Replace "XXX" with the client's meter number
request.TransactionDetail = new TransactionDetail();
request.TransactionDetail.CustomerTransactionId = "***Track Request using VC#***"; //This is a reference field for the customer. Any value can be used and will be provided in the response.
request.Version = new VersionId();
// Tracking information
request.SelectionDetails = new TrackSelectionDetail[1] { new TrackSelectionDetail() };
request.SelectionDetails[0].PackageIdentifier = new TrackPackageIdentifier();
request.SelectionDetails[0].PackageIdentifier.Value = "123456789012"; // Replace "XXX" with tracking number or door tag
//if (usePropertyFile()) //Set values from a file for testing purposes
//{
// request.SelectionDetails[0].PackageIdentifier.Value = getProperty("trackingnumber");
//}
request.SelectionDetails[0].PackageIdentifier.Type = TrackIdentifierType.TRACKING_NUMBER_OR_DOORTAG;
// Date range is optional.
// If omitted, set to false
//request.SelectionDetails[0].ShipDateRangeBegin = DateTime.Parse("06/18/2012"); //MM/DD/YYYY
request.SelectionDetails[0].ShipDateRangeEnd = request.SelectionDetails[0].ShipDateRangeBegin.AddDays(0);
request.SelectionDetails[0].ShipDateRangeBeginSpecified = false;
request.SelectionDetails[0].ShipDateRangeEndSpecified = false;
// Include detailed scans is optional.
// If omitted, set to false
request.ProcessingOptions = new TrackRequestProcessingOptionType[1];
request.ProcessingOptions[0] = TrackRequestProcessingOptionType.INCLUDE_DETAILED_SCANS;
So, this is just a regular example that every developer user can access and main difference is that I do not use ParentCredentials.
The endpoint for accessing API is: https://ws.fedex.com/web-services/track
UserCredentials that I use are valid.
The response that I get contains the error message and the error code from the title of this question. How can I avoid it?
I'm using EWS in my winforms application to create a new appointment in my Outlook (+ to get items from my Outlook Calendar).
The issue i'm having is the following:
Everything works perfect but currently it takes 20-25 seconds to retrieve my appointments (= calendar items in Outlook) and 13-20 seconds to create an appointment
The code that does this comes straight from 'Google':
private void btn_Test_Click(object sender, EventArgs e)
{
DateTime d1 = DateTime.Now;
ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;
try
{
service = new ExchangeService(ExchangeVersion.Exchange2013);
service.Credentials = new WebCredentials("mail", "pass");
/*service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;*/
service.AutodiscoverUrl("mail", RedirectionUrlValidationCallback);
service.Url = new Uri("https://mail.domain.com/EWS/Exchange.asmx");
}
catch (Exception ml2)
{
MessageBox.Show(ml2.ToString());
}
// We get 10 items in the calendar for the next week
DateTime startDate = DateTime.Now;
DateTime endDate = startDate.AddDays(7);
const int NUM_APPTS = 10;
// Initialize the calendar folder object with only the folder ID.
CalendarFolder calendar = CalendarFolder.Bind(service, WellKnownFolderName.Calendar, new PropertySet());
// Set the start and end time and number of appointments to retrieve.
CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS);
// Limit the properties returned to the appointment's subject, start time, and end time.
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End);
// Retrieve a collection of appointments by using the calendar view.
FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);
Console.WriteLine("\nThe first " + NUM_APPTS + " appointments on your calendar from " + startDate.Date.ToShortDateString() +
" to " + endDate.Date.ToShortDateString() + " are: \n");
foreach (Appointment a in appointments)
{
Console.Write("Subject: " + a.Subject.ToString() + " ");
Console.Write("Start: " + a.Start.ToString() + " ");
Console.Write("End: " + a.End.ToString());
Console.WriteLine();
}
DateTime d2 = DateTime.Now;
MessageBox.Show( "Seconds: " + (d2 - d1).TotalSeconds.ToString());
}
Since I have absolutely 0 experience with EWS (or developing while using API's) I was wondering if there was room for performance or I wanted to know if this is just normal? I haven't found anything EWS = SLOW related so I was worrying a bit.
Could it be that my code is wrong or that i need to configure one thing or another server sided to improve results?
Thanks
The most likely thing to slow down you code is
service.AutodiscoverUrl("mail", RedirectionUrlValidationCallback);
service.Url = new Uri("https://mail.domain.com/EWS/Exchange.asmx");
You do an AutoDiscover and then set the link manually which is make the first AutoDiscover Call redundant. Auto-discover will do multiple searches of Local AD domain, DNS records to try and discover the correct URL to use so I would suggest if you are going to hardcode the URL you remark out the first line.
Also your testing logic only looks at the total time to execute you function which isn't going to be helpfully you should look at the time to complete each operation eg
FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);
or
CalendarFolder calendar = CalendarFolder.Bind(service, WellKnownFolderName.Calendar, new PropertySet());
or any Save, Send type method call when the actually call to the server is made if you time this that will give you a true indication of the speed of each call.
I have an invoice with multiple lines that I want to consolidate into one line. It takes the and iterates through each . It sums each to a variable. After the loop, it should create a new line on the invoice and delete the others.
I keep getting a "TxnLineID: required field is missing" even though I am providing it as "-1" for a new line:
private static void Main(string[] args)
{
// creates the session manager object using QBFC
var querySessionManager = new QBSessionManager();
// want to know if a session has begun so it can be ended it if an error happens
var booSessionBegun = false;
try
{
// open the connection and begin the session with QB
querySessionManager.OpenConnection("", "Test Connection");
querySessionManager.BeginSession("", ENOpenMode.omDontCare);
// if successful then booSessionBegin = True
booSessionBegun = true;
// Get the RequestMsgSet based on the correct QB Version
var queryRequestSet = GetLatestMsgSetRequest(querySessionManager);
// Initialize the message set request object
queryRequestSet.Attributes.OnError = ENRqOnError.roeStop;
// QUERY RECORDS **********************
// appendInvoiceQuery to request set
// only invoices that start with the consulting invoice prefix
// include all of the line items
// only unpaid invoices
var invoiceQ = queryRequestSet.AppendInvoiceQueryRq();
invoiceQ.ORInvoiceQuery.InvoiceFilter.ORRefNumberFilter.RefNumberFilter.MatchCriterion.SetValue(ENMatchCriterion.mcStartsWith);
invoiceQ.ORInvoiceQuery.InvoiceFilter.ORRefNumberFilter.RefNumberFilter.RefNumber.SetValue("ML-11");
invoiceQ.ORInvoiceQuery.InvoiceFilter.PaidStatus.SetValue(ENPaidStatus.psNotPaidOnly);
invoiceQ.IncludeLineItems.SetValue(true);
// DELETE INVOICE ***********************************
// var deleteI = queryRequestSet.AppendTxnDelRq();
// deleteI.TxnDelType.SetValue(ENTxnDelType.tdtInvoice);
// deleteI.TxnID.SetValue("3B57C-1539729221");
// Do the request and get the response message set object
var queryResponseSet = querySessionManager.DoRequests(queryRequestSet);
// Uncomment the following to view and save the request and response XML
var requestXml = queryRequestSet.ToXMLString();
// Console.WriteLine(requestXml);
SaveXML(requestXml, 1);
var responseXml = queryResponseSet.ToXMLString();
// Console.WriteLine(responseXml);
SaveXML(responseXml, 2);
// Get the statuscode of the response to proceed with
var respList = queryResponseSet.ResponseList;
var ourResp = respList.GetAt(0);
var statusCode = ourResp.StatusCode;
// Test what the status code
if (statusCode == 0)
{
// Parse the string into an XDocument object
var xmlDoc = XDocument.Parse(responseXml);
// Set the xmlDoc root
var xmlDocRoot = xmlDoc.Root.Element("QBXMLMsgsRs")
.Element("InvoiceQueryRs")
.Elements("InvoiceRet");
var i = 1;
// Iterate through the elements to get values and do some logic
foreach (var invoiceElement in xmlDocRoot)
{
// Create connection to update
var updateSessionManager = new QBSessionManager();
updateSessionManager.OpenConnection("", "Test Connection");
updateSessionManager.BeginSession("", ENOpenMode.omDontCare);
// Make the request set for updates
var updateRequestSet = GetLatestMsgSetRequest(updateSessionManager);
updateRequestSet.Attributes.OnError = ENRqOnError.roeStop;
// Set the variables required to edit a file
var txnId = (string) invoiceElement.Element("TxnID");
var editSequence = (string) invoiceElement.Element("EditSequence");
var xmlLineItemRoot = invoiceElement.Elements("InvoiceLineRet");
var feeAmount = 0.0f;
foreach (var invoiceLineItemElement in xmlLineItemRoot)
{
if (invoiceLineItemElement.Element("ItemRef").Element("FullName").Value == "Consulting Fees:Consulting")
{
feeAmount = float.Parse(invoiceLineItemElement.Element("Amount").Value) + (float) feeAmount;
}
}
//// UPDATING RECORDS ******************************
//// TxnID and EditSequence required
var invoiceM = updateRequestSet.AppendInvoiceModRq();
invoiceM.TxnID.SetValue(txnId);
invoiceM.EditSequence.SetValue(editSequence);
invoiceM.ORInvoiceLineModList.Append().InvoiceLineMod.TxnLineID.SetValue("-1");
invoiceM.ORInvoiceLineModList.Append().InvoiceLineMod.ItemRef.FullName.SetValue("Consulting Fees:Consulting");
invoiceM.ORInvoiceLineModList.Append().InvoiceLineMod.Amount.SetValue((double)feeAmount);
updateSessionManager.DoRequests(updateRequestSet);
i++;
updateSessionManager.EndSession();
updateSessionManager.CloseConnection();
}
}
// end and disconnect after done
querySessionManager.EndSession();
booSessionBegun = false;
querySessionManager.CloseConnection();
}
catch (Exception e)
{
// if it couldn't connect then display a message saying so and make sure to EndSession/CloseConnection
Console.WriteLine(e.Message.ToString() + "\nStack Trace: \n" + e.StackTrace + "\nExiting the application");
if (booSessionBegun)
{
querySessionManager.EndSession();
querySessionManager.CloseConnection();
}
}
}
Furthermore, I want it to remove the lines from the invoice that were used in the sum. I've read conflicting information on how to do this.
One camp says, don't specify those lines and it will erase them when the updateRequestSet is executed. Another contradicts by saying that not specifying them, it will retain them. Can someone please clear this up. I haven't gotten far enough to test, however.
Oh and here is the entirety of the error:
InvoiceMod
ORInvoiceLineModList:
element(2) - InvoiceLineMod:
TxnLineID: required field is missing
End of InvoiceLineMod
End of ORInvoiceLineModList
End of InvoiceMod
Stack Trace:
at Interop.QBFC13.IQBSessionManager.DoRequests(IMsgSetRequest request)
at ConsolidateInvoiceLineItems.Program.Main(String[] args) in C:\qb\QuickBooks\ConsolidateInvoiceLineItems\ConsolidateInvoiceLineItems\Program.cs:line 226
Exiting the application
Wish I could take credit for this, but actually got help from the Intuit Developers forum.
Need to change the multiple Append() to the following:
var invoiceModLineItems = invoiceM.ORInvoiceLineModList.Append().InvoiceLineMod;
invoiceModLineItems.TxnLineID.SetValue("-1");
invoiceModLineItems.ItemRef.FullName.SetValue("Consulting Fees:Consulting");
invoiceModLineItems.Amount.SetValue((double)feeAmount);
I am having with using Aspose to generate dynamic content in slides within Microsoft CRM Dynamics 2011. The data is not populating correctly for several fields and relationals even though the logic in the code seems to be correct and should not yield a null or empty value, and I have confirmed there is indeed data for the fields in the database (The data does populate correctly for some of the fields and relationals). All of these issues occur before the powerpoint itself even starts to be generated, so in reality the issues may not be “Aspose” issues they may just be Web Service / CRM issues with retrieving the data asynchronously.
Aspose Slide Workflow:
1) An HTML web resource includes a Silverlight button to download powerpoint report
2) On button click the Silverlight application Asyncronosously collects all the data needed from the Project entity in CRM through web service requests
3) The data is compiled into a Project class that is then passed over to the ReportGenerator Service and uses the data to populate the parts of the powerpoint (This is the part where we use the custom Aspose stuff)
4) Aspose functionality goes through each specified slide and parses them adding in the data where required.
5) Powerpoint is completed and spit out for the user with the data populated.
These are two examples of where I am having troubles getting data to populate. The project.Pwins value below ends up being null which tells me the lambda expression is not executing appropriately, it remains null at the end of the method which tells me the highlighted line is not even being executed at all.
Example 1:
/// <summary>
/// Retrieves and stores information required for P(win) report, and then tries to send a web service request.
/// </summary>
/// <param name="service"></param>
private void LoadPwin(ReportServiceClient service)
{
string filter = string.Format("?$filter=sfa_Project/Id eq guid'{0}'", GetProjectId());
string url = GetEntitySetAddress("sfa_pwin_competitor") + filter;
WebClient client = new WebClient();
client.DownloadStringCompleted += (sender, args) =>
{
if (args.Error == null)
{
StringReader stream = new StringReader(args.Result);
XmlReader reader = XmlReader.Create(stream);
List<PWin> pwins = new List<PWin>();
List<Dictionary<string, string>> dictionaries = LoadEntitiesFromXml(reader);
foreach (Dictionary<string, string> dictionary in dictionaries)
{
PWin pwin = new PWin();
pwin.CompanyName = ParseDictionaryValue(dictionary["sfa_competitor"]);
pwin.IsBoeing = (ParseDictionaryValue(dictionary["sfa_is_boeing"]) == "true");
pwin.IsDomestic = (ParseDictionaryValue(dictionary["sfa_domestic_or_international"]) == "true");
pwin.AffordabilityWeight = ParseDictionaryValueToNumber(dictionary["sfa_affordability_weight"]);
pwin.AffordabilityScore = ParseDictionaryValueToNumber(dictionary["sfa_affordability_score"]);
pwin.CustomerRelationshipWeight = ParseDictionaryValueToNumber(dictionary["sfa_customer_relationship_weight"]);
pwin.CustomerRelationshipScore = ParseDictionaryValueToNumber(dictionary["sfa_customer_relationship_score"]);
pwin.CustomerAdvantageWeight = ParseDictionaryValueToNumber(dictionary["sfa_customer_advantage_weight"]);
pwin.CustomerAdvantageScore = ParseDictionaryValueToNumber(dictionary["sfa_customer_advantage_score"]);
pwin.CompetitionWeight = ParseDictionaryValueToNumber(dictionary["sfa_competition_weight"]);
pwin.CompetitionScore = ParseDictionaryValueToNumber(dictionary["sfa_competition_score"]);
pwin.CPOBCWeight = ParseDictionaryValueToNumber(dictionary["sfa_cpobc_weight"]);
pwin.CPOBCScore = ParseDictionaryValueToNumber(dictionary["sfa_cpobc_score"]);
pwin.CompanyResourcesWeight = ParseDictionaryValueToNumber(dictionary["sfa_company_resources_weight"]);
pwin.CompanyResourcesScore = ParseDictionaryValueToNumber(dictionary["sfa_company_resources_score"]);
pwin.CompanyResourcesInvestmentWeight = ParseDictionaryValueToNumber(dictionary["sfa_company_resources_investment_weight"]);
pwin.CompanyResourcesInvestmentScore = ParseDictionaryValueToNumber(dictionary["sfa_company_resources_investment_score"]);
pwin.ProgramBackgroundWeight = ParseDictionaryValueToNumber(dictionary["sfa_program_background_weight"]);
pwin.ProgramBackgroundScore = ParseDictionaryValueToNumber(dictionary["sfa_program_background_score"]);
pwin.ContinuityOfEffortWeight = ParseDictionaryValueToNumber(dictionary["sfa_continuity_of_effort_weight"]);
pwin.ContinuityOfEffortScore = ParseDictionaryValueToNumber(dictionary["sfa_continuity_of_effort_score"]);
pwin.ExecutionWeight = ParseDictionaryValueToNumber(dictionary["sfa_execution_weight"]);
pwin.ExecutionScore = ParseDictionaryValueToNumber(dictionary["sfa_execution_score"]);
pwin.TechnicalSolutionWeight = ParseDictionaryValueToNumber(dictionary["sfa_technical_solution_weight"]);
pwin.TechnicalSolutionScore = ParseDictionaryValueToNumber(dictionary["sfa_technical_solution_score"]);
pwin.StrategyToWinWeight = ParseDictionaryValueToNumber(dictionary["sfa_strategy_to_win_weight"]);
pwin.StrategyToWinScore = ParseDictionaryValueToNumber(dictionary["sfa_strategy_to_win_score"]);
pwin.ManagementStrengthWeight = ParseDictionaryValueToNumber(dictionary["sfa_management_strength_weight"]);
pwin.ManagementStrengthScore = ParseDictionaryValueToNumber(dictionary["sfa_management_strength_score"]);
pwin.CustomerPercievedCommitmentWeight = ParseDictionaryValueToNumber(dictionary["sfa_customers_percieved_commitment_weight"]);
pwin.CustomerPercievedCommitmentScore = ParseDictionaryValueToNumber(dictionary["sfa_customers_percieved_commitment_score"]);
pwin.PastPerformanceWeight = ParseDictionaryValueToNumber(dictionary["sfa_past_performance_weight"]);
pwin.PastPerformanceScore = ParseDictionaryValueToNumber(dictionary["sfa_past_performance_score"]);
pwin.RawPWin = ParseDictionaryValueToDecimal(dictionary["sfa_pwin_score"]);
pwin.RelativePWin = ParseDictionaryValueToDecimal(dictionary["sfa_relative_pwin_score"]);
pwins.Add(pwin);
}
project.PWins = new ObservableCollection<PWin>(pwins);
PwinReady = true;
reader.Close();
TrySendRequest(service);
}
};
client.DownloadStringAsync(new Uri(url));
}
Example 2 the project.TeamMembers value below ends up being null:
/// <summary>
/// Retrieves and stores information required for Capture Team Roster report, and then tries to send a web service request.
/// </summary>
/// <param name="service"></param>
private void LoadCaptureTeamRoster(ReportServiceClient service)
{
string filter = string.Format("?$select=sfa_name,sfa_Role&$filter=sfa_Project/Id eq guid'{0}'", GetProjectId());
string url = GetEntitySetAddress("sfa_team_roster") + filter;
WebClient client = new WebClient();
client.DownloadStringCompleted += (sender, args) =>
{
if (args.Error == null)
{
StringReader stream = new StringReader(args.Result);
XmlReader reader = XmlReader.Create(stream);
List<TeamMember> members = new List<TeamMember>();
List<Dictionary<string, string>> dictionaries = LoadEntitiesFromXml(reader);
foreach (Dictionary<string, string> dictionary in dictionaries)
{
TeamMember member = new TeamMember();
member.Name = ParseDictionaryValue(dictionary["sfa_name"]);
member.Role = ParseDictionaryValue(dictionary["sfa_role"]);
members.Add(member);
}
project.TeamMembers = new ObservableCollection<TeamMember>(members);
CaptureTeamRosterReady = true;
reader.Close();
TrySendRequest(service);
}
};
client.DownloadStringAsync(new Uri(url));
}
Here is another example that is not an issue with a relational, but instead is an issue with a field populated on a project entity in CRM that shows up empty after retrieving the data. Both CaptureTeamLeader and ProgramManager end up being empty strings, however the ProjectName and ProjectNumber have no troubles populating
private void LoadCampaignTitle(ReportServiceClient service)
{
project.ProjectName = GetAttributeValue("sfa_name");
project.ProjectNumber = GetAttributeValue("sfa_project_number");
project.CaptureTeamLeader = GetAttributeValue("sfa_capture_team_leader_emp");
project.ProgramManager = GetAttributeValue("sfa_program_manager_emp");
CampaignTitleReady = true;
TrySendRequest(service);
}
Any help would be greatly appreciated. Thanks in advance!
EDIT:
This is the AttributeValue method asked for:
/// <summary>
/// Gets the value of provided attribute from the current page's Xrm data. If for any reason the retrieval fails, returns an empty string.
/// </summary>
/// <param name="attributeName"></param>
/// <returns></returns>
private string GetAttributeValue(string attributeName)
{
// NOTE: This is the preferred way to retrieve data from the CRM. However for some unknown issue,
// this always returns NULL. It will be replaced with directly calling .eval to the window object.
// dynamic Xrm = (ScriptObject)HtmlPage.Window.GetProperty("window.parent.Xrm");
try
{
return HtmlPage.Window.Invoke("getAttributeValue", attributeName).ToString();
}
catch (ArgumentNullException)
{
return string.Empty;
}
catch (ArgumentException)
{
return string.Empty;
}
catch (InvalidOperationException)
{
return string.Empty;
}
}
The solution to this problem was that number 1 The downloadstringasync and other places in my code were doing things asynchronously and therefore the debugger was throwing me off and showing things as null when they were really just being executed later. The actual fix required some changes to a client.xml file in the folder the webservice was being hosted from.
I am trying to upload a simple text file to a specific folder in google documents but with no luck.
FileStream fileStream = new FileStream(#"c:\test.txt", System.IO.FileMode.Open);
DocumentEntry lastUploadEntry =
globalData.service.UploadDocument("c:\\test.txt", null);
string feed =
"https://docs.google.com/feeds/upload/create-session/default/private/full/folder%folder:0B2dzFB6YvN-kYTRlNmNhYjEtMTVmNC00ZThkLThiMjQtMzFhZmMzOGE2ZWU1/contents/";
var result =
globalData.service.Insert(new Uri(feed), fileStream, "application/pdf", "test");
I get an error saying
"The remote server returned an error: (503) Server Unavailable."
I am suspecting that the destination folders uri is wrong but i can't figure out the correct one.
There's a complete sample at https://developers.google.com/google-apps/documents-list/#uploading_a_new_document_or_file_with_both_metadata_and_content that uses the resumable upload component:
using System;
using Google.GData.Client;
using Google.GData.Client.ResumableUpload;
using Google.GData.Documents;
namespace MyDocumentsListIntegration
{
class Program
{
static void Main(string[] args)
{
DocumentsService service = new DocumentsService("MyDocumentsListIntegration-v1");
// TODO: Instantiate an Authenticator object according to your authentication
// mechanism (e.g. OAuth2Authenticator).
// Authenticator authenticator = ...
// Instantiate a DocumentEntry object to be inserted.
DocumentEntry entry = new DocumentEntry();
// Set the document title
entry.Title.Text = "Legal Contract";
// Set the media source
entry.MediaSource = new MediaFileSource("c:\\contract.txt", "text/plain");
// Define the resumable upload link
Uri createUploadUrl = new Uri("https://docs.google.com/feeds/upload/create-session/default/private/full");
AtomLink link = new AtomLink(createUploadUrl.AbsoluteUri);
link.Rel = ResumableUploader.CreateMediaRelation;
entry.Links.Add(link);
// Set the service to be used to parse the returned entry
entry.Service = service;
// Instantiate the ResumableUploader component.
ResumableUploader uploader = new ResumableUploader();
// Set the handlers for the completion and progress events
uploader.AsyncOperationCompleted += new AsyncOperationCompletedEventHandler(OnDone);
uploader.AsyncOperationProgress += new AsyncOperationProgressEventHandler(OnProgress);
// Start the upload process
uploader.InsertAsync(authenticator, entry, new object());
}
static void OnDone(object sender, AsyncOperationCompletedEventArgs e) {
DocumentEntry entry = e.Entry as DocumentEntry;
}
static void OnProgress(object sender, AsyncOperationProgressEventArgs e) {
int percentage = e.ProgressPercentage;
}
}
}
Just follow the article Google Apps Platform Uploading documents
Also check out Google Documents List API version 3.0
Uri should be something similar to below:
string feed = #"https://developers.google.com/google-apps/documents-list/#getting_a_resource_entry_again";
//it may not be exact, just check and read from the links
Try this uri:
"https://docs.google.com/feeds/default/private/full/folder%3A" + fRid + "/contents"
//fRid is the Resource Id of the folder.. in your case: 0B2dzFB6YvN-kYTRlNmNhYjEtMTVmNC00ZThkLThiMjQtMzFhZmMzOGE2ZWU1
Also I guess your URI is giving this error because you are using folder resource ID as - folder:resourceID
Try removing folder: and use only RID
Code to cutout "folder:" -
int ridIndex = dRid.IndexOf(":");
Rid = Rid.Substring(ridIndex + 1);