EF4 update navigation property An entity object cannot be referenced by multiple instances of IEntityChangeTracker - entity-framework-4

I am trying to implement a let's say "change my account email address" fonctionality.
I want to keep backup of all user emails in (R_EmailAddressHistory table).
Here are some of my project's code.
public bool ChangeEmailAddress(string username, string newEmailAddress, string callbackUrl)
{
DateTime currentUtcTime = DateTime.UtcNow;
R_User currentUser = UserRepo.GetSingle(whereCondition: w=>w.Username == username);
currentUser.UpdateDate = currentUtcTime;
if (currentUser.HasPendingNewEmail)
{
R_EmailAddressHistory currentPendingRequest = EmailHistoRepo.GetSingle(whereCondition: w => w.StatusID == (int)Reno.Common.Enums.RecordStatus.Pending && w.R_User.GId == currentUser.GId);
currentPendingRequest.NewEmail = newEmailAddress;
currentPendingRequest.UpdateDate = currentUtcTime;
EmailHistoRepo.Update(currentPendingRequest);
}
else
{
currentUser.HasPendingNewEmail = true;
R_EmailAddressHistory newEmail = new R_EmailAddressHistory();
newEmail.UserId = currentUser.GId;
newEmail.R_User = currentUser;
newEmail.NewEmail = newEmailAddress;
newEmail.InsertDate = currentUtcTime;
newEmail.StatusID = (int) Reno.Common.Enums.RecordStatus.Pending;
currentUser.R_EmailAddressHistory.Add(newEmail);
}
IdentityResult idtResult = UserRepo.Update(currentUser);
if(idtResult == IdentityResult.Succeeded)
{
//Send notification to current email address for validation before proceeding change email process
bool sendResult = Communication.EmailService.SendChangeEmailValidation(username,currentUser.Email, newEmailAddress, callbackUrl);
return sendResult;
}
else
{
return false;
}
}
The previous method is use to change an email address. Each of my tables (R_User and EmailAddressHistory ) has Repository (UserRepo and EmailHistoRepo). The implement the same IRepositoryBase class, here is the Update methode
public IdentityResult Update(T entity)
{
try
{
if (_currentContext.DbContext.Entry(entity).State == EntityState.Detached)
{
_currentContext.DbContext.Set<T>().Attach(entity);
}
_currentContext.DbContext.Entry(entity).State = EntityState.Modified;
return IdentityResult.Succeeded;
}
catch
{
return IdentityResult.Failed;
}
}
When a user has already a non validate new email address, when he request to change his current email address, I show him the pending new email address and he can change it, in this case I whant to update my historical table instead of creating a new one, cause only one pending new email address is allow. In such a case, my code failed in the line EmailHistoRepo.Update(currentPendingRequest) throwing the error : An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
Can anyone help me?
Thanks
EDIT
I am using MVC(4) with a unitOfWork. My UOW is initialized in a the Controller the first time the DB is queried and the Commit is done in the global.asax file in Appalication_EndRequest (see below).
protected void Application_EndRequest(Object sender, EventArgs e)
{
CommitChanges();
}
private void CommitChanges()
{
Reno.BLL.Services.Singleton.UnitOfWork unitOfWork = Reno.BLL.Services.Singleton.UnitOfWork.GetCurrentInstance(false);
if (unitOfWork != null)
{
unitOfWork.Commit();
unitOfWork.Dispose();
}
}

Your currentUser is modified before updating the emailaddress. Save the changes to currentUser first.
Something like this:
R_User currentUser = UserRepo.GetSingle(whereCondition: w=>w.Username == username);
currentUser.UpdateDate = currentUtcTime;
bool pendingNewEmail = currentUser.HasPendingNewEmail;
UserRepo.Update(currentUser);
if (pendingNewEmail)
{
R_EmailAddressHistory currentPendingRequest = EmailHistoRepo.GetSingle(whereCondition: w => w.StatusID == (int)Reno.Common.Enums.RecordStatus.Pending && w.R_User.GId == currentUser.GId);
currentPendingRequest.NewEmail = newEmailAddress;
currentPendingRequest.UpdateDate = currentUtcTime;
EmailHistoRepo.Update(currentPendingRequest);
}
else

