views:

45

answers:

2

Hi.

I am currently trying to add a custom "column name" to a property in a web service. Here is my class.

public class OrderCost
{ 
    public int OrderNum { get; set; }
    public int OrderLine { get; set; }       
    public int OrderRel { get; set; }
    public DateTime OrderDate { get; set; }
    public string PartNum { get; set; }
    public string Description { get; set; }
    public decimal Qty { get; set; }
    public string SalesUM { get; set; }
    public decimal Cost { get; set; }
    public decimal Price { get; set; }
    public decimal Net { get; set; }
    public decimal Margin { get; set; }
    public string EntryPerson { get; set; }
    public string CustID { get; set; }
    public string Customer { get; set; }
}

Basically I have another class (on the Silverlight side) that loops through all the properties and creates a column for each property. Thing is, I want to use a different name other than the name of the property. For example, I would like to show "Order Number" instead of OrderNum. I have attempted to use custom attributes but that does not seem to work. Is there way I can provide a different name to these properties over a web service with a use of an attribute? Is there another way I can achieve what I am trying to do?

A: 

If what you're looking for is a way to control this meta-data on the server without having to update client applications, then I don't think attributes are a solution. For one thing, the attributes are defined at compile-time, and I don't think you should manipulate them at runtime even if you have the ability to do so. Another problem, though, is that web services don't really have any native mechanism that corresponds to .Net attributes, so there isn't a built-in way to communicate the meta-data that those attributes represent.

If you really want to have this meta-data defined through attributes, then you could put your OrderCost class in a separate shared assembly for both the web service and client applications to consume. The downside here is that if you want to change the values you defined in your attributes, then the client applications would not see those changes until they obtained the updated DLL.

Alternatively, if you want client applications to be totally ignorant of any changes to the meta-data, then I'd consider creating some kind of Display class that contains the display information that you want and gets returned as part of the result.

For example, the code below shows a class named MyResultObject, which contains a single "Display" object and a list of "Data" objects. Obviously, namespaces, class names, and organization of those classes is up to you:

namespace MyApplication
{
    public class MyResultObject
    {
        public Display.OrderCost Display { get; set; }

        public IList<Data.OrderCost> Data { get; set; }
    }
}

namespace MyApplication.Display
{
    public class Column
    {
        public string HeaderText { get; set; }
        public bool Visible { get; set; }
    }

    public class OrderCost
    {
        public Column OrderNum { get; set; }
        public Column OrderLine { get; set; }
        public Column OrderRel { get; set; }
        public Column OrderDate { get; set; }
        public Column PartNum { get; set; }
        public Column Description { get; set; }
        public Column Qty { get; set; }
        public Column SalesUM { get; set; }
        public Column Cost { get; set; }
        public Column Price { get; set; }
        public Column Net { get; set; }
        public Column Margin { get; set; }
        public Column EntryPerson { get; set; }
        public Column CustID { get; set; }
        public Column Customer { get; set; }
    }
}

namespace MyApplication.Data
{
    public class OrderCost
    {
        public int OrderNum { get; set; }
        public int OrderLine { get; set; }
        public int OrderRel { get; set; }
        public DateTime OrderDate { get; set; }
        public string PartNum { get; set; }
        public string Description { get; set; }
        public decimal Qty { get; set; }
        public string SalesUM { get; set; }
        public decimal Cost { get; set; }
        public decimal Price { get; set; }
        public decimal Net { get; set; }
        public decimal Margin { get; set; }
        public string EntryPerson { get; set; }
        public string CustID { get; set; }
        public string Customer { get; set; }
    }
}

I think you should ask yourself, though, if it makes sense for a service to have any knowledge about how its data will be displayed. Conversely, does it make sense for a client to be consuming data that it doesn't understand, such that it needs meta-data in order to properly handle that data? In some cases that might be exactly what you want to do, but probably not in the general case, I think. Anyway, it's up to you what the correct approach is for your application.

Dr. Wily's Apprentice
You can't share types in ASMX web services like you can with WCF.
John Saunders
I should have been more explicit in my answer; what I had in mind was having a common assembly used by both the client and the server, though this would require specifically coding your web service proxy to use the classes in that assembly, rather than just generating the code from the WSDL. I think that would be possible, but would require more coupling between the client and server beyond just the WSDL and is not at all an ideal solution in my opinion.
Dr. Wily's Apprentice
A: 

No, neither attributes, nor anything else specific to .NET can be used between the client and the service. See "Basics: How Web Services Work" to learn why not.

John Saunders