Object reference not set to an instance of an object - webservices - c#

I have this error appearing in my web service and even though I'v had a look at the articles on the null issue, I am not able to find how to fix this error
this is my code:
SendInvUpdate.InvServices.UpdateRatePackagesRequest urq = new SendInvUpdate.InvServices.UpdateRatePackagesRequest();
SendInvUpdate.InvServices.UpdateRatePackagesOperationResponse ors = new SendInvUpdate.InvServices.UpdateRatePackagesOperationResponse();
protected void Page_Load(object sender, EventArgs e)
{
Int64 HID = 819942;
Int64 HRID = 154482;
SendInvUpdate.InvServices.UpdateRatePackagesRequest request = new SendInvUpdate.InvServices.UpdateRatePackagesRequest();
ChannelManagerAccount account = new ChannelManagerAccount();
request.HotelId = HID;
int avail = 4;
DateTime frodte = Convert.ToDateTime("2012-04-12");
DateTime todte = Convert.ToDateTime("2012-04-30");
int NoofRatePackages = 3;
UpdateRatePackageRequest[] RatePackages = new UpdateRatePackageRequest[NoofRatePackages];
string res;
request.RatePackages = new UpdateRatePackageRequest[NoofRatePackages];
request.RatePackages = RatePackages;
UpdateRatePackageRequest rp = new UpdateRatePackageRequest();
for (int i = 0; i < NoofRatePackages; i++)
{
rp.RatePackageId = HRID;
RateDetails[] Rates = new RateDetails[NoofRatePackages];
rp.Rates = new RateDetails[NoofRatePackages];
rp.Rates = Rates;
RateDetails rd = new RateDetails();
for (int j = 0; j < NoofRatePackages; j++)
{
rd.Availability = avail;
rd.AvailabilityApplicationType = SendInvUpdate.InvServices.AvailabilityApplicationType.SET;
rd.FromDate = frodte;
rd.ToDate = todte;
}
}
SendInvUpdate.InvServices.InventoryServiceClient icc = new SendInvUpdate.InvServices.InventoryServiceClient();
// ( *Line where the error appears*)
ors = icc.UpdateRatePackages(request);
res = ors.Results.ToString();
}
I know that it has something to do with the RateDetails array and initialising the value of the RateDetails to that instant of request but I am not sure how or what to do with regards to that. In debug mode when looking at values of rp there are no values for rp.Rates[0],rp.Rates[1],rp.Rates[2] also RatePackages[0],RatePackages[1],RatePackages[2] are also null so I have a strong feeling thats where my problem is but I don't have a clue on how to fix.
Would be grateful for any sort of insight to where I've gone wrong!

