简体   繁体   中英

C# Class Library in WCF Service Application


I have a problem with C# class library and WCF Service Application. I built a class library with two classes Graph and Vertice. And they have few public methods inside. Then I created and published(IIS 7) a simple WCF Application, which uses this class library. Code:

public class GraphsService : IGraphsService
{
    public Graph getGraph(int val)
    {
        return new Graph(val);
    }
}

Of course publish process went fine, and I have an access to this WCF. And now the problem:

When I created an Client Application(Web) and added service reference to this project, I can access the method getGraph(int val) but it returns class which doesn't have any of the methods I implemented in class library. Code for client:

protected void Page_Load(object sender, EventArgs e)
    {
        GraphsServiceClient gc = new GraphsServiceClient();
        Graph g = gc.getGraph(5);
        lblGraph.Text = g.ToString();
    }

That line returns me

GraphsClient.GraphService.Graph

But I want it to return my overriden method ToString(which is implemented in class library). How can I make it works?'

My Graph class from Class Library(removed few methods:

public class Graph
    {
        protected List<Vertice> _vertices;

        public Graph()
        {
            this._vertices = new List<Vertice>();
        }
        public Graph(int startValue)
        {
            this._vertices = new List<Vertice>();
            this._vertices.Add(new Vertice(startValue));
        }

        public List<Vertice> Vertices
        {
            get
            {
                return this._vertices;
            }
        }

        public Vertice getFirstVertice()
        {
            if (this._vertices.Count != 0) return this._vertices.First();
            throw new GraphException("Graaph doesn't have any vertices in it!");
        }

        public Vertice findVertice(int value)
        {
            foreach (Vertice v in this._vertices)
            {
                if (v.value == value) return v;
            }
            return null;
        }

        public Graph addVertice(Vertice v, bool undirected = true)
        {
            if (this._vertices.Contains(v)) throw new GraphException("There is already this vertice in graph!");
            foreach (int val in v.Neighbours)
            {
                Vertice tmp = this.findVertice(val);
                if (tmp != null)
                {
                    if (undirected) tmp.addNeighbour(v.value);
                }
                else throw new GraphException("There isn't a vertice " + val + " in graph so it can't be in neighbours list!");
            }
            this._vertices.Add(v);
            return this;
        }

        public int[,] getAdjacencyMatrix()
        {
            int[,] adMatrix = new int[this._vertices.Count + 1, this._vertices.Count + 1];
            Array.Clear(adMatrix, 0, adMatrix.Length);
            int l = 1;
            foreach (Vertice v in this._vertices)
            {
                adMatrix[0, l] = v.value;
                adMatrix[l, 0] = v.value;
                l++;
            }
            for (int i = 1; i < this._vertices.Count + 1; i++)
            {
                for (int j = 1; j < this._vertices.Count + 1; j++)
                {
                    int val1 = adMatrix[i, 0];
                    int val2 = adMatrix[0, j];
                    Vertice v = this.findVertice(val1);
                    if (v.hasNeighbour(val2)) adMatrix[i, j] = v.countNeighbours(val2);
                }
            }
            return adMatrix;
        }

        public string getAdjacencyMatrixAsString()
        {
            string ret = "";
            int[,] adM = this.getAdjacencyMatrix();
            for (int i = 0; i < Math.Sqrt((double)adM.Length); i++)
            {
                for (int j = 0; j < Math.Sqrt((double)adM.Length); j++)
                {
                    if (i != 0 || j != 0) ret += adM[i, j] + "\t";
                    else ret += "\t";
                }
                ret += "\n";
            }
            return ret;
        }

        public override string ToString()
        {
            string ret = "";
            foreach (Vertice v in this._vertices)
            {
                ret += "Vertice: " + v.value + " neighbours: ";
                foreach (int val in v.Neighbours)
                {
                    ret += val + ", ";
                }
                ret = ret.Remove(ret.Length - 2);
                ret += "\n";
            }
            ret = ret.Remove(ret.Length - 1);
            return ret;
        }

    }

Ok, as I get it you Graph is a class marked as a DataContract and you are trying to add behavior to it that can be accessed by the client. The problem is, a DataContract is basically a DTO (Data Transfer Object). None of the behavior you define as part of a DataContract class will be made available to the consuming client as the only items serialized will be the properties. Not knowing exactly what your expectation is on the behavior of the ToString() method on the Graph object, you could add a property to the Graph Object that returns whatever piece of information you hope to get access to. That way you could do something like this.

Graph g = gc.getGraph(5);
lblGraph.Text = g.Name;

Looking at the implementation of your Graph class, I see that you are adding a whole bunch of behavior to the DataContract as suspected. I'd move all of those to the implementation of your OperationContract. None of the methods you have defined in the Graph class will be accessible to the client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM