Add Saml Assertion to a custom binding - c#

I have this CustomBinding:
var sec = new AsymmetricSecurityBindingElement(
new X509SecurityTokenParameters(X509KeyIdentifierClauseType.Any, SecurityTokenInclusionMode.Never),
new X509SecurityTokenParameters(X509KeyIdentifierClauseType.Any, SecurityTokenInclusionMode.AlwaysToRecipient));
sec.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
sec.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
sec.IncludeTimestamp = true;
sec.SetKeyDerivation(false);
sec.KeyEntropyMode = System.ServiceModel.Security.SecurityKeyEntropyMode.ServerEntropy;
sec.EnableUnsecuredResponse = true;
CustomBinding myBinding = new CustomBinding();
myBinding.Elements.Add(sec);
myBinding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
myBinding.Elements.Add(new HttpsTransportBindingElement());
I would like to add some SAML assertions like this:
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" saml:ID="authorization-assertion" saml:IssueInstant="2020-11-12T09:10:27Z" saml:Version="2.0" wsu:Id="authorization-assertion" xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:assertion saml-schema-assertion-2.0.xsd">
<saml:Issuer>COMPANY</saml:Issuer>
<saml:Subject>
<saml:nameID>02942630753.localhost.com</saml:nameID>
</saml:Subject>
<saml:AuthzDecisionStatement Decision="Permit" Resource="IDocument">
<saml:Action Namespace="http://FSE/IDocumentService"/>
</saml:AuthzDecisionStatement>
<saml:AttributeStatement/>
</saml:Assertion>
I thought I might use: myBinding.Elements.Add(), But I don't know how to construct the Assertion element.

As I said yesterday on your previous posting to read a template from a file. You can also put it in code like code below using xml linq. If you read from a file replace the Parse() method with Load() method. :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
string assertion =
"<saml:Assertion xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\"" +
" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" saml:ID=\"authorization-assertion\"" +
" saml:IssueInstant=\"2020-11-12T09:10:27Z\"" +
" saml:Version=\"2.0\"" +
" wsu:Id=\"authorization-assertion\"" +
" xsi:schemaLocation=\"urn:oasis:names:tc:SAML:2.0:assertion saml-schema-assertion-2.0.xsd\">" +
"<saml:Issuer>COMPANY</saml:Issuer>" +
"<saml:Subject>" +
"<saml:nameID>02942630753.localhost.com</saml:nameID>" +
"</saml:Subject>" +
"<saml:AuthzDecisionStatement Decision=\"Permit\" Resource=\"IDocument\">" +
"<saml:Action Namespace=\"http://FSE/IDocumentService\"/>" +
"</saml:AuthzDecisionStatement>" +
"<saml:AttributeStatement/>" +
"</saml:Assertion>";
XDocument doc = XDocument.Parse(assertion);
}
}
}

Related

Create xml like example below and make a request

I need to create an xml which it will look like xml below:
<?xml version="1.0"?>
-<env:Envelope xmlns:ns3="http://rgwspublic2/RgWsPublic2" xmlns:ns2="http://rgwspublic2/RgWsPublic2Service" xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:env="http://www.w3.org/2003/05/soap-envelope">
-<env:Header>
-<ns1:Security>
-<ns1:UsernameToken>
<ns1:Username>xxxx</ns1:Username>
<ns1:Password>yyyy</ns1:Password>
</ns1:UsernameToken>
</ns1:Security>
</env:Header>
-<env:Body>
-<ns2:rgWsPublic2AfmMethod>
-<ns2:INPUT_REC>
<ns3:afm_called_by/>
<ns3:afm_called_for>xxxxxxxxx</ns3:afm_called_for>
</ns2:INPUT_REC>
</ns2:rgWsPublic2AfmMethod>
</env:Body>
</env:Envelope>
I am new in xmls. How can i create an xml like this?
Also if is it easier to create an xml from a list collection?
Then i try to make a request like example below
HttpClient httpClient = new HttpClient();
var response = await httpClient.PostAsync("https://www1.gsis.gr:443", new StringContent(booksFromFile.ToString(), Encoding.UTF8, "application/xml"));
var HttpResponse = await response.Content.ReadAsStringAsync();
Console.WriteLine(HttpResponse);
But i am getting error
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="REFRESH" content="0;url=http://www.gsis.gr"></HEAD>
<BODY>
</BODY>
</HTML>
Try xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml = "<?xml version=\"1.0\"?>" +
"<env:Envelope" +
" xmlns:ns3=\"http://rgwspublic2/RgWsPublic2\"" +
" xmlns:ns2=\"http://rgwspublic2/RgWsPublic2Service\"" +
" xmlns:ns1=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"" +
" xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\">" +
"</env:Envelope>";
XDocument doc = XDocument.Parse(xml);
XElement root = doc.Root;
XNamespace nsEnv = root.GetNamespaceOfPrefix("env");
XNamespace ns1 = root.GetNamespaceOfPrefix("ns1");
XNamespace ns2 = root.GetNamespaceOfPrefix("ns2");
XNamespace ns3 = root.GetNamespaceOfPrefix("ns3");
XElement header = new XElement(nsEnv + "Header",
new XElement(ns1 + "Security",
new XElement(ns1 + "UsernameToken")));
XElement usernameToken = header.Descendants(ns1 + "UsernameToken").FirstOrDefault();
string username = "xxxxx";
string password = "yyyy";
usernameToken.Add(new XElement(ns1 + "Username", username));
usernameToken.Add(new XElement(ns1 + "Password", password));
root.Add(header);
XElement body = new XElement(nsEnv + "Body",
new XElement(ns2 + "rgWsPublic2AfmMethod",
new XElement(ns2 + "INPUT_REC")));
XElement inputRec = body.Descendants(ns2 + "INPUT_REC").FirstOrDefault();
root.Add(body);
string afmCalledFor = "xxxxxxxxx";
inputRec.Add(new XElement(ns3 + "afm_called_by"));
inputRec.Add(new XElement(ns3 + "afm_called_for", afmCalledFor));
}
}
}

