I don't know if this has been already reported, but I'm posting this, in case it hasn't been.
The Problem:
When I try to Register a new RMA ( Register new RMA in Ecom) on an Order, which has a Fixed OrderLine, the following error occurs:
Server Error in '/' Application.
The given key was not present in the dictionary.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. |
Stack Trace:
|
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.34212
Where:
The error happens here (This is a decompiled version of the method in Dynamicweb.Admin.dll - i have added comments):
// Dynamicweb.Admin.EcomRma_Edit
private void BuildOrderLineSelector()
{
System.Collections.Generic.Dictionary<string, int> dictionary = new System.Collections.Generic.Dictionary<string, int>();
if (this._rma.IsNew)
{
ListColumn listColumn = new ListColumn();
listColumn.Name = "";
listColumn.TranslateName = false;
listColumn.Width = 20;
this.OrderlineList.Columns.Add(listColumn);
dictionary = this._newOrderLineListColumns;
}
else
{
dictionary = this._orderLineListColumns;
}
foreach (string current in dictionary.Keys)
{
ListColumn listColumn2 = new ListColumn();
listColumn2.TranslateName = true;
listColumn2.Name = current;
if (dictionary[current] > 0)
{
listColumn2.Width = dictionary[current];
}
this.OrderlineList.Columns.Add(listColumn2);
}
ReturnMerchandiseAuthorizationCollection rmasByOrderId = ReturnMerchandiseAuthorization.GetRmasByOrderId(this._order.ID);
if (this._rma.IsNew)
{
System.Collections.Generic.List<ListRow> list = new System.Collections.Generic.List<ListRow>();
int num = 0;
// 1. This (availableOrderLines) should be a superset or equal to this._order.ProductOrderLines
System.Collections.Generic.Dictionary<string, int> availableOrderLines = ReturnMerchandiseAuthorization.GetAvailableOrderLines(this._order);
// 2. This._order.ProductOrderLines should be a subset or equal to availableOrderLines
foreach (OrderLine current2 in this._order.ProductOrderLines)
{
bool flag = availableOrderLines[current2.ID] > 0; // 3. And this is the reason why (The error happens here)
if (flag)
{
num++;
}
if (flag)
{
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
int num2 = availableOrderLines[current2.ID]; // 3. Same as above
for (int i = 1; i <= num2; i++)
{
stringBuilder.AppendFormat("<option id=\"{0}\" value=\"{0}\">{0}</option>", i);
}
ListRow listRow = new ListRow();
listRow.ItemID = current2.ID;
listRow.AddColumn(string.Format("<input type=\"checkbox\" name=\"RmaOrderLines_{2}\" id=\"RmaOrderLines_{2}\" value=\"{0}\" style=\"align: center;\"{1} onClick=\"showSerialNumberRows('RmaOrderLines_{2}',document.getElementById('SerialNumber_{0}').value)\" />", current2.ID, (flag ? "" : " disabled=\"disabled\""), current2.ID));
listRow.AddColumn(current2.ProductNumber);
listRow.AddColumn(current2.ProductName);
listRow.AddColumn(availableOrderLines[current2.ID]); // 3. Same as above
listRow.AddColumn(string.Format("<select name=\"SerialNumber_{0}\" id=\"SerialNumber_{0}\" class=\"NewUIinput\" style=\"width: 100px;\" onChange=\"showSerialNumberRows('RmaOrderLines_{0}',document.getElementById('SerialNumber_{0}').value)\"{2} >{1}</select>", current2.ID, stringBuilder.ToString(), (flag ? "" : " disabled=\"disabled\"")));
this.OrderlineList.AddRow(listRow);
int arg_24A_0 = 1;
int num3 = availableOrderLines[current2.ID]; // 3. Same as above
for (int j = arg_24A_0; j <= num3; j++)
{
ListRow listRow2 = new ListRow();
listRow2.AddColumn("");
listRow2.AddColumn("<img src=\"/Admin/Images/DoubleArrowRight.gif\" style=\"vertical-align: middle;\">" + Translate.Translate("Serial number", 0));
listRow2.AddColumn(string.Format("<input type=\"text\" name=\"SerialNumber_{0}-{1}\" id=\"SerialNumber_{0}-{1}\" class=\"NewUIinput SerialNumberInputBoxWidth\" />", current2.ID, j.ToString()));
listRow2.AddColumn("");
listRow2.AddColumn("");
listRow2.AddClass("ClassHidden");
listRow2.AddClass("RmaOrderLines_" + current2.ID + "_" + j.ToString());
listRow2.AddClass("RmaOrderLines_" + current2.ID);
this.OrderlineList.AddRow(listRow2);
}
}
int num4 = System.Math.Max(availableOrderLines[current2.ID], System.Convert.ToInt32(current2.Quantity)) - System.Math.Min(availableOrderLines[current2.ID], System.Convert.ToInt32(current2.Quantity)); // 3. Same as above
if (num4 > 0)
{
int num5 = num4 - 1;
for (int k = 0; k <= num5; k++)
{
ListRow listRow3 = new ListRow();
listRow3.Active = false;
listRow3.AddColumn(current2.ProductNumber);
listRow3.AddColumn(current2.ProductName);
try
{
listRow3.AddColumn(this.CreateRmaLink(ReturnMerchandiseAuthorization.GetRmasByOrderLineId(current2.ID)[k].Id.ToString()));
}
catch (System.Exception)
{
listRow3.AddColumn(Translate.Translate("Unable to find RMA Id", 0));
}
list.Add(listRow3);
}
}
}
if (list.Count > 0)
{
ListRow listRow4 = new ListRow();
listRow4.AddColumn("");
listRow4.AddColumn(Translate.Translate("Claimed products", 0));
listRow4.AddColumn("");
listRow4.AddColumn("");
listRow4.AddColumn("");
listRow4.Expandable = true;
this.OrderlineList.AddRow(listRow4);
if (this.Session[this._sessionKeyClaimedProduct] != null)
{
this.Session.Remove(this._sessionKeyClaimedProduct);
}
this.Session.Add(this._sessionKeyClaimedProduct, list);
}
if (num == 0)
{
this.RmaInfoBar.Message = "There are no available products on this order.";
this.RmaInfoBar.TranslateMessage = true;
this.RmaInfoBar.Type = Infobar.MessageType.Warning;
this.RmaInfoBar.Visible = true;
this.DisableUI();
}
}
else
{
foreach (ReturnMerchandiseAuthorizationOrderLine current3 in this._rma.OrderLines)
{
ListRow listRow5 = new ListRow();
listRow5.AddColumn(current3.OrderLine.ProductNumber);
listRow5.AddColumn(current3.OrderLine.ProductName);
listRow5.AddColumn(current3.SerialNumber);
this.OrderlineList.AddRow(listRow5);
}
}
}
Why:
The reason is that the availableOrderLines dictionary does not necessarily contain all entries in this._order.ProductOrderLines. This happens when there is a Fixed OrderLine in the Order, and then during iteration, when a Fixed OrderLine is encountered, the key is not present in the availableOrderLines dictionary, which generates the error above.
Here are two decompiled source code excerpts from Dynamicweb.dll, showing that the ProductOrderLines property of an Order includes Fixed OrderLine instances, while the GetAvailableOrderLines method does not include them.
1.
// Dynamicweb.eCommerce.Orders.Order
public OrderLineCollection ProductOrderLines
{
get
{
OrderLineCollection orderLineCollection = new OrderLineCollection();
foreach (OrderLine current in this.OrderLines)
{
if (current.HasType(new OrderLine.OrderLineType[]
{
OrderLine.OrderLineType.Product,
OrderLine.OrderLineType.Fixed,
OrderLine.OrderLineType.PointProduct
}))
{
if (current != null && current.Product != null)
{
orderLineCollection.Add(current);
}
}
}
return orderLineCollection;
}
}
2.
// Dynamicweb.eCommerce.Orders.ReturnMerchandiseAuthorization.ReturnMerchandiseAuthorization
internal static System.Collections.Generic.Dictionary<string, int> GetAvailableOrderLines(Order order)
{
System.Collections.Generic.Dictionary<string, int> dictionary = new System.Collections.Generic.Dictionary<string, int>();
foreach (OrderLine current in order.OrderLines)
{
if (current.HasType(new OrderLine.OrderLineType[]
{
OrderLine.OrderLineType.Product,
OrderLine.OrderLineType.PointProduct // MISSING OrderLine.OrderLineType.Fixed
}))
{
dictionary.Add(current.ID, (int)System.Math.Round(current.Quantity));
}
}
ReturnMerchandiseAuthorizationCollection allNotDeletedRmas = ReturnMerchandiseAuthorization.GetAllNotDeletedRmas();
foreach (ReturnMerchandiseAuthorization current2 in allNotDeletedRmas)
{
if (current2.OrderLines.Count > 0 && current2.OrderLines.First<ReturnMerchandiseAuthorizationOrderLine>().OrderLine.OrderID == order.ID)
{
foreach (ReturnMerchandiseAuthorizationOrderLine current3 in current2.OrderLines)
{
if (current3.OrderLine.HasType(new OrderLine.OrderLineType[]
{
OrderLine.OrderLineType.Product,
OrderLine.OrderLineType.PointProduct // MISSING OrderLine.OrderLineType.Fixed
}))
{
dictionary[current3.OrderLine.ID] = dictionary[current3.OrderLine.ID] - 1;
}
}
}
}
return dictionary;
}
The solution's Dynamicweb version is 8.5.1.19.
Please let me know if you need more information.