Move the initialization of icc service reference inside your page_load code as
SendInvUpdate.InvServices.InventoryServiceClient icc = new SendInvUpdate.InvServices.InventoryServiceClient();
ors = icc.UpdateRatePackages(request); ( Line where the error appears)
I'm not an expert in asp.net but you can't base your code on global vars if you don't save them in some persistent container (search about SESSION, VIEWSTATE)
EDIT:
also something seems wrong here
UpdateRatePackageRequest[] RatePackages = new UpdateRatePackageRequest[NoofRatePackages];
string res;
request.RatePackages = new UpdateRatePackageRequest[NoofRatePackages];
request.RatePackages = RatePackages;
should be only request.RatePackages = new UpdateRatePackageRequest[NoofRatePackages]; ?
EDIT2:
You send to the InventoryServiceClient an object request that contains an array of UpdateRatePackageRequest, but after creation of the array you don't set any instance of UpdateRatePackageRequest. So I suppose the InventoryServiceClient fails when reading the values from the array.
I will try to change your for loop in this way
for (int i = 0; i < NoofRatePackages; i++)
{
UpdateRatePackageRequest rp = new UpdateRatePackageRequest();
request.RatePackages[i] = rp;
....
Same error with RateDetails. You create the array, but don't set any value of your array with an actual instance of RateDetails
for (int j = 0; j < NoofRatePackages; j++)
{
RateDetails rd = new RateDetails();
rp.Rates[j] = rd;
....

Related

How to create a class in a loop with custom names in C#

So my program lets me send requests using WSDL the class below is provided by the WSDL:
CreateCustomerNoteRequest createCustomerNotesRequestInfo = new CreateCustomerNoteRequest();
Using this class I have to set the variables like this:
//FIRST WRITING NOTE TO OLD ACCOUNT TO SAY ITS BEEN COMPRIMISED AND SHOW NEW CUSTOMER NUMBER:
createCustomerNotesRequestInfo.UserName = username;
createCustomerNotesRequestInfo.Password = password;
createCustomerNotesRequestInfo.SystemToken = "sysToken";
createCustomerNotesRequestInfo.Note = new CustomerNote();
createCustomerNotesRequestInfo.Note.CustomerNumber = cloneCustomerNumber;
createCustomerNotesRequestInfo.Note.Category = new CustomerServiceWSDL.LookupItem();
createCustomerNotesRequestInfo.Note.Category.Code = "GEN";
createCustomerNotesRequestInfo.Note.Details = "Account Takeover – Fraud. Acc – " + customerNumberTextBox.Text + " closed as compromised and new account " + newCloneCustomerNumber + " created matching existing data";
And to finish off I use this to get my response:
createCustomerNotesResponse = soapClient.CreateCustomerNote(createCustomerNotesRequestInfo);
Everything works fine. What I want to do now is because I have multiple Notes I want to loop this process so depending on how many Note there are it would create that many instances.
I do successfully get all the Notes into a list like this using notecount which provides how many number of notes there are (Given by WSDL) so all is good so far:
try
{
for (int i = 0; i <= notesCount; i++)
{
customerNotesArrayList.Add(getCustomerNotesResponse.Notes.Items[i]);
//i++;
}
}
What I want to do: Now depending on the notes count I want to create that many of this:
CreateCustomerNoteRequest createCustomerNotesRequestInfo = new CreateCustomerNoteRequest();
I tried this:
for (int i=0; i<=notesCount;i++)
{
CreateCustomerNoteRequest a[i] = new CreateCustomerNoteRequest();
}
But its not as easy as that so how can I loop to make this happen?
So I want a1, a2, a3 where Ill then loop all the notes in later which shouldn't be a problem. But creating these in the first place is the problem.
[EDIT]
//Create Notes and copy over array contents...
CreateCustomerNoteRequest request = new CreateCustomerNoteRequest();
for (int i = 0; i <= notesCount; i++)
{
request.UserName = username;
request.Password = password;
request.SystemToken = systemToken;
request.Note = new CustomerNote();
request.Note.CustomerNumber = newCloneCustomerNumber;
request.Note.Category = new CustomerServiceWSDL.LookupItem();
request.Note.Category.Code = customerNotesArrayList[i].NoteCategory.Code.ToString();
request.Note.Details = customerNotesArrayList[i].NoteText;
var response = soapClient.CreateCustomerNote(request);
}
You're declaring the array inside the loop, which means it won't be available afterwards. Furthermore you need to declare the array size beforehand:
CreateCustomerNoteRequest[] a = new CreateCustomerNoteRequest[notesCount];
for (int i = 0; i < notesCount; i++)
{
a[i] = new CreateCustomerNoteRequest();
}
// now you can use the array outside the loop as well
Instead of an array you could choose to use a List<CreateCustomerNoteRequest>, which doesn't need a size declaration first.
Note that if you're planning to get the notes inside the same loop, you won't need the array at all:
for (int i = 0; i < notesCount; i++)
{
CreateCustomerNoteRequest request = new CreateCustomerNoteRequest();
var response = soapClient.CreateCustomerNote(request);
// todo process response
}

c# ZFrame data extraction

I need help to understand ZFrames. Using ZeroMq with clrzmq4 binding for c#, I create a frame from a string. Then I get the string from frame and I get an empty string. Something so simple as
public Form1()
{
InitializeComponent();
ZMessage msg = new ZMessage();
msg.Add(new ZFrame("AABBCCDD"));
textBox1.Text = msg.PopString();
}
what do I missed?
Thanks in advance
Edited:
I can get the content with
List<ZFrame> l = msg.ToList();
byte[] by = l[0].Read();
char[] cby = new char[by.Length + 1];
for (int a = 0; a < by.Length; a++)
cby[a] = (char)by[a];
textBox1.Text = new string(cby);
I cant understand why?
I would say this is a bug in clrzmq4: https://github.com/zeromq/clrzmq4/issues/110
As a workaround, if you rewind the stream in between yourself using Position = 0, it works, i.e.
var frame = new ZFrame("AABBCCDD");
frame.Position = 0;
var msg = new ZMessage {frame};
Assert.AreEqual("AABBCCDD", msg.PopString());

keep getting exception, value not getting input into array

Here is my code.. I'm trying to read in from a file with comma delimited data and the names are in the file as "Doe,John" so I am using this to get the name, without it being seperated out by the comma....
fileIn = new TextFieldParser(INPUT_FILE_NAME);
fileIn.TextFieldType = FieldType.Delimited;
fileIn.SetDelimiters(",");
fileIn.HasFieldsEnclosedInQuotes = true;
Here is some of my source code. The name is not being put into nameArray[i] = words[1];
static void InputEmployeeData()
{
int i;
string[] words;
numOfEmployee = Int32.Parse(fileIn.ReadLine());
idArray = new int[numOfEmployee];
nameArray = new string[numOfEmployee];
deptArray = new int[numOfEmployee];
payrateArray = new double[numOfEmployee];
hoursArray = new double[numOfEmployee];
for (i = 0; i <= numOfEmployee; i++)
{
words = fileIn.ReadFields();
idArray[i] = Int32.Parse(words[0]);
nameArray[i] = words[1];
deptArray[i] = Int32.Parse(words[2]);
payrateArray[i] = Double.Parse(words[3]);
hoursArray[i] = Double.Parse(words[4]);
}
}
A sample line from the data file I am reading in from is this.
0090,"Baker, John",1,32.57,50.75
I have numOfEmployee = readline because there is metadata at the top of the file to let me know how many persons are in the file. I keep getting an exception (Object reference not set to an instance of an object) on line 86....
idArray[i] = int.Parse(words[0]);
You need to change this line
for (i = 0; i <= numOfEmployee; i++)
to
for (i = 0; i < numOfEmployee; i++)
The for loop cycles to many times because it start from zero so, you should stop at numOfEmployee - 1. If you execute the loop as is, in the last loop the words array is set to null by the TextFieldParser.ReadFields and you get the Object Reference Not Set Exception

Creating multiple SalesForce Cases in single login

I'm using a SOAP Web Reference in a C# service for this.
If I call (in my SForceManager class) CreateSForceCase() multiple times within the same connection, I receive the same exact CaseNumber until the connection times out and is reconnected (or if i create a new connection for each).
The problem with this, is that I'm needing to insert upto say 5000 cases, and at 3 seconds per case that will take ~4 hours to insert all 5000 cases. Is there a way to let the API know that I want a brand new case each and every time I create one without logging out?
Here's my Manager code:
public String CreateSForceCase(Case sfCase, out string errMsg)
{
//Verify that we are already authenticated, if not
//call the login function to do so
if (!isConnected()) login();
errMsg = "";
sObject[] objCases = new sObject[1];
for (int j = 0; j < objCases.Length; j++)
objCases[j] = sfCase;
//create the object(s) by sending the array to the web service
SaveResult[] sr = _Binding.create(objCases);
for (int j = 0; j < sr.Length; j++)
{
if (sr[j].success)
{
//save the account ids in a class array
if (_cases == null)
_cases = new string[] { sr[j].id };
else
{
string[] tempcases = null;
tempcases = new string[_cases.Length + 1];
for (int i = 0; i < _cases.Length; i++)
tempcases[i] = _cases[i];
tempcases[_cases.Length] = sr[j].id;
_cases = tempcases;
}
return getCaseNumberFromCaseId(_cases[0]);
}
else
{
//there were errors during the create call, go through the errors
//array and write them to the screen
for (int i = 0; i < sr[j].errors.Length; i++)
{
//get the next error
Error err = sr[j].errors[i];
errMsg = err.message;
}
}
}
return string.Empty;
}
and the call within for getting the case # is:
public String getCaseNumberFromCaseId(string caseId)
{
if (!isConnected()) login();
sObject[] ret = _Binding.retrieve("CaseNumber", "Case", new string[] { caseId });
if (ret != null)
return ((Case)ret[0]).CaseNumber;
else
return string.Empty;
}
so something like:
SForceManager manager = new SForceManager();
string case1 = manager.CreateSForceCase(...);
string case2 = manager.CreateSForceCase(...);
string case3 = manager.CreateSForceCase(...);
then case1 == case2 == case3
but if i do:
SForceManager manager = new SForceManager();
string case1 = manager.CreateSForceCase(...);
SForceManager manager = new SForceManager();
string case2 = manager.CreateSForceCase(...);
SForceManager manager = new SForceManager();
string case3 = manager.CreateSForceCase(...);
then case1 != case2 != case3 like i expect
So I figured out a way to perform this.
The idea is to actually take in a list of "Case objects" and send those all at once, then return a string array of case id's.
I'm not sure what would happen if I try opening too many such that the timeout period may pass in the middle of processing (so it could be improved yet):
public String[] CreateSForceCases(Case[] sfCase, out List<string> errMsg)
{
String[] toRet = new string[sfCase.Length];
errMsg = new List<string>();
//Verify that we are already authenticated, if not
//call the login function to do so
if (!isConnected()) login();
//errMsg = "";
sObject[] objCases = new sObject[sfCase.Length];
for (int j = 0; j < objCases.Length; j++)
objCases[j] = sfCase[j];
//create the object(s) by sending the array to the web service
SaveResult[] sr = _Binding.create(objCases);
for (int j = 0; j < sr.Length; j++)
{
if (sr[j].success)
{
//save the account ids in a class array
if (_cases == null)
_cases = new string[] { sr[j].id };
else
{
string[] tempcases = null;
tempcases = new string[_cases.Length + 1];
for (int i = 0; i < _cases.Length; i++)
tempcases[i] = _cases[i];
tempcases[_cases.Length] = sr[j].id;
_cases = tempcases;
}
toRet[j] = getCaseNumberFromCaseId(_cases[j]);
}
else
{
//there were errors during the create call, go through the errors
//array and write them to the screen
for (int i = 0; i < sr[j].errors.Length; i++)
{
//get the next error
Error err = sr[j].errors[i];
errMsg.Add(err.message);
}
}
}
return toRet;
//return null;
}
There was also a problem in the error handling process in the original, however this one fixes that. I figured I would post my solution in case anyone else has come across this issue...I was not able to find any answer to my question anywhere.

What are the correct SAPI input parameters to the succesfully usage?

I have a problem this COM function I can't know what the correct parameters are.
I get bad notification from VS 2013.
Program: speakBoard
WAVEFORMATEX waveFORMATEX = new WAVEFORMATEX();
waveFORMATEX.wFormatTag = 1;
waveFORMATEX.nChannels = 1;
waveFORMATEX.nSamplesPerSec = 44100;
waveFORMATEX.wBitsPerSample = 16;
waveFORMATEX.nBlockAlign = 4;
waveFORMATEX.cbSize = 0;
SPVTEXTFRAG SPVtextFRAG = new SPVTEXTFRAG();
SPVtextFRAG.pTextStart = "one";
SPVtextFRAG.ulTextLen = 100;
SPVtextFRAG.ulTextSrcOffset = 0;
SpeakBoard1.STTTSEngine se;
Guid rguid = new Guid("ggg");
SpeakBoard1.ISpTTSEngineSite es;
se.Speak(255, ref rguid, ref waveFORMATEX, ref SPVtextFRAG, es);
I face with similar problem for C++. This is my code for filling the main structure:
SPVTEXTFRAG fillSPVTEXTFRAG(){
SPVTEXTFRAG spvTextFrag;
spvTextFrag.pNext = NULL;
spvTextFrag.State.eAction = SPVA_Speak;
spvTextFrag.State.LangID = 3;
spvTextFrag.State.wReserved = 3;
spvTextFrag.State.EmphAdj = 3;
spvTextFrag.State.RateAdj = 3;
spvTextFrag.State.Volume = 100;
spvTextFrag.State.PitchAdj.MiddleAdj = 0;
spvTextFrag.State.PitchAdj.RangeAdj = 0;
spvTextFrag.State.SilenceMSecs = 0;
//spvTextFrag.State.pPhoneIds = ;
spvTextFrag.State.ePartOfSpeech = SPPS_Unknown;// SPPARTOFSPEECH.SPPS_Unknown;
spvTextFrag.State.Context.pCategory;
spvTextFrag.State.Context.pBefore;
spvTextFrag.State.Context.pAfter;
spvTextFrag.pTextStart = L"one";
spvTextFrag.ulTextLen = 100;
spvTextFrag.ulTextSrcOffset = 0;
return spvTextFrag;
}
This code fills one of five parameters for call the Speak method of ISpTTSEngine. But you also need to implement the ISpTTSEngineSite interface for such calls.

Categories