When writing file 3 lines are deleted, and should not

I am removing the duplicated entries in one XML file, and the code is removing them and summing the values to have only one entry of each invoice.
But when it reaches the end it removes 3 lines the following ones:
<NumberOfEntries>11972</NumberOfEntries>
<TotalDebit>0</TotalDebit>
<TotalCredit>34422.86</TotalCredit>
So instead of having the final file like:
...
<SourceDocuments>
<SalesInvoices>
<NumberOfEntries>11972</NumberOfEntries>
<TotalDebit>0</TotalDebit>
<TotalCredit>34422.86</TotalCredit>
<Invoice>
<InvoiceNo>FS 006120180101/19959</InvoiceNo>
...
It appears like:
...
<SourceDocuments>
<SalesInvoices>
<Invoice>
<InvoiceNo>FS 006120180101/19959</InvoiceNo>
...
My code is the following one:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication2
{
class Program
{
//Ficheiro
const string FILENAME = "ccc.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XNamespace ns = doc.Root.Name.Namespace;
List<XElement> originalInvoices = doc.Descendants(ns + "Invoice").ToList();
var groups = originalInvoices.GroupBy(x => (string)x.Element(ns + "Hash")).ToList();
var finalInvoices = groups.Select(x => new
{
unit = x.Descendants(ns + "UnitPrice").Sum(z => (decimal)z),
credit = x.Descendants(ns + "CreditAmount").Sum(z => (decimal)z),
tax = x.Descendants(ns + "TaxPayable").Sum(z => (decimal)z),
net = x.Descendants(ns + "NetTotal").Sum(z => (decimal)z),
gross = x.Descendants(ns + "GrossTotal").Sum(z => (decimal)z),
first = x.First()
}).ToList();
foreach (var finalInvoice in finalInvoices)
{
finalInvoice.first.Element(ns + "Line").SetElementValue(ns + "UnitPrice", finalInvoice.unit);
finalInvoice.first.Element(ns + "Line").SetElementValue(ns + "CreditAmount", finalInvoice.credit);
finalInvoice.first.Element(ns + "DocumentTotals").SetElementValue(ns + "TaxPayable", finalInvoice.tax);
finalInvoice.first.Element(ns + "DocumentTotals").SetElementValue(ns + "NetTotal", finalInvoice.net);
finalInvoice.first.Element(ns + "DocumentTotals").SetElementValue(ns + "GrossTotal", finalInvoice.gross);
}
doc.Descendants(ns + "SalesInvoices").FirstOrDefault().ReplaceWith(new XElement(ns + "SalesInvoices", finalInvoices.Select(x => x.first)));
doc.Descendants(ns + "SalesInvoices").
Console.WriteLine(doc);
doc.Save("Root.xml");
Console.ReadKey();
}
}
}
And you can see a sample of my XML file here: Pastebin Link
Can someone help me with this, how can I make it to not remove those 3 lines?
The problem is probably on the last line where it writes the file, but I'm not sure.
doc.Descendants(ns + "SalesInvoices").FirstOrDefault().ReplaceWith(new XElement(ns + "SalesInvoices", finalInvoices.Select(x => x.first)));
Small Update on the question:
Well I really think that the problem is on the line above because if I change for example SalesInvoices with TotalCredit which is the last line of the ones that are disappearing the file still wrong but instead of:
...
<SourceDocuments>
<SalesInvoices>
<Invoice>
<InvoiceNo>FS 006120180101/19959</InvoiceNo>
...
I'm getting:
...
<SourceDocuments>
<SalesInvoices>
<NumberOfEntries>11972</NumberOfEntries>
<TotalDebit>0</TotalDebit>
<TotalCredit>
<Invoice>
<InvoiceNo>FS 006120180101/19959</InvoiceNo>
...
there is a missing 34422.86</TotalCredit> before tag <Invoice>
and it's adding the </TotalCredit> after the first closed element </Invoice> as you can test here: Link to test the code
Easy to fix. Just add the missing 3 elements :
foreach (var finalInvoice in finalInvoices)
{
finalInvoice.first.Element(ns + "Line").SetElementValue(ns + "UnitPrice", finalInvoice.unit);
finalInvoice.first.Element(ns + "Line").SetElementValue(ns + "CreditAmount", finalInvoice.credit);
finalInvoice.first.Element(ns + "DocumentTotals").SetElementValue(ns + "TaxPayable", finalInvoice.tax);
finalInvoice.first.Element(ns + "DocumentTotals").SetElementValue(ns + "NetTotal", finalInvoice.net);
finalInvoice.first.Element(ns + "DocumentTotals").SetElementValue(ns + "GrossTotal", finalInvoice.gross);
}
XElement salesInvoices = doc.Descendants(ns + "SalesInvoices").FirstOrDefault();
XElement numberOfEntries = salesInvoices.Element(ns + "NumberOfEntries");
XElement totalDebit = salesInvoices.Element(ns + "TotalDebit");
XElement totalCredit = salesInvoices.Element(ns + "TotalCredit");
salesInvoices.ReplaceWith(new XElement(ns + "SalesInvoices", new object[] {
numberOfEntries,
totalDebit,
totalCredit,
finalInvoices.Select(x => x.first)
}));

