2013-04-03 3 views
0

Я работаю над веб-службой, которая должна принимать коллекцию с тремя значениями разных типов. ЗначенияКак передать многомерный список или кортеж на веб-службу C#

SkuNumber (целое число), FirstName (строка), LastName (строка)

Я хочу, чтобы веб-сервис, чтобы принять список из 100 экземпляров этих значений, но я не уверен, как идти о Это. Я использую многомерный список или массив? Может быть, кортеж? Или я могу просто создать простую структуру классов и принять список этого класса?

Все это достаточно просто в обычном приложении, я просто не знаю, как приложение, вызывающее веб-службу, передаст данные с любым из указанных параметров.

Может ли кто-нибудь дать мне несколько указателей?

+0

FWIW, я вообще избегать собственных многомерных массивов, как чума: они несколько неэффективны, имеют плохую совместимость с новыми конструкциями, как LINQ и сериализация, и обычно вызывает головные боли. – JerKimball

+0

Является ли это службой WCF или устаревшим сервисом ASMX? –

+0

Это устаревшая служба ASMX. Он будет вызываться из приложения терминала терминала POS типа Java. Услуга может быть написана в WCF, что является лучшим подходом. – user2167861

ответ

2

Если совместная сборка невозможна, вы всегда можете использовать хороший XML. Это может быть не оптимальное решение, и я уверен, что многие пользователи здесь откажутся от этой идеи, но ее легко поддерживать и относительно быстро реализовать, поэтому она действительно зависит от вашей индивидуальной ситуации и уровня квалификации разработчиков для поддержки приложения.

Преимущество использования XML здесь заключается в том, что вызывающее приложение может быть написано практически на любом языке практически на любой платформе, если оно придерживается структуры XML.

Строка XML должна быть достаточно простой для генерации в вызывающем приложении, но самым большим недостатком здесь является то, что если у вас тонна данных, обработка может занять больше времени, чем требуется, - на обоих концах службы.

Вот рабочий пример, если вы хотите, чтобы дать ему попробовать:

public class Whatever 
    { 
     public int SkuNumber { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
    } 

    [WebMethod] 
    public void HelloWorld(string xmlString) 
    { 
     //make all the node names + attribute names lowercase, to account for erroneous xml formatting -- leave the values alone though 
     xmlString = Regex.Replace(xmlString, @"<[^<>]+>", m => m.Value.ToLower(),RegexOptions.Multiline | RegexOptions.Singleline); 

     var xmlDoc = LoadXmlDocument(xmlString); 


     var listOfStuff = new List<Whatever>(); 

     var rootNode = xmlDoc.DocumentElement; 
     foreach(XmlNode xmlNode in rootNode) 
     { 
      var whatever = new Whatever 
           { 
            FirstName = xmlNode["first_name"].InnerText, 
            LastName = xmlNode["last_name"].InnerText, 
            SkuNumber = Convert.ToInt32(xmlNode["sku_number"].InnerText) 
           }; 
      listOfStuff.Add(whatever); 
     } 
    } 

    public static XmlDocument LoadXmlDocument(string xmlString) 
    { 
     //some extra stuff to account for URLEncoded strings, if necessary 
     if (xmlString.IndexOf("%3e%") > -1) 
      xmlString = HttpUtility.UrlDecode(xmlString); 

     xmlString = xmlString.Replace((char)34, '\'').Replace("&", "&amp;").Replace("\\", ""); 

     var xmlDocument = new XmlDocument(); 
     xmlDocument.PreserveWhitespace = false; 
     xmlDocument.LoadXml(xmlString); 

     return xmlDocument; 
    } 

Ваш XML будет выглядеть следующим образом:

<stuff_to_track> 
<whatever> 
    <sku_number>1</sku_number> 
    <first_name>jimi</first_name> 
    <last_name>hendrix</last_name> 
</whatever> 
<whatever> 
    <sku_number>2</sku_number> 
    <first_name>miles</first_name> 
    <last_name>davis</last_name> 
</whatever> 
<whatever> 
    <sku_number>3</sku_number> 
    <first_name>david</first_name> 
    <last_name>sanborn</last_name> 
</whatever> 
<whatever> 
    <sku_number>4</sku_number> 
    <first_name>john</first_name> 
    <last_name>coltrane</last_name> 
</whatever> 
</stuff_to_track> 

Я также рекомендую проверки входящего XML, как для схемы и данные.

+0

Thanks kmdsax. Я попробую этот подход. Учитывая разные платформы, я думаю, что это может быть лучше всего подходит. – user2167861

2

Создайте класс и примите список этого класса. Обязательно отметьте его как [Serializable].

[Serializable] 
public class Whatever 
{ 
    public int SkuNumber { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

Лучшая практика будет определить класс в сборке, которые могут быть доступны как на службе, и проект, который вызывает его.

Проблема с кортежем или многомерным массивом заключается в том, что данные, которые вы отправляете, не имеют неотъемлемой идентичности: вы можете вставить в нее какую-нибудь старую вещь. Если у вас есть класс, вы указываете, что отправляете заказ или запрос или купон или что-то, что вы отслеживаете. Есть уровень смысла, который идет вместе с ним.

+0

Спасибо Ann.Это достаточно ясно. Наверное, я все еще не понимаю, как будет работать вызывающее приложение. Им нужно будет иметь одну и ту же структуру классов на своей стороне и передать список «любых» экземпляров? – user2167861

+0

На самом деле, я вижу, вы предположили, что класс, определенный в сборке, доступен для обоих. Это единственный способ, или они могут определить одинаковый класс на стороне вызывающего приложения? Я просто не уверен, есть ли у нас доступное доступное место. – user2167861

+0

FYI, если это служба ASMX, тогда он использует XML-сериализатор, который мало внимания уделяет атрибуту '[Serializable]'. –

0

Просто отправить то, что вы хотите:

public class Whatever 
{ 
    public int SkuNumber { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

[WebMethod] 
public void TakeList(List<Whatever> theList) 
{ 
    foreach (var w in theList) 
    { 
    } 
} 
Смежные вопросы