To return a NewsItem from your webservice, add the [XMLInclude] attribute
before the declaration of the NewsItem class.
I think what may be confusing you about the public default constructor is
this: If you create a constructor with parameters, then no default
construct will be automatically created; you will have to manually create
one. If you do not create any constructor, then a default will be
created automatically. That tidbit may or may not have anything to do
with your problem though.
Here's how I implemented a very simple web service returning a NewsItem
to a web page:
First, the NewsItem class that I created as a public class in the
WebService namespace and file but not within the webservice class:
public class NewsItem
{
private int _NewsId;
private string _NewsTitle;
private string _NewsDate;
private string _PicName;
private string _NewsSummary;
public NewsItem()
{
}
public int NewsId
{
get{return _NewsId;}
set{_NewsId=value;}
}
public string NewsTitle
{
get{return _NewsTitle;}
set{_NewsTitle=value;}
}
public string NewsDate
{
get{return _NewsDate;}
set{_NewsDate = value;}
}
public string PicName
{
get{return _PicName;}
set{_PicName = value;}
}
public string NewsSummary
{
get{return _NewsSummary;}
set{_NewsSummary = value;}
}
}
Next, I added these lines to the Page_Load method of an otherwise blank
webform:
NewsService.Service1 news = new WebApplication2.NewsService.Service1();
news.Credentials = System.Net.CredentialCache.DefaultCredentials;
news.NewsItem item = news.GetItem();
Response.Write(item.NewsSummary);
And then last, I created this WebMethod:
[WebMethod]
[XmlInclude(typeof(NewsItem))]
public NewsItem GetItem()
{
NewsItem item = new NewsItem();
item.NewsDate = "02/05/2005";
item.NewsId = 1;
item.NewsSummary = "No one was killed today.";
item.NewsTitle = "Special Report!";
item.PicName = "NewBornBaby.jpg";
return item;
}
Now, when I run the project, the phrase "No one was killed today." is
displayed as expected. We have successfully returned a custom class
NewsItem from our web service. This is one method of doing so, where we
instantiate on the web service client (the asp.net web application) an
object NewsItem defined in the web service.
Another way I successfully passed a NewsItem from a web service to my
webform involves the following changes:
1. Copy the NewsItem class from the web service file and paste it into
the aspx file, within the project namespace but outside of the webform
class. Now you have the NewsItem class available locally for the webform.
2. The third line of the code for the Page_Load above, remove the "news."
at the beginning. Now we want to instantiate the local copy of the
NewsItem class, rather than the copy at the web service.
3. In the project explorer, make sure you are showing all files and
browse to the Reference.cs file for your web service. Edit all
references to the word NewsItem to read YourNameSpace.NewsItem, except
for one reference to the word - the one that should be the last reference
and it starts with public class NewsItem. This reference is just below
an attribute similar to
[System.Xml.Serialization.XmlTypeAttribute(Namespace=
http://tempuri.org/)]
though yours may have a different namespace.
4. Now if you compile your app and run it again, you will instantiate a
NewsItem from your local copy of the class but it will still accept the
NewsItem returned by the web service and your web form will still display
the phrase "No one was killed today."
All that is left is for you to flush out how to set the properties of the
NewsItems. Though I didn't do it in this example, I have used both these
methods in the past to create arrays of custom classes and successfully
pass them between a web service and ASP.Net. Remember that this behavior
does not follow the W3C guidelines for WebServices and clients other than
ASP.Net may not be able to consume your NewsItem web service.
One last point. If you choose the second route, where you modify the
Reference.cs file, keep in mind that any time you update the web
reference in Visual Studio, the Reference.cs file is re-created and you
will have to make your changes to that file again.
Hope this helps,
DalePres
MCAD, MCDBA, MCSE
Jose Fernandez said:
Well...
new problems...
I created a News class.
This is...
public class NewsItem
{
private int _NewsId;
private string _NewsTitle;
private string _NewsDate;
private string _PicName;
private string _NewsSummary;
public NewsItem()
{
this._NewsId = NewsId;
this._NewsTitle = NewsTitle;
this._PicName = PicName;
this._NewsSummary= NewsSummary;
}
public NewsItem(int ID, string Title, string PicName, string Summary)
{
this._NewsId = ID;
this._NewsTitle = Title;
this._PicName = PicName;
this._NewsSummary= Summary;
}
public int NewsId
{
get{return _NewsId;}
set{_NewsId=value;}
}
public string NewsTitle
{
get{return _NewsTitle;}
set{_NewsTitle=value;}
}
public string NewsDate
{
get{return _NewsDate;}
set{_NewsDate = value;}
}
public string PicName
{
get{return _PicName;}
set{_PicName = value;}
}
public string NewsSummary
{
get{return _NewsSummary;}
set{_NewsSummary = value;}
}
}
And changed the webmethod like this.
[WebMethod]
public ArrayList CoverNews(string Sport)
{
ArrayList NewsItems = new ArrayList();
SqlConnection myConnection = new SqlConnection("Password=XXX;User
ID=XXX;Initial Catalog=XXX;Data Source=XXX");
SqlCommand myCommand = new SqlCommand ("SELECT TOP 1 PERCENT
News.idNews, News.newsTitle, News.newsSummary, News.newsDate,
NewsPictures.picName, News.SportCat" +
" FROM News INNER JOIN NewsPictures ON News.idPic =
NewsPictures.idPic" +
" WHERE (News.SportCat = 'Sport') ORDER BY News.idNews DESC",
myConnection);
try
{
myCommand.Connection.Open();
SqlDataReader dr = myCommand.ExecuteReader();
while(dr.Read())
{
//NewsItems.Add(new
NewsItem((int)dr["idNews"],dr["NewsTitle"].ToString(),dr["PicName"].ToSt
ring(),dr["NewsSummary"].ToString()));
NewsItems.Add(new NewsItem());
}
}
catch(Exception ex)
{
ex.ToString();
}
finally
{
myCommand.Connection.Close();
}
return NewsItems;
}
I did this following the instructions of the link on microsoft. I
created a Class and made an array of it....
It compiled fine, when I press F5 (Visual Studio) i get tha page that
shows the webservice details and I can see the Method, when I invoke it,
i got an empty XML. Just the header...
"<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfAnyType xmlns:xsd="
http://www.w3.org/2001/XMLSchema"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xmlns="
http://tempuri.org/" /> "
BUT on the microsoft page says
"Class and struct types with public fields or properties. The public
properties and fields are serialized. Classes must have a default
constructor that does not accept any parameters."
Default constructor? How can I assing values to my class without
parameters??
I know that with a Dataset... I solve it, but I don't like Datasets for
small pieces of data. I'm just retrieving 1 news.
Thanks