How to read xml file in c# with specific attribute

I have an xml file with attribute
xmlns="http://www.reservwire.com/namespace/WebServices/Xml">
When I remove this attribute, then I can read each tag. If I don't remove attribute I receive error message "Object refrence not set to instance of object"
My C# code:
XmlDocument xml = new XmlDocument();
xml.Load(Server.MapPath("~/HotelSearchCriteria/PrepareBooking.xml"));
string CommmitLevel = xml.DocumentElement
.SelectSingleNode("/BookingCreate/CommitLevel")
.InnerText;
My XML:
<BookingCreate xmlns="http://www.reservwire.com/namespace/WebServices/Xml">
<Authority>
<Org>danco</Org>
<User>xmltest</User>
<Password>xmltest</Password>
<Language>en</Language>
<Currency>EUR</Currency>
<TestDebug>false</TestDebug>
<Version>1.26</Version>
</Authority>
<QuoteId>17081233-3</QuoteId>
<HotelStayDetails>
<Room>
<Guests>
<Adult title="Mr" first="djkvb" last="jkj" />
<Adult title="Mr" first="jfs" last="kjdjs" />
</Guests>
</Room>
</HotelStayDetails>
<HotelSearchCriteria>
<AvailabilityStatus>allocation</AvailabilityStatus>
<DetailLevel>basic</DetailLevel>
</HotelSearchCriteria>
<CommitLevel>prepare</CommitLevel>
</BookingCreate>
What to do to read xml with xmlns attribute? It is necessary for me to have xmlns attribute.
You need to specify the namespace, by using a namespace manager. This should work
XmlDocument bookingXml = new XmlDocument();
bookingXml.Load("PrepareBooking.xml");
XmlNamespaceManager ns = new XmlNamespaceManager(bookingXml.NameTable);
ns.AddNamespace("booking", "http://www.reservwire.com/namespace/WebServices/Xml");
var commitLevel = bookingXml.SelectSingleNode("//booking:BookingCreate//booking:CommitLevel", ns).InnerText;
Using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement bookingCreate = doc.Descendants().Where(x => x.Name.LocalName == "BookingCreate").FirstOrDefault();
XNamespace ns = bookingCreate.GetDefaultNamespace();
var results = doc.Descendants(ns + "BookingCreate").Select(x => new {
org = (string)x.Descendants(ns + "Org").FirstOrDefault(),
user = (string)x.Descendants(ns + "User").FirstOrDefault(),
password = (string)x.Descendants(ns + "Password").FirstOrDefault(),
language = (string)x.Descendants(ns + "Language").FirstOrDefault(),
currency = (string)x.Descendants(ns + "Currency").FirstOrDefault(),
testDebug = (Boolean)x.Descendants(ns + "TestDebug").FirstOrDefault(),
version = (string)x.Descendants(ns + "Version").FirstOrDefault(),
quoteId = (string)x.Element(ns + "QuoteId"),
guests = x.Descendants(ns + "Adult").Select(y => new {
title = (string)y.Attribute("title"),
first = (string)y.Attribute("first"),
last = (string)y.Attribute("last")
}).ToList(),
availability = (string)x.Descendants(ns + "AvailabilityStatus").FirstOrDefault(),
detailLevel = (string)x.Descendants(ns + "DetailLevel").FirstOrDefault()
}).FirstOrDefault();
}
}
}

