I have records in a SQL Server database table that need to be transmitted to a payment processing API. Only table records where Transmitted = 0 are to be sent to the API. I found this question which helps me to understand the error at hand.
I want to read the records from my database table into a C# class, parse into JSON, and send via API call. I've tried using Entity Framework Core but receive Null Reference exception when I called the stored procedure and add the results to my model class as follows:
public async Task<IEnumerator<Onboarding>> GetOnboardingList()
{
try
{
using (var context = new SOBOContext())
{
var ob = await context.Onboarding
//.Where(o => o.Transmitted == false)
.FromSql("Execute GetUnsentOnboardingRecords_sp")
.ToListAsync();
Console.WriteLine(ob.ToArray());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return new OnboardingList().GetEnumerator();
}
When attempting to use Entity Framework Core, I created the OnboardingList class as below:
public class OnboardingList : IEnumerable<Onboarding>
{
private readonly List<Onboarding> _onboarding;
public IEnumerator<Onboarding> GetEnumerator()
{
return _onboarding?.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _onboarding.GetEnumerator();
}
}
I then reverted to SqlDataReader that calls the stored procedure. The method, in part, is as follows:
var listOnboardingModel = new List<Onboarding>();
try
{
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
SqlCommand cmd = new SqlCommand("GetUnsentOnboardingRecords_sp", connection)
{
CommandType = CommandType.StoredProcedure
};
connection.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
listOnboardingModel.Add(new Onboarding
{
OnboardingId = reader[1] as int? ?? 0,
UserId = reader[2] as int?,
UserName = reader[3].ToString(),
FirstName = reader[4].ToString(),
MiddleInitial = reader[5].ToString(),
Lastname = reader[6].ToString(),
DateOfBirth = reader[7].ToString(),
Ssn = reader[8].ToString(),
Email = reader[9].ToString(),
Address1Line1 = reader[10].ToString(),
Address1Line2 = reader[11].ToString(),
Address1ApartmentNumber = reader[12].ToString(),
Address1City = reader[13].ToString(),
Address1State = reader[14].ToString(),
Address1ZipCode = reader[15].ToString(),
Address1Country = reader[16].ToString(),
DayPhone = reader[17].ToString(),
EveningPhone = reader[18].ToString(),
PhonePin = reader[19].ToString(),
MerchantSourceIp = reader[20].ToString(),
ThreatMetrixPolicy = reader[21].ToString(),
SessionId = reader[22].ToString(),
BankAccount1CountryCode = reader[23].ToString(),
BankAccount1Name = reader[24].ToString(),
BankAccount1Description = reader[25].ToString(),
BankAccount1Number = reader[26].ToString(),
BankAccount1OwnershipType = reader[27].ToString(),
BankAccount1Type = reader[28].ToString(),
BankAccount1BankName = reader[29].ToString(),
BankAccount1RoutingNumber = reader[30].ToString(),
BankAccount2CountryCode = reader[31].ToString(),
BankAccount2Name = reader[32].ToString(),
BankAccount2Number = reader[33].ToString(),
BankAccount2OwnershipType = reader[34].ToString(),
BankAccount2Type = reader[35].ToString(),
BankAccount2BankName = reader[36].ToString(),
BankAccount2Description = reader[37].ToString(),
BankAccount2RoutingNumber = reader[38].ToString(),
AuthSginerFirstName = reader[39].ToString(),
AuthSignerLastName = reader[40].ToString(),
AuthSignerTitle = reader[41].ToString(),
AverageTicket = reader[42] as int? ?? 0,
BusinessLegalName = reader[43].ToString(),
BusinessApartmentNumber = reader[44].ToString(),
BusinessAddressLine1 = reader[45].ToString(),
BusinessAddressLine2 = reader[46].ToString(),
BusinessCity = reader[47].ToString(),
BusinessState = reader[48].ToString(),
BusinessZipCode = reader[49].ToString(),
BusinessCountry = reader[50].ToString(),
BusinessDescription = reader[51].ToString(),
DoingBusinessAs = reader[52].ToString(),
Ein = reader[53].ToString(),
HighestTicket = reader[54] as int? ?? 0,
MerchantCategoryCode = reader[55].ToString(),
MonthlyBankCardVolume = reader[56] as int? ?? 0,
OwnerFirstName = reader[57].ToString(),
OwnerLastName = reader[58].ToString(),
OwnerSsn = reader[59].ToString(),
OwnerDob = reader[60].ToString(),
OwnerApartmentNumber = reader[61].ToString(),
OwnerAddress = reader[62].ToString(),
OwnerAddress2 = reader[63].ToString(),
OwnerCity = reader[64].ToString(),
OwnerRegion = reader[65].ToString(),
OwnerZipCode = reader[66].ToString(),
OwnerCountry = reader[67].ToString(),
OwnerTitle = reader[68].ToString(),
OwnerPercentage = reader[69].ToString(),
BusinessUrl = reader[70].ToString(),
CreditCardNumber = reader[71].ToString(),
ExpirationDate = reader[72].ToString(),
NameOnCard = reader[73].ToString(),
PaymentMethodId = reader[74].ToString(),
PaymentBankAccountNumber = reader[75].ToString(),
PaymentBankRoutingNumber = reader[76].ToString(),
PaymentBankAccountType = reader[77].ToString(),
Transmitted = reader[78] as bool?,
TransmitDate = reader[79].ToString(),
InternationalId = reader[80].ToString(),
DriversLicenseVersion = reader[81].ToString(),
DocumentType = reader[82].ToString(),
DocumentExpDate = reader[83].ToString(),
DocumentIssuingState = reader[84].ToString(),
MedicareReferenceNumber = reader[85].ToString(),
MedicareCardColor = reader[86].ToString(),
PaymentBankAccountName = reader[87].ToString(),
PaymentBankAccountDescription = reader[88].ToString(),
PaymentBankCountryCode = reader[89].ToString(),
PaymentBankName = reader[90].ToString(),
PaymentBankOwnershipType = reader[91].ToString()
});
}
}
connection.Close();
}
Console.WriteLine(listOnboardingModel);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return listOnboardingModel;
When I run the console application, I receive the Error Exception thrown: 'System.IndexOutOfRangeException' in System.Data.SqlClient.dll
Index was outside the bounds of the array.
How do I prevent the above out of range exception and also ensure that all qualifying records from my database table are included for transmission?
You appear to have two distinct issues:
You .ToString() a null value, which causes null reference exception.
An ordinal is likely out of bounds, a column does not match the numeric value provided causing it to be out of bounds.
Check for DBNull.Value otherwise bullet point one will occur.
My assumption would be that you start with one, while index's are zero based. So the first column would start at zero not one.
You should lookup Dapper or some built in utilities for SqlDataReader to leverage cleaner code calls to build your object. Dapper would condense the code by simply doing:
IEnumerable<Sample> GetSamples() => dbConnection.Query<Sample>(...);
As long as the column name matches the property name, it'll populate. Based on the entity provided it looks pretty simple, but checkout the documentation.
Also you should wrap command in using statement like, that way you do not have someone accidentally call a command.Dispose() in the middle of your connection block on accident:
using(var connection = new SqlConnection(...))
using(var command = new SqlCommand(..., ...))
{
connection.Open();
...
using(var reader = command.ExecuteReader())
while(reader.Read())
{
}
}
Related
I'm using Entity Framework to add new records to the database, everything goes ok without any errors, but I don't see the new record in the database.
Update code works, but insert code doesn't work. No errors appear, but no records are inserted into the database.
My code :
var DBs2 = ConnectionTools.OpenConn();
DBs2.Configuration.AutoDetectChangesEnabled = false;
DBs2.Configuration.ValidateOnSaveEnabled = false;
var resList = CreatedSerials.Where(u => u.Item4 == VID).ToList();
foreach (var r in resList)
{
// if serial id ==0 => new then add it as new
if ( r.Item7 == 0)
{
try
{
var purchasesItemSerials = new purchases_item_seriels()
{
pitem_ID = pitem_ID,
stitems_ID = r.Item1,
pmain_ID = PurchasesID,
pitem_virtualID = r.Item4,
pis_CustomSerial = r.Item2,
pis_ExpireDate = r.Item3,
pis_Statues = 0,
ss_StoreID = Convert.ToInt32(gridView1.GetRowCellValue(ItemImdex, "storeID")),
Purchases_Price = Convert.ToDecimal(gridView1.GetRowCellValue(ItemImdex, "item_NetSmallestUnitPrice")),
};
ss.Add(purchasesItemSerials);
}
catch (Exception eeeeee)
{
Msg.Show("", eeeeee.ToString(), 0);return;
}
}
else
{
var DBs350 = ConnectionTools.OpenConn();
var UpdateSerial = DBs350.purchases_item_seriels.Find(r.Item7);
UpdateSerial.pitem_ID = pitem_ID;
UpdateSerial.stitems_ID = r.Item1;
UpdateSerial. pmain_ID = PurchasesID;
UpdateSerial.pitem_virtualID = r.Item4;
UpdateSerial.pis_CustomSerial = r.Item2;
UpdateSerial.pis_ExpireDate = r.Item3;
UpdateSerial.pis_Statues = r.Item6;
UpdateSerial.ss_StoreID = Convert.ToInt32(gridView1.GetRowCellValue(ItemImdex, "storeID"));
UpdateSerial.Purchases_Price = Convert.ToDecimal(gridView1.GetRowCellValue(ItemImdex, "item_NetSmallestUnitPrice"));
DBs350.SaveChanges();
}
}
try
{
DBs2.purchases_item_seriels.AddRange(ss);
DBs2.SaveChanges();
}
catch (Exception eeeeee)
{
Msg.Show("", eeeeee.ToString(), 0);return;
}
I also tried :
DBs2.Configuration.AutoDetectChangesEnabled = true;
DBs2.Configuration.ValidateOnSaveEnabled = true;
but again: no data is inserted, no errors appear
I also tried :
int returnCode = DBs2.SaveChanges();
and returnCode = 0
**I also tried : inserting just a single item then SaveChanges **
// if this serial is new
var NewSerialresList = CreatedSerials.Where(u => u.Item4 == VID && u.Item7 == 0).ToList();
if (NewSerialresList.Count() > 0)
{
var ss = new List<purchases_item_seriels>();
foreach (var r in NewSerialresList)
{
try
{
mrsalesdbEntities DBs002 = new mrsalesdbEntities();
var purchasesItemSerials = new purchases_item_seriels()
{
pitem_ID = pitem_ID,
stitems_ID = r.Item1,
pmain_ID = PurchasesID,
pitem_virtualID = r.Item4,
pis_CustomSerial = r.Item2,
pis_ExpireDate = r.Item3,
pis_Statues = 0,
ss_StoreID = Convert.ToInt32(gridView1.GetRowCellValue(ItemImdex, "storeID")),
Purchases_Price = Convert.ToDecimal(gridView1.GetRowCellValue(ItemImdex, "item_NetSmallestUnitPrice")),
};
//ss.Add(purchasesItemSerials);
DBs002.purchases_item_seriels.Add(purchasesItemSerials);
DBs002.SaveChanges();
}
catch (Exception ex)
{
Msg.Show("", ex.ToString(), 0);
}
}
int CC = ss.Count();
}
i use this function to change the connection variables at run-time :
public static mrsalesdbEntities OpenConn()
{
mrsalesdbEntities MrSalesContext = new mrsalesdbEntities();
MrSalesContext.ChangeDatabase
(
initialCatalog: myconn.database,
port: Convert.ToUInt32( myconn.port),
userId: myconn.uid,
password: myconn.password,
dataSource: myconn.server
);
return MrSalesContext;
}
public static void ChangeDatabase(
this DbContext source,
string initialCatalog = "",
uint port = 3307,
string dataSource = "",
string userId = "",
string password = "",
bool integratedSecuity = true,
string configConnectionStringName = "mrsalesdbEntities")
/* this would be used if the
* connectionString name varied from
* the base EF class name */
{
try
{
// use the const name if it's not null, otherwise
// using the convention of connection string = EF contextname
// grab the type name and we're done
var configNameEf = string.IsNullOrEmpty(configConnectionStringName)
? source.GetType().Name
: configConnectionStringName;
// add a reference to System.Configuration
var entityCnxStringBuilder = new EntityConnectionStringBuilder
(System.Configuration.ConfigurationManager
.ConnectionStrings[configNameEf].ConnectionString);
// init the sqlbuilder with the full EF connectionstring cargo
var sqlCnxStringBuilder = new MySqlConnectionStringBuilder
(entityCnxStringBuilder.ProviderConnectionString);
// only populate parameters with values if added
if (!string.IsNullOrEmpty(initialCatalog))
sqlCnxStringBuilder.Database = initialCatalog;
if ((port) != 0)
sqlCnxStringBuilder.Port = port;
if (!string.IsNullOrEmpty(dataSource))
sqlCnxStringBuilder.Server = dataSource;
if (!string.IsNullOrEmpty(userId))
sqlCnxStringBuilder.UserID = userId;
if (!string.IsNullOrEmpty(password))
sqlCnxStringBuilder.Password = password;
// set the integrated security status
//sqlCnxStringBuilder.IntegratedSecurity = integratedSecuity;
// now flip the properties that were changed
source.Database.Connection.ConnectionString
= sqlCnxStringBuilder.ConnectionString;
}
catch (Exception ex)
{
// set log item if required
}
}
}
I'm making a library for connecting an Informix database with a C# extension for use in Outsystems.
So, now I've hit a wall. I need to receive a list/multiset from the db. How can I do that? I'm using the IfxDataReader to receive the data. But I see no method that could work.
Here is how we can send a list/multiset input parameter. But I need to receive it from a result set.
EDIT: Seeing as this was frowned upon by someone I'll provide some code and my try at it to see if you think it's correct (can't test it right now as I don't yet have data on the database... I'll test it in the end):
ssBensAndFotos = new RLBensAndFotos_BemRecordList();
DatabaseConnection dc = new DatabaseConnection(ssDatabase, ssHost, ssServer, ssService, ssProtocol, ssUserID, ssPassword);
try
{
dc.Conn = new IfxConnection(dc.ConnectionString);
dc.Cmd = new IfxCommand("get_bens_and_fotos_by_id_diligencia", dc.Conn);
dc.Cmd.CommandType = CommandType.StoredProcedure;
dc.Cmd.Parameters.Add(new IfxParameter("pi_id_diligencia", IfxType.Integer) { Direction = ParameterDirection.Input, Value = sspi_id_diligencia });
dc.Conn.Open();
using (IfxDataReader reader = dc.Cmd.ExecuteReader())
if (reader.HasRows)
while (reader.Read())
{
var bensAndFotos = new STBensAndFotos_BemStructure()
{
ssid_bem = reader.GetInt32(0),
ssnumero = reader.GetInt32(1),
ssespecie = reader.GetString(2),
ssbem = reader.GetString(3),
ssvalor = reader.GetDecimal(4),
sscomum = reader.GetInt32(5),
ssvoice_record = AuxiliaryMethods.CreateByteArrayFromIfxBlob(reader.GetIfxBlob(6))
};
// Here I get the string, split it and check to see which members of the array are integers, since in this case I'll be getting a multiset of int's
var multisetString = reader.GetString(7).Split('\'');
int n;
foreach (var item in multisetString)
if (int.TryParse(item, out n))
bensAndFotos.ssfotos.Add(new STBensAndFotos_FotoStructure() { ssfoto = n });
ssBensAndFotos.Add(bensAndFotos);
}
dc.Conn.Close();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
LIST, MULTISET and SET are mapped to String. You should be able to use IfxDataReader.GetString() to get the data.
I am rather new to the whole programming with C# and I stumbled upon a small problem that I just cannot solve.
I start up the software the code below is programmed into and it is working well until it reaches the SaveChanges call and it throws an error:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
I have already attempted to inspect EntityValidationErrors, but it doesn't want to show me any errors at all. So I am turning to you all to find some answers.
//
// GET: /Installningar/FoxImportTidning
public async Task<ActionResult> FoxImportTidning()
{
Tidning tidning = new Tidning();
SaveTidningToDatabase("C:/Backup/Prenback/backuptidning.xls");
return View();
}
//
// POST: /Installningar/FoxImportTidning
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> FoxImportTidning(Tidning Id)
{
if (ModelState.IsValid)
{
db.Entry(Id).State = EntityState.Modified;
await db.SaveChangesAsync();
Main.PopulateGlobalInst();
ViewBag.SaveMsg = "Sparat!";
return RedirectToAction("Main", "Main", new { Id = Id.Id });
}
return View(Id);
}
private ApplicationDbContext databas6 = new ApplicationDbContext();
private string SaveTidningToDatabase(string filePath)
{
String excelConnString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0\"", filePath);
using (OleDbConnection excelConnection = new OleDbConnection(excelConnString))
{
using (OleDbCommand cmd = new OleDbCommand("Select * from [backuptidning$]", excelConnection))
{
excelConnection.Open();
var tidningLista = new List<Tidning>();
databas6.Tidnings.Clear();
databas6.SaveChanges();
using (OleDbDataReader dReader = cmd.ExecuteReader())
do
{
while (dReader.Read())
{
Object[] tidninginfo = new Object[45];
int id = Convert.ToInt32(dReader[0]);
string namn = Convert.ToString(dReader[1]);
string datadir = Convert.ToString(dReader[2]);
string adr1 = Convert.ToString(dReader[3]);
string adr2 = Convert.ToString(dReader[4]);
string regnr = Convert.ToString(dReader[5]);
string tel = Convert.ToString(dReader[6]);
string pg = Convert.ToString(dReader[7]);
string bg = Convert.ToString(dReader[8]);
string villkor = Convert.ToString(dReader[9]);
int sista_nr = Convert.ToInt32(dReader[10]);
int faktavg = Convert.ToInt32(dReader[11]);
int vilande = Convert.ToInt32(dReader[12]);
int listlopnr = Convert.ToInt32(dReader[13]);
int faktnr = Convert.ToInt32(dReader[14]);
decimal moms = Convert.ToDecimal(dReader[15]);
int avipriskod = Convert.ToInt32(dReader[16]);
DateTime? inbetdat = null;
try
{
inbetdat = Convert.ToDateTime(dReader[17]);
}
catch { }
int period = Convert.ToInt32(dReader[18]);
string avityp = Convert.ToString(dReader[19]);
DateTime? sistavidat = null;
try
{
sistavidat = Convert.ToDateTime(dReader[20]);
}
catch { }
DateTime? fromdatum = null;
try
{
fromdatum = Convert.ToDateTime(dReader[21]);
}
catch { }
DateTime? tomdatum = null;
try
{
tomdatum = Convert.ToDateTime(dReader[22]);
}
catch { }
int fromprennr = Convert.ToInt32(dReader[23]);
int tomprennr = Convert.ToInt32(dReader[24]);
string databasversion = Convert.ToString(dReader[25]);
int nummerperiod = Convert.ToInt32(dReader[26]);
int nolastyear = Convert.ToInt32(dReader[27]);
int nonextyear = Convert.ToInt32(dReader[28]);
string dubbelnummer = Convert.ToString(dReader[29]);
bool skrivetik = Convert.ToBoolean(dReader[30]);
bool utrmomsavdrag = Convert.ToBoolean(dReader[31]);
bool buntning = Convert.ToBoolean(dReader[32]);
int pren = Convert.ToInt32(dReader[33]);
int betalare = Convert.ToInt32(dReader[34]);
int kredit = Convert.ToInt32(dReader[35]);
int fornyanr = Convert.ToInt32(dReader[36]);
string landskod = Convert.ToString(dReader[37]);
DateTime? nästsist = null;
try
{
nästsist = Convert.ToDateTime(dReader[38]);
}
catch { }
string fax = Convert.ToString(dReader[39]);
string epost = Convert.ToString(dReader[40]);
string hemsida = Convert.ToString(dReader[41]);
string bic = Convert.ToString(dReader[42]);
string iban = Convert.ToString(dReader[43]);
string faktkoll = Convert.ToString(dReader[44]);
var tidning = new Tidning();
tidning.Id = id;
tidning.Namn = namn;
tidning.Datadir = datadir;
tidning.Adr1 = adr1;
tidning.Adr2 = adr2;
tidning.Regnr = regnr;
tidning.Tel = tel;
tidning.Pg = pg;
tidning.Bg = bg;
tidning.Villkor = villkor;
tidning.Sista_nr = sista_nr;
tidning.FaktAvg = faktavg;
tidning.Vilande = vilande;
tidning.Listlopnr = listlopnr;
tidning.Faktnr = faktnr;
tidning.Moms = moms;
tidning.AviPriskod = avipriskod;
tidning.InbetDatum = inbetdat;
tidning.Period = period;
tidning.AviTyp = (AviTyp)Enum.Parse(typeof(AviTyp), avityp, true);
tidning.SistAviDatum = sistavidat;
tidning.FromDatum = fromdatum;
tidning.TomDatum = tomdatum;
tidning.FromPrennr = fromprennr;
tidning.TomPrennr = tomprennr;
tidning.Databasversion = databasversion;
tidning.Nummerperiod = nummerperiod;
tidning.Nolastyear = nolastyear;
tidning.Nonextyear = nonextyear;
tidning.Dubbelnummer = dubbelnummer;
tidning.Skrivetik = skrivetik;
tidning.Utrmomsavdrag = utrmomsavdrag;
tidning.Buntning = buntning;
tidning.Pren = pren;
tidning.Betalare = betalare;
tidning.Kredit = kredit;
tidning.Fornyanr = fornyanr;
tidning.Landskod = landskod;
tidning.NastSist = nästsist;
tidning.Fax = fax;
tidning.Epost = epost;
tidning.Hemsida = hemsida;
tidning.Bic = bic;
tidning.Iban = iban;
tidning.Faktkoll = faktkoll;
tidningLista.Add(tidning);
}
} while (dReader.NextResult());
databas6.Tidnings.AddRange(tidningLista);
databas6.SaveChanges(); //<--- This is where it goes wrong
excelConnection.Close();
return ("hej"); //<--- Do not mind this one
}
}
}
If you need any further information, just tell me and I will provide it. The main thing I want is to get this working and this is not the only code giving me this problem, but if this one can be solved, then maybe the other ones can be solved the same way.
This error is caused when you are trying to add invalid data to your database table.
e.g. you are adding string of 100 chars to the table column but in table definition your column has maxlength of 50. in that case value you are adding is invalid as per the column definitions and this error occur.
you should log what properties are causing the error. for that you can use below code:
catch (System.Data.Entity.Validation.DbEntityValidationException ex)
{
Logger.WriteError("{0}{1}Validation errors:{1}{2}", ex, Environment.NewLine, ex.EntityValidationErrors.Select(e => string.Join(Environment.NewLine, e.ValidationErrors.Select(v => string.Format("{0} - {1}", v.PropertyName, v.ErrorMessage)))));
throw;
}
You can catch these errors easily ,using the watch window, without writing much code.
Kindly find the very good solution in the following link
https://stackoverflow.com/a/40732784/3397630
I really inspired in the way that answer was given, with the very good screenshots . Sharing it here with the hope it will be helpful to you and the others.
thanks
KArthik
I have the following code. The program just exits, no value returned from call. Any ideas?
AS400System system = new AS400System();
system.Define(ConfigurationManager.AppSettings["AS400Server"]);
system.UserID = ConfigurationManager.AppSettings["AS400User"];
system.Password = ConfigurationManager.AppSettings["AS400Password"];
system.IPAddress = "10.98.1.21";
system.Connect(cwbcoServiceEnum.cwbcoServiceRemoteCmd);
if(system.IsConnected(cwbcoServiceEnum.cwbcoServiceRemoteCmd) == 1) {
Program program = new Program();
program.LibraryName = "P2PTST";
program.ProgramName = "AUI0XFR";
program.system = system;
program.system.Signon();
string paramStatus = "A";
Int64 paramStockItem = Int64.Parse(t.EtagNumber);
Guid paramGuid = Guid.NewGuid();
string paramReturn;
StringConverter stringConverter = new StringConverter();
ProgramParameters parameters = new ProgramParameters();
parameters.Append("ApiIGuid", cwbrcParameterTypeEnum.cwbrcInout, 38);
parameters.Append("StockItemNumber", cwbrcParameterTypeEnum.cwbrcInout, 20);
parameters.Append("ItemStatus", cwbrcParameterTypeEnum.cwbrcInout, 1);
parameters.Append("ReturnCode", cwbrcParameterTypeEnum.cwbrcInout, 7);
parameters["ApiIGuid"].Value = stringConverter.ToBytes(paramGuid.ToString().PadRight(38, ' '));
parameters["StockItemNumber"].Value = stringConverter.ToBytes(paramStockItem.ToString().PadRight(20, ' '));
parameters["ItemStatus"].Value = stringConverter.ToBytes(paramStatus.ToString());
try{
program.Call(parameters);
paramReturn = stringConverter.FromBytes(parameters["ReturnCode"].Value);
system.Disconnect(cwbcoServiceEnum.cwbcoServiceAll);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
We just went through this and had the same issues, so decided to create and use a stored procedure to accomplish this in .NET. Because we were concerned about having the 400 side distribute the code to create a stored procedure, it ended up being very quick to go ahead and create the procedure on the PC side, followed by our remote command, so no additional changes were necessary on the 400 side.
My environment is Win7 x64 running VS2012 C#, CAX V7.1, and importing both IBM.Data.DB2.iSeries, and System.Data;
I need System.Data for the Parameters. That ended up being critical to get data back!
I send the 400 two params, filesetID and a name. I get back a number and a uuid.
(but they are all characters!)
It looks something like this:
public void RemoteCmd(ref PicMeta pm)
{
iDB2Connection cn;
try
{
using (cn = new iDB2Connection("DataSource=<servername/IP>; UserID="<user>"; Password="<pass>";"))
{
cn.Open();
using (iDB2Command cm = cn.CreateCommand())
{
//Place a try/catch here, so it will create the procedure the first time, or any time it has been removed from the 400. If already set, it will fail, and you'll go directly to the remote command.
try
{
//Here we create a procedure and execute or continue.
cm.CommandText = "CREATE PROCEDURE LIBRARY.SP_PICGETID(INOUT FSET CHAR (1 ), INOUT UNIT CHAR (6 ), INOUT NEXTID CHAR (3 ), INOUT UUID CHAR (36 )) LANGUAGE RPGLE NOT DETERMINISTIC NO SQL CALLED ON NULL INPUT EXTERNAL NAME LIBRARY.PICGETID PARAMETER STYLE GENERAL";
cm.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.Out.WriteLine(ex.Message);
}
//Continue - create and call the command
//ParameterDirection needs "using System.Data;"
cm.CommandTimeout = 0;
cm.CommandType = System.Data.CommandType.StoredProcedure;
cm.CommandText = "LIBRARY.SP_PICGETID";
iDB2Parameter p = new iDB2Parameter();
p.ParameterName = "FSET";
p.Direction = ParameterDirection.Input;
p.iDB2DbType = iDB2DbType.iDB2Char;
p.Size = 1;
p.iDB2Value = pm.fileset;
cm.Parameters.Add(p);
p = new iDB2Parameter();
p.ParameterName = "UNIT";
p.Direction = ParameterDirection.Input;
p.iDB2DbType = iDB2DbType.iDB2Char;
p.Size = 6;
p.iDB2Value = pm.unit;
cm.Parameters.Add(p);
p = new iDB2Parameter();
p.ParameterName = "NEXTID";
p.Direction = ParameterDirection.InputOutput;
p.iDB2DbType = iDB2DbType.iDB2Char;
p.Size = 3;
p.iDB2Value = "";
cm.Parameters.Add(p);
p = new iDB2Parameter();
p.ParameterName = "GUUID";
p.Direction = ParameterDirection.InputOutput;
p.iDB2DbType = iDB2DbType.iDB2Char;
p.Size = 36;
p.iDB2Value = "";
cm.Parameters.Add(p);
cm.ExecuteNonQuery();
iDB2ParameterCollection pc = cm.Parameters;
//We get our Out parameters here
pm.nextid = pc["NEXTID"].Value.ToString();
pm.uuid = pc["GUUID"].Value.ToString();
}
cn.Close();
}
}
catch (Exception e)
{
Console.Out.WriteLine(e.Message);
}
return;
}
Hope this helps!
I am LINQ to input information from a Database. I have my try.catch block set up to catch these exceptions. However I believe I ran into a sore spot where I am attempting to see what the message is but it just bypass printing the message to me and goes directly to error page. Here is an example of the code I have so far. I would love to get some input on why this seems to be acting so strange.
private void CreateEntry()
{
var date = DateTime.Today;
var version = (from v in house.StayLateVersions
where v.Active
select v).FirstOrDefault();
if (version == null)
{
throw new NullReferenceException();
}
//Try to create an entry for the database. Upon failure, sends the exception to ThrowDbError();
try
{
ResidenceHallInspection rhi = new ResidenceHallInspection();
rhi.versionId = version.id;
rhi.submitDate = DateTime.Now;
rhi.CheckInOrOut = ddlCheck.SelectedItem.Text;
rhi.Id = txtId.Text;
rhi.FirstName = txtFirstName.Text;
rhi.MiddleName = txtMiddleName.Text;
rhi.LastName = txtLastName.Text;
rhi.Walls = chbxWalls.SelectedItem.Text;
rhi.Windows = chbxWindows.SelectedItem.Text;
rhi.Blinds = chbxBlinds.SelectedItem.Text;
rhi.Couch = chbxCouch.SelectedItem.Text;
rhi.CommonRoomCouch = chbxCRCouch.SelectedItem.Text;
rhi.CommonRoomChair = chbxCRChair.SelectedItem.Text;
rhi.Doors = chbxDoors.SelectedItem.Text;
rhi.Carpet = chbxCarpet.SelectedItem.Text;
rhi.Ceiling = chbxCeiling.SelectedItem.Text;
rhi.CommonRoomCounter = chbxCRCounter.SelectedItem.Text;
rhi.Cabinet = chbxCabinet.SelectedItem.Text;
rhi.Phone = chbxPhone.SelectedItem.Text;
rhi.Bed = chbxBed.SelectedItem.Text;
rhi.Desk = chbxDesk.SelectedItem.Text;
rhi.DeskChairs = chbxDeskChair.SelectedItem.Text;
rhi.Tub = chbxTub.SelectedItem.Text;
rhi.Vanity = chbxVanity.SelectedItem.Text;
rhi.Notes = txtNotes.Text;
rhi.Building = txtResHall.Text;
rhi.ApartmentNumber = txtSuitNo.Text;
rhi.BedSpace = txtBedSpace.Text;
house.AddToResidenceHallInspections(rhi);
house.SaveChanges();
}
catch (Exception oe)
{
ThrowDbError(oe);
Response.Write(oe.InnerException);
}
}
/*=================================================*/
/*Possible Errors */
/*=================================================*/
private void ThrowDbError(Exception oe)
{
Response.Write(oe.Source);
house.Dispose();
Session.Contents.Add("FormException", oe);
Response.Redirect("/Database-Error/", true);
}
The most likely reason for that to happen is that you are running the database version query outside the try/catch block. Any exception in this db access code will not be handled by the code you have shown above.
Try extending your try block to also include the db access code:
var version = (from v in house.StayLateVersions
where v.Active
select v).FirstOrDefault();
if (version == null)
{
throw new NullReferenceException();
}
and see if this time the error is caught.