Reputation: 33
I wrote a webservice to create a new invoice in the database, but I am having problems to pass the line itens from a windows client to this WS. MY WS is:
namespace InvoicesTest
{
/// <summary>
/// Summary description for Invoices
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Invoices : System.Web.Services.WebService
{
[Serializable]
public struct InvoiceItem
{
public string Product {get; set;}
public string PartNumber {get; set;}
}
[WebMethod(Description = "Create Document Type")]
public string newDocType(string docTypeName, List<InvoiceItem> lstInvoiceItem)
{
for (int i = 0; i < lstInvoiceItem.Count; i++)
{
...
return "ok";
}
}
}
Until here is ok. My problem is to pass the values from a windows form to this WS. First I got an error that I should send an array instead List...
Now, I am getting an error like System.IndexOutOfRangeException: Index was outside the bounds of the array
private void button4_Click(object sender, EventArgs e)
{
InvoiceItem[] dt = new InvoiceItem[listView1.Items.Count];
int j = 0;
foreach (ListViewItem listItem in listView1.Items)
{
dt[j].Product = listItem.SubItems[0].Text;
dt[j].PartNumber = listItem.SubItems[1].Text;
j++;
}
textBox1.Text = InvoicesTest.newDocType("teste", dt.ToArray());
}
Even working with List<>
, it doesnt work.
I appreciate any help...
Upvotes: 2
Views: 1713
Reputation: 33
Thanks Richard, let me try show the result of my test to pass a custom collection as a parameter to the webservice.
Create a custom collection class...
public class Invoice
{
public int InvoiceNumber;
public string Product, PartNumber;
public Invoice() { }
public Invoice(string product, string pNumber, int iNumber)
{
InvoiceNumber = iNumber;
Product = product;
PartNumber = pNumber;
}
}
Create a Web Method...
[WebMethod]
public void Method(Invoice[] fields, bool attachmentincluded)
{
System.Collections.Generic.List<Invoice> invoices = new List<Invoice>(fields);
foreach (Invoice i in invoices)
{
string N,P;
int I;
N =i.PartNumber;
P = i.Product;
I = i.InvoiceNumber;
}
}
In the consumer application...
//Create Invoices...
List<Invoice> lst = new List<Invoice>();
try
{
foreach (ListViewItem listItem in listView1.Items)
{
Invoice aux = new Invoice();
aux.Product = listItem.SubItems[0].Text;
aux.PArtNumber = listItem.SubItems[1].Text;
lst.Add(aux);
}
textBox1.Text += localhost.Invoice(lst.ToArray(), true);
}
catch (Exception ex)
{
textBox1.Text = ex.ToString();
throw;
}
Upvotes: 0
Reputation: 19403
I think you'd be better to have a list within the invoices class and populate that; e.g.
[Serializable]
public struct InvoiceItem
{
public string Product {get; set;}
public string PartNumber {get; set;}
}
public class Invoices : System.Web.Services.WebService
{
/*[DataMember] ** needed If working with data contracts */
public List<InvoiceItem> InvoiceItems {get; set;}
}
then load it by :
invoice.InvoiceItems.Clear();
foreach (ListViewItem listItem in listView1.Items)
invoice.InvoiceItems.Add(new InvoiceItem()
{ ProductNumber = listItem.SubItems[0].Text,
PartNumber = listItem.SubItems[1].Text}
);
Generally I find it way easier to work with the built in collections such as List rather than arrays that are somehow old fashioned and clunky to use. maybe that's just me though.
Upvotes: 2