Unable to read XML due to parent node

I have the following XML file
<eConnect xmlns:dt="urn:schemas-microsoft-com:datatypes">
<SOPTransactionType>
<eConnectProcessInfo>
<ConnectionString>Data Source=DGLSQL1;Initial Catalog=dgl;Persist Security Info=False;Integrated Security=SSPI</ConnectionString>
<EConnectProcsRunFirst>True</EConnectProcsRunFirst>
</eConnectProcessInfo>
<taSopLotAuto_Items>
<taSopLotAuto>
<SOPTYPE>2</SOPTYPE>
<SOPNUMBE>435462</SOPNUMBE>
<LNITMSEQ>16384</LNITMSEQ>
<ITEMNMBR>7740</ITEMNMBR>
<LOCNCODE>18</LOCNCODE>
<QUANTITY>65</QUANTITY>
<LOTNUMBR>15483D0104X68X</LOTNUMBR>
</taSopLotAuto>
</taSopLotAuto_Items>
</SOPTransactionType>
</eConnect>
I am using the following code to read this file
XmlDocument doc = new XmlDocument();
doc.Load("C:\\SOP.XML");
XmlNodeList nodes = doc.SelectNodes("/taSopLotAuto_Items/taSopLotAutoka");
foreach (XmlNode node in nodes)
{
string text = node["SOPTYPE"].InnerText;
Console.WriteLine(text + "\n");
}
Here I want to read the content of <taSopLoAuto>. But I am unable to read the file content. Is this because of top few lines written in document? Please help me to solve the problem.
The namespace is an issue. You can use Linq like below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<eConnect xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">" +
"<SOPTransactionType>" +
"<eConnectProcessInfo>" +
"<ConnectionString>Data Source=DGLSQL1;Initial Catalog=dgl;Persist Security Info=False;Integrated Security=SSPI</ConnectionString>" +
"<EConnectProcsRunFirst>True</EConnectProcsRunFirst>" +
"</eConnectProcessInfo>" +
"<taSopLotAuto_Items>" +
"<taSopLotAuto>" +
"<SOPTYPE>2</SOPTYPE>" +
"<SOPNUMBE>435462</SOPNUMBE>" +
"<LNITMSEQ>16384</LNITMSEQ>" +
"<ITEMNMBR>7740</ITEMNMBR>" +
"<LOCNCODE>18</LOCNCODE>" +
"<QUANTITY>65</QUANTITY>" +
"<LOTNUMBR>15483D0104X68X</LOTNUMBR>" +
"</taSopLotAuto>" +
"<taSopLotAuto>" +
"<SOPTYPE>2</SOPTYPE>" +
"<SOPNUMBE>435462</SOPNUMBE>" +
"<LNITMSEQ>16384</LNITMSEQ>" +
"<ITEMNMBR>7740</ITEMNMBR>" +
"<LOCNCODE>18</LOCNCODE>" +
"<QUANTITY>65</QUANTITY>" +
"<LOTNUMBR>15483D0104X68X</LOTNUMBR>" +
"</taSopLotAuto>" +
"<taSopLotAuto>" +
"<SOPTYPE>2</SOPTYPE>" +
"<SOPNUMBE>435462</SOPNUMBE>" +
"<LNITMSEQ>16384</LNITMSEQ>" +
"<ITEMNMBR>7740</ITEMNMBR>" +
"<LOCNCODE>18</LOCNCODE>" +
"<QUANTITY>65</QUANTITY>" +
"<LOTNUMBR>15483D0104X68X</LOTNUMBR>" +
"</taSopLotAuto>" +
"</taSopLotAuto_Items>" +
"</SOPTransactionType>" +
"</eConnect>";
XDocument doc = XDocument.Parse(xml);
List<XElement> taSopLotAutos = doc.Descendants()
.Where(x => x.Name.LocalName == "taSopLotAuto")
.ToList();
var results = taSopLotAutos.Select(x => new
{
sopType = (int)x.Element("SOPTYPE"),
sopNumbe = (int)x.Element("SOPNUMBE"),
lnitmsseg = (int)x.Element("LNITMSEQ"),
locncode = (int)x.Element("LOCNCODE"),
quantity = (int)x.Element("QUANTITY"),
lotnumbr = (string)x.Element("LOTNUMBR")
}).ToList();
}
}
}