I finally found the answer. The problem was that when I first get the user in line
R_User currentUser = UserRepo.GetSingle(whereCondition: w=>w.Username == username);
The currentUser variable hold a refrence of all of its R_EmailAddressHistory.
And then after, I queried the DB (2nd time) to get the pending email change request (or type R_EmailAddressHistory) to modify its new email and its update date, in line
R_EmailAddressHistory currentPendingRequest = EmailHistoRepo.GetSingle(whereCondition: w => w.StatusID == (int)Reno.Common.Enums.RecordStatus.Pending && w.R_User.GId == currentUser.GId);
currentPendingRequest.NewEmail = newEmailAddress;
currentPendingRequest.UpdateDate = currentUtcTime;
But te last code updates only currentPendingRequest while another reference of the same object which is in currentUser.R_EmailAddressHistory is not update and was already tracked by the context. Therefore, by doing an update on the new instance (EmailHistoRepo.Update(currentPendingRequest)), the code failed: the same object if referenced in 2 places.
So, the solution was (the only thing I modified):
R_User currentUser = UserRepo.GetSingle(whereCondition: w=>w.Username == username);
currentUser.UpdateDate = currentUtcTime;
if (currentUser.HasPendingNewEmail)
{
R_EmailAddressHistory currentPendingRequest = currentUser.R_EmailAddressHistory.Where(h => h.StatusID == (int)Reno.Common.Enums.RecordStatus.Pending).First(); // EmailHistoRepo.GetSingle(whereCondition: w => w.StatusID == (int)Reno.Common.Enums.RecordStatus.Pending && w.R_User.GId == currentUser.GId);
currentPendingRequest.NewEmail = newEmailAddress;
currentPendingRequest.UpdateDate = currentUtcTime;
}
I decided to modify the instance in currentUser variable.

Related

To close db and cannot create commands from unopened database error

