• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3509
  • Last Modified:

How to solve Serialization Error: ...Use XmlElementAttribute or XmlAttributeAttribute to specify a new name...

Hi guys:

I'm getting the following error message:
Member ParameterString.Val of type System.String hides base class member ParameterBase.Val of type System.Object. Use XmlElementAttribute or XmlAttributeAttribute to specify a new name.

The scenario: I have one base class, and two other that derive from it. I want to have a web service that deliver any of the two derived objects. Any help will be welcome on this idea.
The prolem right now is that I can't find the way to get rid of this error.
Following is my code, simple just to reproduce this error.

1- This is the Model class:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace WSAndXml_Model
{
      public abstract class ParameterBase
      {

            protected string _name;
            protected object _val;

            [XmlAttribute]
            public string Name
            {
                  get { return _name; }
                  set { _name = value; }
            }

            [XmlElement(ElementName = "ValObject")]
            public virtual object Val
            {
                  get { return _val; }
                  set { _val = value; }
            }
      }


      public class ParameterInt32 : ParameterBase
      {
            public ParameterInt32() : base()
            {}

            [XmlElement(DataType = "Int32", ElementName = "ValInt32")]
            public new Int32 Val
            {
                  get { return (Int32)_val; }
                  set { _val = value; }
            }
      }


      public class ParameterString : ParameterBase
      {
            public ParameterString() : base()
            {
            }

            [XmlElement(DataType = "string", ElementName = "ValString")]
            public new String Val
            {
                  get { return (String)_val; }
                  set { _val = value; }
            }
      }

}

2- This is the Web Service:
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

using System.Xml.Serialization;
using Model = WSAndXml_Model;


[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[XmlInclude(typeof(Model.ParameterBase))]
[XmlInclude(typeof(Model.ParameterInt32))]
[XmlInclude(typeof(Model.ParameterString))]
public class Parameters : System.Web.Services.WebService
{
      public Parameters()
      {    }

      [WebMethod]
      public Model.ParameterBase GetParameter()
      {
            Model.ParameterBase param = null;
            param = new Model.ParameterInt32();
            param.Name = "First";
            param.Val = 1;

            return param;
      }
}


3- This is the piece of code that access the web service:
      private void btnSubmit_Click(object sender, EventArgs e)
      {
            WSAndXmlRef.Parameters wsParam = new WSAndXmlRef.Parameters();

            WSAndXmlRef.ParameterBase param = null;
            param = wsParam.GetParameter();

            this.lblName.Text = param.Name;
            this.lblValue.Text = param.ValObject.ToString();
      }


Please help, thanks
Aishel
0
aishel73
Asked:
aishel73
  • 3
  • 2
1 Solution
 
corestruct00Commented:
Aishel,

it looks like you just need to make your derived class properties override the base class property (use the keyword override).

          [XmlElement(DataType = "Int32", ElementName = "ValInt32")]
          public override new Int32 Val
          {
               get { return (Int32)_val; }
               set { _val = value; }
          }

See the following: http://msdn2.microsoft.com/en-us/library/ebca9ah3(VS.80).aspx

corestruct00
0
 
aishel73Author Commented:
Actually I changed the line :
 [XmlElement(DataType = "Int32", ElementName = "ValInt32")]
for this other:
 [XmlElement(DataType = "int", ElementName = "ValInt32")]

but the code actually compiles ok. Is the web service while running that generates the error.
Anyway I change the "new" to "override" I get the following error: "cannot change return type when overriding inherited member", and the code won't compile.

Aishel
0
 
sumixCommented:
 either override or new, corestruct!

  and, of course, you cannot override a method and change its return type. The problem here is that you really need a new method.
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
aishel73Author Commented:
If I remove the val the serializer will work. But that is not my idea.
My idea was having a base element of Value type "object" to handle any unconvensional type, not defined in any of the subclases. This from th epoint of view of oop looks the right thing to do. Can you bring your thoughs on this.
The failing point is the serialization side.

Aishel
0
 
sumixCommented:
Here's what you can do:

   Modify the ParameterBase class like this:

    public abstract class ParameterBase
    {

        protected string _name;
        [XmlElement(ElementName="Val")]
        public object _val;

        [XmlAttribute]
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        [XmlIgnore()]
        public virtual object Val
        {
            get { return _val; }
            set { _val = value; }
        }
    }

 This way, in your web service method (you have a local reference to Model assembly) you will see _val, Val (of type object) and Name properties. When sending the result of GetParameter method, 'param' object will be serialized (_val will be sent as an int with name 'Val' and Val will not be sent) and in Submit_Click method you will see for 'param' object Name and Val (of type int) properties.
0
 
aishel73Author Commented:
Hi:

I get it, corect me if I'm wrong. It is not good that the serializer doesn't "understand" the new(C#)/shadows(VB) modifiers.
For the sake of clarity I end up with the following version:

      public class ParameterBase //abstract
      {
            protected string _name;
            protected object _val;

            [XmlAttribute]
            public string Name
            {
                  get { return _name; }
                  set { _name = value; }
            }

            [XmlIgnore()]
            public object Val
            {
                  get { return _val; }
                  set { _val = value; }
            }
            [XmlElement(ElementName="Val")]
            public object ValXml
            {
                  get { return _val; }
                  set { _val = value; }
            }
      }

Thanks all for your help.
Aishel
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now