Accessing and displaying certain xml elements from a Service Reference

I'm writing a Stock Quote app in Silverlight and I can't figure out how to display only the information that I want from the xml, such as the price of the stock. It will display the tags and everything.
Here is my code:
private void getQuote_Click(object sender, RoutedEventArgs e)
{
bool check = NetworkInterface.GetIsNetworkAvailable();
if (check)
{
//available
GetQuote.StockQuoteSoapClient client = new StockQuoteSoapClient();
//call that method
client.GetQuoteAsync(symbolBox.Text);
//event handler response
client.GetQuoteCompleted +=client_GetQuoteCompleted;
}
else
{
return;
}
}
public void client_GetQuoteCompleted(object sender, GetQuoteCompletedEventArgs e)
{
result.Text = e.Result;
}
And here is the xml being returned by http://www.webservicex.net/stockquote.asmx?op=GetQuote
<string><StockQuotes><Stock><Symbol>msft</Symbol><Last>46.62</Last><Date>7/17/2015</Date><Time>4:00pm</Time><Change>-0.04</Change><Open>46.59</Open><High>46.78</High><Low>46.26</Low><Volume>29467107</Volume><MktCap>377.14B</MktCap><PreviousClose>46.66</PreviousClose><PercentageChange>-0.09%</PercentageChange><AnnRange>40.12 - 50.05</AnnRange><Earns>2.41</Earns><P-E>19.35</P-E><Name>Microsoft Corporation</Name></Stock></StockQuotes></string>
This is for a mobile app; it has to provide new, up-to-date information from the web service every time it is used, and I only need a few different pieces of the information. Also, the information shouldn't be specifically Microsoft, but any real company whose stock symbol is entered by the user.
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<string>" +
"<StockQuotes>" +
"<Stock>" +
"<Symbol>msft</Symbol>" +
"<Last>46.62</Last>" +
"<Date>7/17/2015</Date>" +
"<Time>4:00pm</Time>" +
"<Change>-0.04</Change>" +
"<Open>46.59</Open>" +
"<High>46.78</High>" +
"<Low>46.26</Low>" +
"<Volume>29467107</Volume>" +
"<MktCap>377.14B</MktCap>" +
"<PreviousClose>46.66</PreviousClose>" +
"<PercentageChange>-0.09%</PercentageChange>" +
"<AnnRange>40.12 - 50.05</AnnRange>" +
"<Earns>2.41</Earns>" +
"<P-E>19.35</P-E>" +
"<Name>Microsoft Corporation</Name>" +
"</Stock>" +
"</StockQuotes>" +
"</string>";
XDocument doc = XDocument.Parse(input);
var stocks = doc.Descendants("Stock").Select(x => new {
symbol = x.Element("Symbol").Value,
last = double.Parse(x.Element("Last").Value),
date = DateTime.Parse(x.Element("Date").Value),
time = DateTime.Parse(x.Element("Time").Value),
change = double.Parse(x.Element("Change").Value),
open = double.Parse(x.Element("Open").Value),
high = double.Parse(x.Element("High").Value),
low = double.Parse(x.Element("Low").Value),
volume = long.Parse(x.Element("Volume").Value),
mktcap = double.Parse(x.Element("MktCap").Value.Replace("B", "")),
previousClose = double.Parse(x.Element("PreviousClose").Value),
percentChange = double.Parse(x.Element("PercentageChange").Value.Replace("%", "")),
annRange = x.Element("AnnRange").Value,
earns = double.Parse(x.Element("Earns").Value),
p_e = double.Parse(x.Element("P-E").Value),
name = x.Element("Name").Value,
}).ToList();
}
}
}
​

Categories