c# ZFrame data extraction - c#

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());

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
}

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

Fill an array with a loop

I want to get a shorter code than now but I don't know how.
What I do now is like the code below.
arrPictureBox[0] = picChair0;
arrPictureBox[1] = picChair1;
arrPictureBox[2] = picChair2;
arrPictureBox[3] = picChair3;
arrPictureBox[4] = picChair4;
arrPictureBox[5] = picChair5;
arrPictureBox[6] = picChair6;
arrPictureBox[7] = picChair7;
arrPictureBox[8] = picChair8;
arrPictureBox[9] = picChair9;
arrPictureBox[10] = picChair10;
arrPictureBox[11] = picChair11;
(pic) is a picturebox.
But I want less code but I don't know if it possible to do this with a loop (for loop).
for (int i = 0 ; i < arrPictureBox.Length; i++)
{
arrPictureBox[i] = picChair + i;
}
If picChairN is a local variable then there's nothing you can do to simplify it as much as you'd like. The best you can do is
arrPictureBox = new [] { picChair0, picChair1, picChair2, picChair3,
picChair4, picChair5, picChair6, picChair7,
picChair8, picChair9, picChair10, picChair11};
If picChairN is a class member (e.g. a field created by the designer) then you could use reflection, but considering you already have the array method typed out I don't see much benefit.
Let's predict you're on WinForms and the pictureBoxes already exist, then you can use the following:
for (int i = 0; i < arrPictureBox.Length; i++)
{
arrPictureBox[i] = this.Controls["picChair" + i];
}
Which actually does this:
get the first Control (a PictureBox for example) with the given name
add the found control to the array of pictureboxes
EDIT:
It might be useful to check for non existing pictureBoxes:
for (int i = 0 ; i < arrPictureBox.Length; i++)
{
var pb = this.Controls["picChair" + i] as PictureBox;
if (pb != null)
{
arrPictureBox[i] = pb;
}
}
You can use al List like below.
List<string> arrPictureBox = new List<string>();
for (int i = 0; i < 20; i++)
{
arrPictureBox.Add("picChair" + i);
}
var result = arrPictureBox.ToArray();
Hope it helps.
If all the picture boxes are on the same form and are the ONLY picture boxes on the form, you can loop through them with something like the following:
int x = 0;
foreach(Control c in this.Controls)
{
if(c is PictureBox)
{
arrPictureBox[x++] = c
}
}

unable to convert string to int when using streamreader

I am having trouble converting a string to an int. Ive looked around and have been told to use the int.Parse but it isn't helping.
I have created an object Winner that has a int WinnerScore and string WinnerName.
I am trying to add these values to an array Winner[] before sorting them.
When I run this code it says:
NullReferenceException was unhandled
Object reference not set to an instance of an object.
Any idea why this is happening?
StreamReader sr = new StreamReader("highscores.txt");
for (int u = 0; u < nWinners; u++)
{
unsortedList[u].WinnerScore = int.Parse(sr.ReadLine());
unsortedList[u].WinnerName = sr.ReadLine();
}
sr.Close();
With a certain confidence I can suppose that you have declared the array unsortedList but you haven't initialized the objects of Winner class that you want to store in that array.
Simply declaring
Winner[] unsortedList = new Winner[100];
creates an array that could store 100 instances of Winner but this array is empty, there are no instances of a Winner class in the 100 slots available, they are all null. You should create every single Winner instances that you want to store in the 100 slots of the array.
So, as an example, your code could be rewritten as
Winner[] unsortedList = new Winner[nWinners];
using(StreamReader sr = new StreamReader("highscores.txt"))
{
for (int u = 0; u < nWinners; u++)
{
Winner w = new Winner();
w.WinnerScore = int.Parse(sr.ReadLine());
w.WinnerName = sr.ReadLine();
unsortedList[u] = w;
}
sr.Close();
}
However, this has the drawback that you need to know, before entering the loop, the exact number of Winner objects required to dimension your array, If, for some reason, you fail to count them correctly, you fall in another problem (Index Out Of Range).
In this case it is always better to use a List<Winner> where you don't need to know before hand the exact number of elements
List<Winner> unsortedList = new List<Winner>();
using(StreamReader sr = new StreamReader("highscores.txt"))
{
while((line = sr.ReadLine()) != null))
{
Winner w = new Winner();
w.WinnerScore = int.Parse(line);
w.WinnerName = sr.ReadLine();
unsortedList.Add(w);
}
sr.Close();
}
You've left creation as well as initialization:
// My suggestion of unsortedList generic type
public struct Winner {
public int WinnerScore;
public String WinnerName;
}
...
// 1. You shoud create unsortedList:
List<Winner> unsortedList = new List<Winner>();
// 2. You should also initialize the list with Winner instances
for (int u = 0; u < nWinners; ++u)
unsortedList.Add(new Winner());
// 3. Only that you can fill unsortedList from file.
// And you original code becames the correct one
using (StreamReader sr = new StreamReader("highscores.txt")) {
for (int u = 0; u < nWinners; ++u) {
unsortedList[u].WinnerScore = int.Parse(sr.ReadLine());
unsortedList[u].WinnerName = sr.ReadLine();
}
}
var unsortedList = new List<Winner>();
var nWinners = 100;
using (StreamReader sr = new StreamReader("highscores.txt"))
{
for (int i = 0; i < nWinners; i++)
{
var winer = new Winner();
winer.WinnerScore = int.Parse(sr.ReadLine());
winer.WinnerName = sr.ReadLine();
unsortedList.Add(winer);
}
sr.Close();
}

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

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;
....

Categories