string dppath = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "user.db3");
db = new SQLiteConnection(dppath);
string DELETEPASSCODE_DETAIL = "DELETE FROM Table1;";
db.Execute(DELETEPASSCODE_DETAIL);
db.Close();
Hello. When the program executes the above code and reaches the below code, I get this error: cannot create commands from unopened database
try
{
string dpPath = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "user.db3");`
if (dpPath.IndexOf("user.db3") < 0)
{
CreateDB();
CreateTable();
}
else
{
if (db == null)
{
db = new SQLiteConnection(dpPath);
}
var tableExist = db.GetTableInfo("Table1");
……
The error occurs on this db.GetTableInfo("Table1");
I made some mistakes for the first check of the code. Now, I reproduced this issue.
The db can not be null, delete the If statement.
Change:
if (db == null)
{
db = new SQLiteConnection(_databasePath);
}
var tableExist = db.GetTableInfo("Info");
var table_Info = db.Table<Info>().ToList();
To:
db = new SQLiteConnection(_databasePath);
var tableExist = db.GetTableInfo("Info");
var table_Info = db.Table<Info>().ToList();
db.Table<Info>().ToList() could also be used to get the table information.

Entity Framework not able to update Tables

I'm new to EF, using 6.0 code-first.
using (EmpolyeeContext emp = new EmpolyeeContext())
{
var callrecordSession = new CallRecordingSession();
string ucid = new Random().Next(0, 5000).ToString();
callrecordSession.UCID = ucid;
callrecordSession.InstrumentationTransactionId = new Random().Next(0, 9000).ToString();
callrecordSession.ClientName = "IVR";
callrecordSession.ClientRequestObject = "{string.empty}";
callrecordSession.CallRecordingStatusName = "Started";
callrecordSession.ModifiedDatetime = DateTime.Now;
emp.CallRecordingSessions.Add(callrecordSession);
var itemToEdit = emp.CallRecordingSessions.Where(c => c.UCID == ucid).FirstOrDefault<CallRecordingSession>();
if (itemToEdit != null)
{
itemToEdit.CallRecordingStatusName = "Inprogress";
itemToEdit.ModifiedDatetime = DateTime.Now;
}
emp.SaveChanges();
}
What is wrong with this code? I'm always getting itemtoEdit as null
Entity Framework always queries the data source. This is by design. If they queried your local cache instead, You could get an Id that has already been inserted by a different user in the database. Also Entity framework has to merge results from your memory and the database.
var itemToEdit = emp.CallRecordingSessions.Where(c => c.UCID == ucid).FirstOrDefault<CallRecordingSession>();
So all you got to do is call the savechanges before you get the data back.
emp.CallRecordingSessions.Add(callrecordSession);
emp.SaveChanges();
var itemToEdit = emp.CallRecordingSessions.Where(c => c.UCID == ucid).FirstOrDefault<CallRecordingSession>();
if (itemToEdit != null)
{
itemToEdit.CallRecordingStatusName = "Inprogress";
itemToEdit.ModifiedDatetime = DateTime.Now;
}
emp.SaveChanges();
.SaveChanges() did the tricks.

FromOutcome for `Switch Node` directing flow to `Method Call Node` don't wont to work

I have difined my flow as:
builder.id("", PublisherBean.PUBLISHER_FLOW_NAME);
builder.viewNode("list", "/pages/publishers.xhtml");
builder.viewNode("details", "/pages/publishers-details.xhtml");
builder.viewNode("deleted", "/pages/publishers-deleted.xhtml");
builder.viewNode("form", "/pages/publishers-form.xhtml");
builder.viewNode("exit", "/index.xhtml");
builder.methodCallNode("invoke-update")
.expression("#{publisherBean.update()}")
.defaultOutcome("details");
builder.methodCallNode("switch-fail")
.defaultOutcome("invoke-publishers")
.expression("#{publisherBean.switchFail()}");
builder.switchNode("proceed-action-request")
.defaultOutcome("switch-fail")
.switchCase()
.condition("#{publisherBean.actionType.ifEdit()}").fromOutcome("form");
builder.switchNode("go-for-it")
.defaultOutcome("switch-fail")
.switchCase()
.switchCase()
.condition("#{publisherBean.actionType.ifEdit()}").fromOutcome("invoke-update");
as you can see, there is two switch nodes. First directs to a View Node, second one is trying to direct to a Method Call Node.
First one works fine, however second is giving me a headache. Second one is giving me an error
Unable to find matching navigation case with from-view-id '/pages/publishers-form.xhtml' for action '#{publisherBean.proceed()}' with outcome 'proceed-form'.
proceed function is just
public String proceed() {
LOG.log(Level.OFF, "Form proceed in action type {0}", actionType);
return "go-for-it";
}
Logged info confirms, that publisherBean.actionType.ifEdit() returns true, however that fact is ignored. If i change outcome from invoke-update to form or any other View Node id, then it "works fine".
Is it i'm doing something wrong, or Method Call Node cant be used as an outcome to a Switch Node?
I run into this issue too. In my case the problem is in calling Method Call Node after another Method Call Node.
I invesigated it a bit and found a problem in: com.sun.faces.application.NavigationHandlerImpl.synthesizeCaseStruct method. This method is used to determine where to go from methodCallNode or switchCallNode and it only looks at viewNodes and returnNodes.
private CaseStruct synthesizeCaseStruct(FacesContext context, Flow flow, String fromAction, String outcome) {
CaseStruct result = null;
FlowNode node = flow.getNode(outcome);
if (null != node) {
if (node instanceof ViewNode) {
result = new CaseStruct();
result.viewId = ((ViewNode)node).getVdlDocumentId();
result.navCase = new MutableNavigationCase(fromAction,
fromAction, outcome, null, result.viewId,
flow.getDefiningDocumentId(), null, false, false);
} else if (node instanceof ReturnNode) {
String fromOutcome = ((ReturnNode)node).getFromOutcome(context);
FlowHandler flowHandler = context.getApplication().getFlowHandler();
try {
flowHandler.pushReturnMode(context);
result = getViewId(context, fromAction, fromOutcome, FlowHandler.NULL_FLOW);
// We are in a return node, but no result can be found from that
// node. Show the last displayed viewId from the preceding flow.
if (null == result) {
Flow precedingFlow = flowHandler.getCurrentFlow(context);
if (null != precedingFlow) {
String toViewId = flowHandler.getLastDisplayedViewId(context);
if (null != toViewId) {
result = new CaseStruct();
result.viewId = toViewId;
result.navCase = new MutableNavigationCase(context.getViewRoot().getViewId(),
fromAction,
outcome,
null,
toViewId,
FlowHandler.NULL_FLOW,
null,
false,
false);
}
}
} else {
result.newFlow = FlowImpl.SYNTHESIZED_RETURN_CASE_FLOW;
}
}
finally {
flowHandler.popReturnMode(context);
}
}
} else {
// See if there is an implicit match within this flow, using outcome
// to derive a view id within this flow.
String currentViewId = outcome;
// If the viewIdToTest needs an extension, take one from the currentViewId.
String currentExtension;
int idx = currentViewId.lastIndexOf('.');
if (idx != -1) {
currentExtension = currentViewId.substring(idx);
} else {
// PENDING, don't hard code XHTML here, look it up from configuration
currentExtension = ".xhtml";
}
String viewIdToTest = "/" + flow.getId() + "/" + outcome + currentExtension;
ViewHandler viewHandler = Util.getViewHandler(context);
viewIdToTest = viewHandler.deriveViewId(context, viewIdToTest);
if (null != viewIdToTest) {
result = new CaseStruct();
result.viewId = viewIdToTest;
result.navCase = new MutableNavigationCase(fromAction,
fromAction, outcome, null, result.viewId,
null, false, false);
}
}
return result;
}

Add Sales Tax Item using QBFC

Is there any way to add Sales Tax Item using QBFC?
Example:
Sales Tax A
4%
Sales Tax B
10%
I can add it easily from Quickbooks, but I need a way to add from external application using QBFC.
Any help will be greatly appreciated.
You can find a good example in the On Screen Reference.
At the top of the screen choose ItemSalesTaxAdd from the "Select Message" dropdown. From there click on the C# tab and you will see the following sample code:
//The following sample code is generated as an illustration of
//Creating requests and parsing responses ONLY
//This code is NOT intended to show best practices or ideal code
//Use at your most careful discretion
using System;
using System.Net;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using Interop.QBFC10;
namespace com.intuit.idn.samples
{
public class Sample
{
public void DoItemSalesTaxAdd()
{
bool sessionBegun = false;
bool connectionOpen = false;
QBSessionManager sessionManager = null;
try
{
//Create the session Manager object
sessionManager = new QBSessionManager();
//Create the message set request object to hold our request
IMsgSetRequest requestMsgSet = sessionManager.CreateMsgSetRequest("US",1,.0);
requestMsgSet.Attributes.OnError = ENRqOnError.roeContinue;
BuildItemSalesTaxAddRq(requestMsgSet);
//Connect to QuickBooks and begin a session
sessionManager.OpenConnection("","Sample Code from OSR");
connectionOpen = true;
sessionManager.BeginSession("", ENOpenMode.omDontCare);
sessionBegun = true;
//Send the request and get the response from QuickBooks
IMsgSetResponse responseMsgSet = sessionManager.DoRequests(requestMsgSet);
//End the session and close the connection to QuickBooks
sessionManager.EndSession();
sessionBegun = false;
sessionManager.CloseConnection();
connectionOpen = false;
WalkItemSalesTaxAddRs(responseMsgSet);
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Error");
if (sessionBegun)
{
sessionManager.EndSession();
}
if (connectionOpen)
{
sessionManager.CloseConnection();
}
}
}
void BuildItemSalesTaxAddRq(IMsgSetRequest requestMsgSet)
{
IItemSalesTaxAdd ItemSalesTaxAddRq= requestMsgSet.AppendItemSalesTaxAddRq();
//Set field value for Name
ItemSalesTaxAddRq.Name.SetValue("ab");
//Set field value for BarCodeValue
ItemSalesTaxAddRq.BarCode.BarCodeValue.SetValue("ab");
//Set field value for AssignEvenIfUsed
ItemSalesTaxAddRq.BarCode.AssignEvenIfUsed.SetValue(true);
//Set field value for AllowOverride
ItemSalesTaxAddRq.BarCode.AllowOverride.SetValue(true);
//Set field value for IsActive
ItemSalesTaxAddRq.IsActive.SetValue(true);
//Set field value for ListID
ItemSalesTaxAddRq.ClassRef.ListID.SetValue("200000-1011023419");
//Set field value for FullName
ItemSalesTaxAddRq.ClassRef.FullName.SetValue("ab");
//Set field value for ItemDesc
ItemSalesTaxAddRq.ItemDesc.SetValue("ab");
//Set field value for TaxRate
ItemSalesTaxAddRq.TaxRate.SetValue(20.00);
//Set field value for ListID
ItemSalesTaxAddRq.TaxVendorRef.ListID.SetValue("200000-1011023419");
//Set field value for FullName
ItemSalesTaxAddRq.TaxVendorRef.FullName.SetValue("ab");
//Set field value for ExternalGUID
ItemSalesTaxAddRq.ExternalGUID.SetValue(Guid.NewGuid().ToString());
//Set field value for IncludeRetElementList
//May create more than one of these if needed
ItemSalesTaxAddRq.IncludeRetElementList.Add("ab");
}
void WalkItemSalesTaxAddRs(IMsgSetResponse responseMsgSet)
{
if (responseMsgSet == null) return;
IResponseList responseList = responseMsgSet.ResponseList;
if (responseList == null) return;
//if we sent only one request, there is only one response, we'll walk the list for this sample
for (int i=0; i<responseList.Count; i++)
{
IResponse response = responseList.GetAt(i);
//check the status code of the response, 0=ok, >0 is warning
if (response.StatusCode >= 0)
{
//the request-specific response is in the details, make sure we have some
if (response.Detail != null)
{
//make sure the response is the type we're expecting
ENResponseType responseType = (ENResponseType)response.Type.GetValue();
if (responseType == ENResponseType.rtItemSalesTaxAddRs)
{
//upcast to more specific type here, this is safe because we checked with response.Type check above
IItemSalesTaxRet ItemSalesTaxRet = (IItemSalesTaxRet)response.Detail;
WalkItemSalesTaxRet(ItemSalesTaxRet);
}
}
}
}
}
void WalkItemSalesTaxRet(IItemSalesTaxRet ItemSalesTaxRet)
{
if (ItemSalesTaxRet == null) return;
//Go through all the elements of IItemSalesTaxRet
//Get value of ListID
string ListID1 = (string)ItemSalesTaxRet.ListID.GetValue();
//Get value of TimeCreated
DateTime TimeCreated2 = (DateTime)ItemSalesTaxRet.TimeCreated.GetValue();
//Get value of TimeModified
DateTime TimeModified3 = (DateTime)ItemSalesTaxRet.TimeModified.GetValue();
//Get value of EditSequence
string EditSequence4 = (string)ItemSalesTaxRet.EditSequence.GetValue();
//Get value of Name
string Name5 = (string)ItemSalesTaxRet.Name.GetValue();
//Get value of BarCodeValue
if (ItemSalesTaxRet.BarCodeValue != null)
{
string BarCodeValue6 = (string)ItemSalesTaxRet.BarCodeValue.GetValue();
}
//Get value of IsActive
if (ItemSalesTaxRet.IsActive != null)
{
bool IsActive7 = (bool)ItemSalesTaxRet.IsActive.GetValue();
}
if (ItemSalesTaxRet.ClassRef != null)
{
//Get value of ListID
if (ItemSalesTaxRet.ClassRef.ListID != null)
{
string ListID8 = (string)ItemSalesTaxRet.ClassRef.ListID.GetValue();
}
//Get value of FullName
if (ItemSalesTaxRet.ClassRef.FullName != null)
{
string FullName9 = (string)ItemSalesTaxRet.ClassRef.FullName.GetValue();
}
}
//Get value of ItemDesc
if (ItemSalesTaxRet.ItemDesc != null)
{
string ItemDesc10 = (string)ItemSalesTaxRet.ItemDesc.GetValue();
}
//Get value of TaxRate
if (ItemSalesTaxRet.TaxRate != null)
{
double TaxRate11 = (double)ItemSalesTaxRet.TaxRate.GetValue();
}
if (ItemSalesTaxRet.TaxVendorRef != null)
{
//Get value of ListID
if (ItemSalesTaxRet.TaxVendorRef.ListID != null)
{
string ListID12 = (string)ItemSalesTaxRet.TaxVendorRef.ListID.GetValue();
}
//Get value of FullName
if (ItemSalesTaxRet.TaxVendorRef.FullName != null)
{
string FullName13 = (string)ItemSalesTaxRet.TaxVendorRef.FullName.GetValue();
}
}
//Get value of ExternalGUID
if (ItemSalesTaxRet.ExternalGUID != null)
{
string ExternalGUID14 = (string)ItemSalesTaxRet.ExternalGUID.GetValue();
}
if (ItemSalesTaxRet.DataExtRetList != null)
{
for (int i15 = 0; i15 < ItemSalesTaxRet.DataExtRetList.Count; i15++)
{
IDataExtRet DataExtRet = ItemSalesTaxRet.DataExtRetList.GetAt(i15);
//Get value of OwnerID
if (DataExtRet.OwnerID != null)
{
string OwnerID16 = (string)DataExtRet.OwnerID.GetValue();
}
//Get value of DataExtName
string DataExtName17 = (string)DataExtRet.DataExtName.GetValue();
//Get value of DataExtType
ENDataExtType DataExtType18 = (ENDataExtType)DataExtRet.DataExtType.GetValue();
//Get value of DataExtValue
string DataExtValue19 = (string)DataExtRet.DataExtValue.GetValue();
}
}
}
}
}
You can add each tax item as a line item. Make sure you set the invoice to a 0 tax, so tax is not calculated on top of tax.
You would have line item sales tax A and another line item sales tax B.

entered values are being cleared in gsp

I am entering values(URLs) in the text box and when I click the next button, validation runs whether the entered url values are valid or not.
if the urls are not valid then i display the error as below
if(valid == false){
this.errors.reject("Incorrect URL is entered for "+countries.get(countryCode)+" - please ensure to use a correct URL for More Games.")
return [];
}
Once the error is shown, its clearing the entered values and need to enter the values again. How can I restrict clearing the values(i think the page is getting loaded again) or to restrict the page to load again.
here is the command -
class DeliveryMoreGamesURLCommand implements Command {
private static final LOG = LogFactory.getLog(DeliveryController.class)
def wrapperService = ApplicationHolder.application.getMainContext().getBean("wrapperService");
def customerService = ApplicationHolder.application.getMainContext().getBean("customerService");
def countryService = ApplicationHolder.application.getMainContext().getBean("countryService");
def helperService = ApplicationHolder.application.getMainContext().getBean("helperService");
def ascService = ApplicationHolder.application.getMainContext().getBean("ascService");
Hashtable<String, String> countries;
public LinkedHashMap<String, Object> preProcess(sessionObject, params, request) {
Delivery delivery = (Delivery) sessionObject;
def customer = Customer.get(delivery.customerId);
def contentProvider = ContentProvider.get(delivery.contentProviderId);
def deployment = Deployment.get(delivery.deploymentId);
def operatingSystem = OperatingSystem.get(delivery.operatingSystemId);
countries = wrapperService.getCountries(deployment, operatingSystem);
def sortedCountries = countries.sort { a, b -> a.value <=> b.value };
def urls = ascService.getMoreGamesUrlsPerTemplates(deployment, operatingSystem);
def moreGamesUrls = new Hashtable<String,String>();
countries.each { country ->
String countryCode = countryService.getTwoLetterCountryAbbreviation(country.key);
String url = customerService.getMoreGamesUrl(customer, contentProvider, countryCode);
if ("".equals(url)) {
url = urls.get(country.key);
if (url == null) {
url = "";
}
}
moreGamesUrls.put(country.key, url); // We need to use the existing country code if the channels are deployed with three letter country codes
}
return [command: this, countries: sortedCountries, moreGamesUrls: moreGamesUrls]
}
public LinkedHashMap<String, Object> postProcess(sessionObject, params, request) {
Delivery delivery = (Delivery) sessionObject;
def urls = params.gamesUrls;
LOG.debug("urls from gsp :"+urls)
try{
urls.eachWithIndex { u, i ->
String countryCode = u.key;
String url = urls["${u.key}"]
if(url != ""){
Boolean valid = helperService.isURLValid(url)
if(valid == false){
this.errors.reject("Incorrect URL is entered for "+countries.get(countryCode)+" - please ensure to use a correct URL for More Games.")
return [];
}
}
}
}catch (Exception ex) {
logger.warn("Incorrect URL is entered", ex)
return [];
}
def moreGamesUrls = new Hashtable<String, String>();
urls.eachWithIndex { u, i ->
String countryCode = u.key;
String url = urls["${u.key}"]
moreGamesUrls.put(countryCode, url);
}
delivery.countries = countries;
delivery.moreGamesUrls = moreGamesUrls;
LOG.debug("moreGamesUrls after edit=${delivery.moreGamesUrls}");
return null;
}
}
from the command preprocess the data will be rendered and after clicking the next button, the postprocess will be invoked and the validation for the url...
Resolved this issue by implementing moreGamesUrls as a global variable(which stored the values even after the error is thrown)

Resources