Below is the code I'm working with to pass multiple line items to create sales order through GP Web service. I can pass single Line Item without any problem , but when I pass multiple Items it is only taking the last one. The array has around 5 Item ID and I'm passing fixed Quantity as 15, Need to make both dynamic. But for the testing purpose I'm trying like this. I know the problem with the creation/initialization of some web service objects. As novice to the entire set of things I couldn't find the exact problem.
C# Code
CompanyKey companyKey;
Context context;
SalesOrder salesOrder;
SalesDocumentTypeKey salesOrderType;
CustomerKey customerKey;
BatchKey batchKey;
// SalesOrderLine salesOrderLine;
ItemKey orderedItem;
Quantity orderedAmount;
Policy salesOrderCreatePolicy;
DynamicsGPClient wsDynamicsGP = new DynamicsGPClient();
wsDynamicsGP.ClientCredentials.Windows.ClientCredential.UserName = "Admin";
wsDynamicsGP.ClientCredentials.Windows.ClientCredential.Password = "pass";
wsDynamicsGP.ClientCredentials.Windows.ClientCredential.Domain = "Gp";
System.ServiceModel.WSHttpBinding binding;
binding = new System.ServiceModel.WSHttpBinding(System.ServiceModel.SecurityMode.None);
context = new Context();
companyKey = new CompanyKey();
companyKey.Id = (1);
context.OrganizationKey = (OrganizationKey)companyKey;
salesOrder = new SalesOrder();
salesOrderType = new SalesDocumentTypeKey();
salesOrderType.Type = SalesDocumentType.Order;
salesOrder.DocumentTypeKey = salesOrderType;
customerKey = new CustomerKey();
customerKey.Id = "121001";
salesOrder.CustomerKey = customerKey;
batchKey = new BatchKey();
batchKey.Id = "RMS";
salesOrder.BatchKey = batchKey;
// SalesOrderLine[] orders = new SalesOrderLine[6];
SalesOrderLine[] lines = { };
for (int i = 1; i < 5; i++)
{
SalesOrderLine salesOrderLine = new SalesOrderLine();
orderedItem = new ItemKey();
orderedItem.Id = Arr[i].ToString();
salesOrderLine.ItemKey = orderedItem;
orderedAmount = new Quantity();
orderedAmount.Value = 15;
salesOrderLine.Quantity = orderedAmount;
lines = new SalesOrderLine[] { salesOrderLine };
MessageBox.Show(lines.Count().ToString());
}
salesOrder.Lines = lines;
//salesOrder.Lines = orders;
salesOrderCreatePolicy = wsDynamicsGP.GetPolicyByOperation("CreateSalesOrder", context);
wsDynamicsGP.CreateSalesOrder(salesOrder, context, salesOrderCreatePolicy);
if (wsDynamicsGP.State != CommunicationState.Faulted)
{
wsDynamicsGP.Close();
}
MessageBox.Show("Success");
lines = new SalesOrderLine[] { salesOrderLine }; will recreate the lines array object each time meaning you loose any previously added objects. Effectively only the final object in the loop is actually added.
Try using a List<T> like so:
SalesOrderLine[] lines = { }; Becomes List<SalesOrderLine> lines = new List<SalesOrderLine>();
lines = new SalesOrderLine[] { salesOrderLine }; Becomes: lines.Add(salesOrderLine);
If its important you end up with an array as the input:
salesOrder.Lines = lines; Becomes: salesOrder.Lines = lines.ToArray();
Related
I am trying to set the value of object property which is of type List and initialise it by using a foreach to add the items to the list e.g.
var sessionPlanner = new SessionPlannerDTO()
{
Age = "",
NumberOfPlayers = session.numberOfPlayers.Value,
MedicalInformation = "",
PlayerNeeds = "",
SessionDate = session.daySessionDate.Value,
Location = session.Location.locationName,
PracticeView = new List<PracticeViewDTO>(foreach(var practice in session.Sessions){
new PracticeViewDTO(){AbilityLevel = practice.ActivityPlan.abilityLevel.Value,
ActivityUrl = practice.ActivityPlan.activityUrl,
EquipmentNeeds = practice.ActivityPlan.equipmentNeeds,
FacilityNeeds = practice.ActivityPlan.activityNeeds,
HealthAndSafety = practice.ActivityPlan.healthAndSafetyIssues,
SessionTitle = practice.ActivityPlan.activityName
};
})
};
PracticeView is what I am trying to achieve by making it a list without doing the below:
var practiceViewList = new List<PracticeViewDTO>();
foreach(var practice in session.Sessions)
{
var practiceX = new PracticeViewDTO()
{
AbilityLevel = practice.ActivityPlan.abilityLevel.Value,
ActivityUrl = practice.ActivityPlan.activityUrl
};
practiceViewList.Add(practiceX);
}
You can't use other code than assignments in object or collection initializers. So your foreach() there won't compile.
Use session.Sessions.Select() to map the source entities to your DTO, and ToList() to create a list of the result:
sessionPlanner = new SessionPlannerDTO
{
Age = "",
// ...
PracticeView = session.Sessions.Select(s =>
new PracticeViewDTO
{
AbilityLevel = s.ActivityPlan.abilityLevel.Value,
// ...
}).ToList()
};
You also may want to consider using AutoMapper, instead of hand-writing mapping code.
I am using SuiteTalk web services (v. 2013_2) . I am trying to create an ItemFulfillment where the items in it were related to items that had a lot or serial number.
When I try to save this item fulfillment into NetSuite I get an error of :
Please commit inventorydetail on this line.
I was attempting to set the itemFulfillment.serialNumbers and itemFulfillment.binNumbers when I create the itemFulfillmentItem.
For example I set
nsIfItem.serialNumbers = "SNum(5)"
nsIfItem.binNumbers = "BNum(5)"
based on those properties being- A comma delimited list of serial or LOT numbers. If entering serial numbers there must be a number for each item.
Lot numbers must be entered in a format of LOT#(Quantity).
For example, to enter a quantity of 100 items as Lot number ABC1234, enter ABC1234(100).
Do I also need to set something else on the itemFulfillment or how do I get rid of that error.
I'm not sure if this question is still active, but I had the same issue and iI couldn't find much help on it. I solved this issue by creating the inventory assignment objects and adding to the transaction.
First, create the initialize ref for Item Fulfillment and assign the returned record to a variable:
InitializeRecord ir = new InitializeRecord();
ir.type = InitializeType.itemFulfillment;
InitializeRef iref = new InitializeRef();
iref.typeSpecified = true;
iref.type = InitializeRefType.salesOrder;
iref.internalId = 'Sales Order internalID';
ir.reference = iref;
ReadResponse getInitResp = _service.initialize(ir);
ItemFulfillment ifrec = (ItemFulfillment)getInitResp.record;
Get the list of items on the initialized transaction:
ItemFulfillmentItemList ifitemlist = ifrec.itemList;
Create a list to which to add each unique item being fulfilled:
List<ItemFulfillmentItem> ifitems = new List<ItemFulfillmentItem>();
Run the following code for each item in initialized transaction's item list:
If the current line item has already been added to the ifitems list, add the current Fulfillment line as an assignment to that item:
InventoryAssignment assignment = new InventoryAssignment
{
issueInventoryNumber = new RecordRef { internalId = 'internalID',
type = 'RecordType',
typeSpecified = true
}
};
List<InventoryAssignment> list = new List<InventoryAssignment>();
list.Add(assignment);
ifitemlist.item[b].inventoryDetail = new InventoryDetail
{
inventoryAssignmentList = new InventoryAssignmentList
{
inventoryAssignment = list.ToArray()
}
};
ifitemlist.item[b].quantity += 'quantity shipped';
If the line item has not yet been added, create new line item:
ItemFulfillmentItem ffItem = new ItemFulfillmentItem();
ffItem.item = ifitemlist.item[b].item;
ffItem.itemReceive = true;
ffItem.itemReceiveSpecified = true;
ffItem.itemIsFulfilled = true;
itemIsFulfilled = true;
ffItem.itemIsFulfilledSpecified = true;
ffItem.orderLineSpecified = true;
ffItem.orderLine = ifitemlist.item[b].orderLine;
//Check if serialized
if (Your fulfillment item contains serialized data)
{
ffItem.serialNumbers = 'Serial numbers';
InventoryAssignment assignment = new InventoryAssignment
{
issueInventoryNumber = new RecordRef {
internalId = 'Inventory internal ID',
type = RecordType,
typeSpecified = true
}
};
ffItem.inventoryDetail = new InventoryDetail
{
inventoryAssignmentList = new InventoryAssignmentList
{
inventoryAssignment = new InventoryAssignment[]
{
assignment
},
replaceAll = false
},
nullFieldList = new string[] { },
customForm = new RecordRef { }
};
}
ffItem.quantity = 'QUANTITY SHIPPED';
ffItem.quantitySpecified = true;
ifitems.Add(ffItem);
Finally, add your "ifitems" list to your Item Fulfillment and add this to NetSuite:
ItemFulfillmentItemList ifitemlistToFulfill = new ItemFulfillmentItemList();
ifitemlistToFulfill.replaceAll = false;
ifitemlistToFulfill.item = ifitems.ToArray();
ItemFulfillment newItemFulfill = new ItemFulfillment();
newItemFulfill.itemList = ifitemlistToFulfill;
_service.add(newItemFulfill);
I have written a method to insert a table in a word document using Open XML. The method accepts a generic list and a few parameters to control number of columns, column headings etc.
That all works fine.
However when populating the cells in the table I want to pull out the values for each row and place them in their corresponding columns. Given the names of the properties are going to change depending on the contents of the generic list, I am not sure how to accomplish this.
Anyone that can point me in the right direction it would be appreciated.
void InsertTable<T>(List<T> tableData, int[] tableHeadingCount, string[] columnHeadings, string locationInDocument)
{
using (WordprocessingDocument myDoc = WordprocessingDocument.Open(_newDocument, true))
{
var docPart = myDoc.MainDocumentPart;
var doc = docPart.Document;
var table = new Table();
var tableBorderTop = new TopBorder();
var tableBorderBottom = new BottomBorder();
var tableBorderLeft = new LeftBorder();
var tableBorderRight = new RightBorder();
var tableBorderHorizontal = new InsideHorizontalBorder();
var tableBorderVertical = new InsideVerticalBorder();
var tableProperties = new TableProperties();
var borders = new TableBorders();
// Set Border Styles for Table
tableBorderTop.Val = BorderValues.Single;
tableBorderTop.Size = 6;
tableBorderBottom.Val = BorderValues.Single;
tableBorderBottom.Size = 6;
tableBorderLeft.Val = BorderValues.Single;
tableBorderLeft.Size = 6;
tableBorderRight.Val = BorderValues.Single;
tableBorderRight.Size = 6;
tableBorderHorizontal.Val = BorderValues.Single;
tableBorderHorizontal.Size = 6;
tableBorderVertical.Val = BorderValues.Single;
tableBorderVertical.Size = 6;
// Assign Border Styles to Table Borders
borders.TopBorder = tableBorderTop;
borders.BottomBorder = tableBorderBottom;
borders.LeftBorder = tableBorderLeft;
borders.RightBorder = tableBorderRight;
borders.InsideHorizontalBorder = tableBorderHorizontal;
borders.InsideVerticalBorder = tableBorderVertical;
// Append Border Styles to Table Properties
tableProperties.Append(borders);
// Assign Table Properties to Table
table.Append(tableProperties);
var tableRowHeader = new TableRow();
tableRowHeader.Append(new TableRowHeight() { Val = 2000 });
for (int i = 0; i < tableHeadingCount.Length; i++)
{
var tableCellHeader = new TableCell();
//Assign Font Properties to Run
var runPropHeader = new RunProperties();
runPropHeader.Append(new Bold());
runPropHeader.Append(new Color() { Val = "000000" });
//Create New Run
var runHeader = new Run();
//Assign Font Properties to Run
runHeader.Append(runPropHeader);
var columnHeader = new Text();
//Assign the Pay Rule Name to the Run
columnHeader = new Text(columnHeadings[i]);
runHeader.Append(columnHeader);
//Create Properties for Paragraph
var justificationHeader = new Justification();
justificationHeader.Val = JustificationValues.Left;
var paraPropsHeader = new ParagraphProperties(justificationHeader);
SpacingBetweenLines spacing = new SpacingBetweenLines() { Line = "240", LineRule = LineSpacingRuleValues.Auto, Before = "0", After = "0" };
paraPropsHeader.Append(spacing);
var paragraphHeader = new Paragraph();
paragraphHeader.Append(paraPropsHeader);
paragraphHeader.Append(runHeader);
tableCellHeader.Append(paragraphHeader);
var tableCellPropertiesHeader = new TableCellProperties();
var tableCellWidthHeader = new TableCellWidth();
tableCellPropertiesHeader.Append(new Shading() { Val = ShadingPatternValues.Clear, Color = "auto", Fill = "#C0C0C0" });
var textDirectionHeader = new TextDirection();
textDirectionHeader.Val = TextDirectionValues.BottomToTopLeftToRight;
tableCellPropertiesHeader.Append(textDirectionHeader);
tableCellWidthHeader.Type = TableWidthUnitValues.Dxa;
tableCellWidthHeader.Width = "2000";
tableCellPropertiesHeader.Append(tableCellWidthHeader);
tableCellHeader.Append(tableCellPropertiesHeader);
tableRowHeader.Append(tableCellHeader);
}
tableRowHeader.AppendChild(new TableHeader());
table.Append(tableRowHeader);
//Create New Row in Table for Each Record
foreach (var record in tableData)
{
var tableRow = new TableRow();
for (int i = 0; i < tableHeadingCount.Length; i++)
{
//**** This is where I dynamically want to iterate through selected properties and output the value ****
var propertyText = "Test";
var tableCell = new TableCell();
//Assign Font Properties to Run
var runProp = new RunProperties();
runProp.Append(new Bold());
runProp.Append(new Color() { Val = "000000" });
//Create New Run
var run = new Run();
//Assign Font Properties to Run
run.Append(runProp);
//Assign the text to the Run
var text = new Text(propertyText);
run.Append(text);
//Create Properties for Paragraph
var justification = new Justification();
justification.Val = JustificationValues.Left;
var paraProps = new ParagraphProperties(justification);
var paragraph = new Paragraph();
paragraph.Append(paraProps);
paragraph.Append(run);
tableCell.Append(paragraph);
var tableCellProperties = new TableCellProperties();
var tableCellWidth = new TableCellWidth();
tableCellWidth.Type = TableWidthUnitValues.Dxa;
tableCellWidth.Width = "2000";
tableCellProperties.Append(tableCellWidth);
tableCell.Append(tableCellProperties);
tableRow.Append(tableCell);
}
table.Append(tableRow);
}
var res = from bm in docPart.Document.Body.Descendants<BookmarkStart>()
where bm.Name == locationInDocument
select bm;
var bookmark = res.SingleOrDefault();
var parent = bookmark.Parent; // bookmark's parent element
Paragraph newParagraph = new Paragraph();
parent.InsertAfterSelf(newParagraph);
if (bookmark != null)
{
newParagraph.InsertBeforeSelf(table);
}
}
}
I resolved this issue by tackling the problem another way. Essentially rather than passing a List to the Insert Table Method. I decided to Pass a Multi-Dimensional Array with all the data need for the table including the table headings. This essentially meant that the Insert Table method would be more generic and any customization i.e. Generating Data, Specifying Column Headings etc would be done in the Method calling Insert Table.
My goal here so to make the listing say "Free International Shipping". Trying to set up international options and it said I need to set ShipToLocation I tried the line below:
internationalShippingOptions.ShipToLocation.Add("Worldwide");
But when the program hits it I get this error:
"Object reference not set to an instance of an object"
If you would like to see the full method it is:
static ShippingDetailsType BuildShippingDetails()
{
ShippingDetailsType sd = new ShippingDetailsType();
sd.ApplyShippingDiscount = false;
sd.ShippingType = ShippingTypeCodeType.Flat;
AmountType amount = new AmountType();
amount.Value = 0;
amount.currencyID = CurrencyCodeType.USD;
ShippingServiceOptionsTypeCollection shippingOptions = new ShippingServiceOptionsTypeCollection();
ShippingServiceOptionsType domesticShippingOptions = new ShippingServiceOptionsType();
domesticShippingOptions.ShippingService = ShippingServiceCodeType.EconomyShippingFromOutsideUS.ToString();
domesticShippingOptions.FreeShipping = true;
domesticShippingOptions.ShippingServiceCost = amount;
domesticShippingOptions.ShippingServicePriority = 1;
shippingOptions.Add(domesticShippingOptions);
ShippingServiceOptionsType internationalShippingOptions = new ShippingServiceOptionsType();
InternationalShippingServiceOptionsType internationalShippingOptions = new InternationalShippingServiceOptionsType();
internationalShippingOptions.ShippingService = ShippingServiceCodeType.StandardInternational.ToString();
internationalShippingOptions.ShipToLocation.Add("Worldwide");
internationalShippingOptions.FreeShipping = true;
sd.InternationalShippingServiceOption = new InternationalShippingServiceOptionsTypeCollection(new InternationalShippingServiceOptionsType[] { internationalShippingOptions });
sd.ShippingServiceOptions = shippingOptions;
return sd;
}
Here is the code to make it say "Free Standard Intl Shipping". At first in the sandbox it says "Free Standard Shipping" but if you change the shipping destination in the sandbox it will say "Free Standard Intl Shipping".
static ShippingDetailsType BuildShippingDetails()
{
// Shipping details
ShippingDetailsType sd = new ShippingDetailsType();
sd.ApplyShippingDiscount = true;
sd.PaymentInstructions = "eBay .Net SDK test instruction.";
sd.ShippingRateType = ShippingRateTypeCodeType.StandardList;
// Shipping type and shipping service options
//adding international shipping
InternationalShippingServiceOptionsType internationalShipping1 = new InternationalShippingServiceOptionsType();
internationalShipping1.ShippingService = ShippingServiceCodeType.StandardInternational.ToString();
internationalShipping1.ShippingServiceCost = new AmountType { Value = 0, currencyID = CurrencyCodeType.USD };
internationalShipping1.ShippingServicePriority = 1;
internationalShipping1.ShipToLocation = new StringCollection(new[] { "Worldwide" });
sd.ShippingServiceUsed = ShippingServiceCodeType.StandardInternational.ToString();
sd.InternationalShippingServiceOption = new InternationalShippingServiceOptionsTypeCollection(new[] { internationalShipping1 });
//adding domestic shipping
ShippingServiceOptionsType domesticShipping1 = new ShippingServiceOptionsType();
domesticShipping1.ShippingService = ShippingServiceCodeType.ShippingMethodStandard.ToString();
domesticShipping1.ShippingServiceCost = new AmountType { Value = 0, currencyID = CurrencyCodeType.USD };
domesticShipping1.ShippingInsuranceCost = new AmountType { Value = 0, currencyID = CurrencyCodeType.USD };
domesticShipping1.ShippingServicePriority = 4;
domesticShipping1.LocalPickup = true;
domesticShipping1.FreeShipping = true;
sd.ShippingServiceOptions = new ShippingServiceOptionsTypeCollection(new[] { domesticShipping1 });
sd.ShippingType = ShippingTypeCodeType.Flat;
return sd;
To call the method:
item.ShippingDetails = BuildShippingDetails();
I am trying to search for message items between two dates from the inbox folder.
I use the following restrictionType but it throws this error:
firmt.RootFolder = null
What am I doing wrong?
There is some messages between the mentionned dates ;-)
Thanks for your suggestions.
using (ExchangeServiceBinding esb = new ExchangeServiceBinding())
{
esb.Url = ConfigurationManager.AppSettings["ExchangeWebServicesURL"].ToString();
esb.RequestServerVersionValue = new RequestServerVersion();
esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;
esb.PreAuthenticate = true;
esb.Credentials = new NetworkCredential(email, password);
FindItemType findItemRequest = new FindItemType();
// paging
IndexedPageViewType ipvt = new IndexedPageViewType();
ipvt.BasePoint = IndexBasePointType.Beginning;
ipvt.MaxEntriesReturned = nombreMessage;
ipvt.MaxEntriesReturnedSpecified = true;
ipvt.Offset = offset;
findItemRequest.Item = ipvt;
// filter by dates
AndType andType = new AndType();
List<SearchExpressionType> searchExps = new List<SearchExpressionType>();
RestrictionType restriction = new RestrictionType();
PathToUnindexedFieldType pteft = new PathToUnindexedFieldType
{
FieldURI = UnindexedFieldURIType.itemDateTimeSent
};
IsGreaterThanOrEqualToType IsGreaterThanOrEqualTo = new IsGreaterThanOrEqualToType
{
Item = pteft,
FieldURIOrConstant = new FieldURIOrConstantType
{
Item = new ConstantValueType
{
Value = DateTime.Today.AddDays(-6d).ToString()
}
}
};
searchExps.Add(IsGreaterThanOrEqualTo);
IsLessThanOrEqualToType IsLessThanOrEqualTo = new IsLessThanOrEqualToType
{
Item = pteft,
FieldURIOrConstant = new FieldURIOrConstantType
{
Item = new ConstantValueType
{
Value = DateTime.Today.AddDays(1d).ToString()
}
}
};
searchExps.Add(IsLessThanOrEqualTo);
andType.Items = searchExps.ToArray();
restriction.Item = andType;
findItemRequest.Restriction = restriction;
//// Define the sort order of items.
FieldOrderType[] fieldsOrder = new FieldOrderType[1];
fieldsOrder[0] = new FieldOrderType();
PathToUnindexedFieldType dateOrder = new PathToUnindexedFieldType
{
FieldURI = UnindexedFieldURIType.itemDateTimeReceived
};
fieldsOrder[0].Item = dateOrder;
fieldsOrder[0].Order = SortDirectionType.Descending;
findItemRequest.SortOrder = fieldsOrder;
findItemRequest.Traversal = ItemQueryTraversalType.Shallow;
// define which item properties are returned in the response
findItemRequest.ItemShape = new ItemResponseShapeType
{
BaseShape = DefaultShapeNamesType.IdOnly
};
// identify which folder to search
DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
folderIDArray[0] = new DistinguishedFolderIdType { Id = DistinguishedFolderIdNameType.inbox };
// add folders to request
findItemRequest.ParentFolderIds = folderIDArray;
// find the messages
FindItemResponseType findItemResponse = esb.FindItem(findItemRequest);
//-------------
ArrayOfResponseMessagesType responseMessages = findItemResponse.ResponseMessages;
ResponseMessageType responseMessage = responseMessages.Items[0];
if (responseMessage is FindItemResponseMessageType)
{
FindItemResponseMessageType firmt = (responseMessage as FindItemResponseMessageType);
*******FindItemParentType fipt = firmt.RootFolder;********
object obj = fipt.Item;
// FindItem contains an array of items.
ArrayOfRealItemsType realitems = (obj as ArrayOfRealItemsType);
ItemType[] items = realitems.Items;
// if no messages were found, then return null -- we're done
if (items == null || items.Count() <= 0)
return null;
// FindItem never gets "all" the properties, so now that we've found them all, we need to get them all.
BaseItemIdType[] itemIds = new BaseItemIdType[items.Count()];
for (int i = 0; i < items.Count(); i++)
itemIds[i] = items[i].ItemId;
GetItemType getItemType = new GetItemType
{
ItemIds = itemIds,
ItemShape = new ItemResponseShapeType
{
BaseShape = DefaultShapeNamesType.AllProperties,
BodyType = BodyTypeResponseType.Text,
BodyTypeSpecified = true,
AdditionalProperties = new BasePathToElementType[] {
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.itemDateTimeSent },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageFrom },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageIsRead },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageSender },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageToRecipients },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageCcRecipients },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageBccRecipients }
}
}
};
GetItemResponseType getItemResponse = esb.GetItem(getItemType);
messages = ReadItems(getItemResponse, items.Count());
}
I found the answer on my own after a long search about date format.
The restrictions has to be defined as this:
// greater or equal to
string dateStart = DateTime.Today.add(-6d);
string dateEnd = DateTime.Today.Add(1d);
PathToUnindexedFieldType dateSentPath = new PathToUnindexedFieldType();
dateSentPath.FieldURI = UnindexedFieldURIType.itemDateTimeSent;
IsGreaterThanOrEqualToType IsGreaterThanOrEqual = new IsGreaterThanOrEqualToType();
IsGreaterThanOrEqual.Item = dateSentPath;
FieldURIOrConstantType dateConstant = new FieldURIOrConstantType();
ConstantValueType dateConstantValue = new ConstantValueType();
dateConstantValue.Value = string.Format("{0}-{1}-{2}T00:00:00Z", dateStart.Year.ToString(), dateStart.Month.ToString(), dateStart.Day.ToString());
dateConstant.Item = dateConstantValue;
IsGreaterThanOrEqual.FieldURIOrConstant = dateConstant;
// less than or equal to
PathToUnindexedFieldType dateSentPath1 = new PathToUnindexedFieldType();
dateSentPath1.FieldURI = UnindexedFieldURIType.itemDateTimeSent;
IsLessThanOrEqualToType lessThanOrEqualTo = new IsLessThanOrEqualToType();
lessThanOrEqualTo.Item = dateSentPath1;
FieldURIOrConstantType dateConstant1 = new FieldURIOrConstantType();
ConstantValueType dateConstantValue1 = new ConstantValueType();
dateConstantValue1.Value = string.Format("{0}-{1}-{2}T00:00:00Z", dateEnd.Year.ToString(), dateEnd.Month.ToString(), dateEnd.Day.ToString());
dateConstant1.Item = dateConstantValue1;
lessThanOrEqualTo.FieldURIOrConstant = dateConstant1;
RestrictionType restriction = new RestrictionType();
AndType andType = new AndType();
andType.Items = new SearchExpressionType[] { lessThanOrEqualTo, IsGreaterThanOrEqual };
restriction.Item = andType;
findItemRequest.Restriction = restriction;
Hope this help someone some day ;-)
In case anyone stumbles upon this in the future, EWS has gotten even more strict about date formatting. The accepted answer formatting works for 2 digit months, but it does not for single digit months.
The formatting that works in all cases is:
DateTime.Today.AddDays(15).ToString("yyyy-MM-ddThh:mm:ssZ")
The restriction also works using the "Sortable date/time pattern".
Datetime.Now.ToString("s")