I am using CSVHelper (https://github.com/JoshClose/CsvHelper/blob/master/src/CsvHelper/Configuration/IReaderConfiguration.cs) to read a csv file and I want to skip a certain number of rows from the beginning of the file. Is it possible to use "ShouldSkipRecord" in order to achieve that?
You could use ShouldSkipRecord if you know that the rows all start with say a certain character.
public class Program
{
public static void Main(string[] args)
{
using (MemoryStream stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream))
using (StreamReader reader = new StreamReader(stream))
using (CsvReader csv = new CsvReader(reader))
{
writer.WriteLine("# Something here.");
writer.WriteLine("# Another line we don't need.");
writer.WriteLine("Id,Name");
writer.WriteLine("1,George");
writer.Flush();
stream.Position = 0;
csv.Configuration.ShouldSkipRecord = row => row[0].StartsWith("#");
var records = csv.GetRecords<Foo>().ToList();
}
}
}
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
If you know you want to skip say the first 2 rows, this would work.
public class Program
{
public static void Main(string[] args)
{
using (MemoryStream stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream))
using (StreamReader reader = new StreamReader(stream))
using (CsvReader csv = new CsvReader(reader))
{
writer.WriteLine("Something here.");
writer.WriteLine("Another line we don't need.");
writer.WriteLine("Id,Name");
writer.WriteLine("1,George");
writer.Flush();
stream.Position = 0;
for (int i = 0; i < 2; i++)
{
csv.Read();
}
var records = csv.GetRecords<Foo>().ToList();
}
}
}
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
Below is what worked for me:
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
ShouldSkipRecord = (row) =>
{
//your logic for skipping records goes here
return (string.IsNullOrEmpty(row.Record[7]);
}
};
using (var reader = new StreamReader("CsvFilePath"))
using (var csv = new CsvReader(reader, config))
{
lst = csv.GetRecords<Foo>().ToList();
}
Related
I'm trying to make use of System.Text.Json serialization for a project I'm working on. When I make use of a custom CosmosSerializer and call GetItemQueryIterator, the ToStream call is being sent a Microsoft.Azure.Cosmos.SqlQuerySpec that cannot be serialized. Here is a sample that should easily reproduce the problem. Any and all help is appreciated!
using Microsoft.Azure.Cosmos;
using System;
using System.IO;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace CosmosTestApp
{
class Program
{
const string endpoint = "<REPLACE>";
const string key = "<REPLACE>";
const string dbName = "test";
const string containerName = "items";
public static async Task Main(string[] args)
{
var options = new CosmosClientOptions()
{
Serializer = new CosmosJsonSerializer()
};
var client = new CosmosClient(endpoint, key, options);
var dbResponse = await client.CreateDatabaseIfNotExistsAsync(dbName);
var db = dbResponse.Database;
var containerDef = new ContainerProperties(containerName, "/id");
var containerResposne = await db.CreateContainerIfNotExistsAsync(containerDef);
var testContainer = containerResposne.Container;
var testDoc = new TestDoc();
var docResponse = await testContainer.CreateItemAsync(testDoc, new PartitionKey(testDoc.Id));
Console.WriteLine($"Created document {docResponse.Resource.Id}");
var query = testContainer.GetItemQueryIterator<TestDoc>("SELECT * FROM c");
while (query.HasMoreResults)
{
var doc = await query.ReadNextAsync();
foreach(var x in doc.Resource)
{
Console.WriteLine($"Retrieved document {x.Id}");
}
}
}
}
internal class CosmosJsonSerializer : CosmosSerializer
{
public override T FromStream<T>(Stream stream)
{
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
stream.Close();
var item = JsonSerializer.Parse<T>(memoryStream.ToArray());
return item;
}
}
//This errors on the SqlQuerySpec
public override Stream ToStream<T>(T input)
=> new MemoryStream(JsonSerializer.ToUtf8Bytes(input));
}
internal class TestDoc
{
[JsonPropertyName("id")]
public string Id { get; set; } = "1";
public string TestString { get; set; } = "testing CosmosJsonSerializer";
}
}
EDIT: Bug has been filed and confirmed here: https://github.com/Azure/azure-cosmos-dotnet-v3/issues/575
I am using ASP.NET Web API and C#. As i am new to Express Mapper and i am having ADO.NET code which is returning list of results.How to map using Express Mapper?
This is a test to demonstrate how to work with custom mappers in ExpressMapper. I hope you'll be able to use it accordingly -
public static void Main()
{
var ds = new DataSet();
var dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Age", typeof(int));
dt.Rows.Add("Test", 10);
dt.Rows.Add("Test2", 10);
ds.Tables.Add(dt);
var mapped = Mapper.Map<DataTable, List<RequestModel>>(ds.Tables[0], new CustomTypeMapper());
}
where -
class RequestModel
{
public int Age { get; set; }
public string Name { get; set; }
}
class CustomTypeMapper : ICustomTypeMapper<DataTable, List<RequestModel>>
{
public List<RequestModel> Map(IMappingContext<DataTable, List<RequestModel>> context)
{
if (context.Source == null)
throw new ArgumentNullException();
var output = new List<RequestModel>();
foreach (DataRow row in context.Source.Rows)
{
output.Add(new RequestModel
{
Age = row.Field<int>("Age"),
Name = row.Field<string>("Name")
});
}
return output;
}
}
I'm trying to create an RSS feed for a ServiceStack Service. I've followed various examples as closely as I can. My problem is that I get no output and I am not sure how to troubleshoot the issue. I suspect I have done something wrong on the serialisation. Here is (a simplified version of) what I have
My DTO's are
using System.Collections.Generic;
using ServiceStack;
using Library;
[Route("/MyCollection/Tomorrow/{ID}", "GET, POST")]
[Api("MyCollections Delivery")]
public class MyCollectionTomorrow
: IReturn<MyCollectionTomorrowResponse>
{
public long ID { get; set; }
}
public class MyCollectionTomorrowResponse : IHasResponseStatus
{
public long ID { get; set; }
public List<MyCollection> Result { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
public class MyCollection
{
public string Description { get; set; }
public string MyCollectionDayOfWeek { get; set; }
public DateTime MyCollectionDate { get; set; }
public bool Assisted { get; set; }
public string RoundType { get; set; }
public string Description { get; set; }
}
My service is
using System;
using Library;
using ServiceStack;
using ServiceStack.Configuration;
using System;
using Library;
using ServiceStack;
using ServiceStack.Configuration;
using MyCollection.Tomorrow;
using MyCollections.Tomorrow;
public class MyCollectionTomorrowService : Service
{
public object Any(WasteCollectionTomorrow request)
{
int id;
var param = new CollectionTomorrow();
param.ID = ID;
var response = client.Get<CollectionTomorrowResponse>(param);
return response;
}
catch (Exception ex)
{
var response = new CollectionTomorrowResponse();
response.Result = null
var status = new ResponseStatus { Message = ex.Message, StackTrace = ex.StackTrace };
response.ResponseStatus = status;
return response;
}
}
}
and my media type is
namespace DataFeedServices
{
using System;
using System.IO;
using System.ServiceModel.Syndication;
using System.Text;
using System.Xml;
using ServiceStack;
using ServiceStack.Data;
using ServiceStack.Web;
using MyCollections.Tomorrow;
public class RssFormat
{
private const string RssContentType = "application/rss+xml";
public static void Register(IAppHost appHost)
{
appHost.ContentTypes.Register(RssContentType, SerializeToStream, DeserializeFromStream);
}
public static void SerializeToStream(IRequest req, object response, Stream stream)
{
StreamWriter sw = null;
try
{
var syndicationFeedResponse = response as MyCollectionResponse;
sw = new StreamWriter(stream);
if (response != null)
{
WriteRssCollectionFeed(sw, syndicationFeedResponse);
}
}
finally
{
if (sw != null)
{
sw.Dispose();
}
}
}
public static void WriteRssCollectionFeed(StreamWriter sw, MyCollectionResponse Mycollections)
{
const string Baseuri = "example.com";
try
{
var uri = new Uri(Baseuri);
var syndicationFeed = new SyndicationFeed(
"MyCollection Service",
"Mycollections " ,
uri);
syndicationFeed.Authors.Add(new SyndicationPerson("email#mysite.com"));
if (Mycollections.Result != null)
{
foreach (var cats in Mycollections.Result)
{
syndicationFeed.Categories.Add(new SyndicationCategory(cats.RoundID));
}
}
syndicationFeed.Generator = "MyApp";
syndicationFeed.Copyright = new TextSyndicationContent("Copyright 2015");
syndicationFeed.LastUpdatedTime = DateTime.Now;
if (Mycollections.Result != null)
{
// set items
foreach (var coll in Mycollections.Result)
{
var item = new SyndicationItem { Title = new TextSyndicationContent(coll.CollectionDate) };
item.Links.Add(new SyndicationLink(uri));
item.Authors.Add(new SyndicationPerson("email#mysite.com"));
var itemContent = new StringBuilder();
itemContent.Append("My Item content");
item.Content = new TextSyndicationContent(
itemContent.ToString(),
TextSyndicationContentKind.Plaintext);
}
}
Rss20FeedFormatter rssFeed = syndicationFeed.GetRss20Formatter();
var xwriter = XmlWriter.Create(sw);
rssFeed.WriteTo(xwriter);
}
catch (Exception)
{
throw new Exception("Something bad happened");
}
}
public static object DeserializeFromStream(Type type, Stream stream)
{
throw new NotImplementedException();
}
}
}
Since your ContentType is not reusable and coupled to a specific MyCollectionResponse, it's easier to just return a raw string with the RSS XML:
[AddHeader(ContentType = "application/rss+xml")]
public object Any(WasteCollectionTomorrow request)
{
//..
return rssXml;
}
You can also write it directly to the Response Output Stream with something like:
public object Any(WasteCollectionTomorrow request)
{
//..
base.Response.ContentType = "application/rss+xml";
RssFormat.SerializeToStream(response, Response.OutputStream);
base.Response.EndRequest();
return null;
}
I am trying to implement a payment gateway(INTUIT payment gateway). I would like to serialize an xml to an model class and save into my database. I am using Desktop Model for intuit payment gateway, as the hosted model is a pain to get working with especially ssl certificates, so i dont want to try that.
I must mention i am able to get the response using the below mentioned code, where i am stuck at the moment is serialize the xml and save the response into the database. This xml is pulled from a folder in my xmlfiles folder located in my project.
For sample xml format, check out this one. https://ipp.developer.intuit.com/0085_QuickBooks_Windows_SDK/qbms/0060_Documentation/Sending_Requests
this is an xml file i am trying to post to url (https://merchantaccount.ptc.quickbooks.com/j/AppGateway)
<?xml version="1.0"?>
<?qbmsxml version="4.5"?>
<QBMSXML>
<SignonMsgsRq>
<SignonDesktopRq>
<ClientDateTime>2012-07-25T17:13:45</ClientDateTime>
<ApplicationLogin>abc.abc.us</ApplicationLogin>
<ConnectionTicket>TGT-1-g42FGaMfOTQ82GcWFBpsuQ</ConnectionTicket>
</SignonDesktopRq>
</SignonMsgsRq>
<QBMSXMLMsgsRq>
<CustomerCreditCardChargeRq>
<TransRequestID>4540453787200</TransRequestID>
<CreditCardNumber>4111111111111111</CreditCardNumber>
<ExpirationMonth>12</ExpirationMonth>
<ExpirationYear>2016</ExpirationYear>
<IsCardPresent>false</IsCardPresent>
<Amount>10.00</Amount>
</CustomerCreditCardChargeRq>
</QBMSXMLMsgsRq>
</QBMSXML>
The Controller i use to make a post to the url
public ActionResult Index()
{
WebRequest req = null;
WebResponse rsp = null;
string fileName = Server.MapPath("~/XMLData/XMLFile1.xml");
string uri = "https://merchantaccount.ptc.quickbooks.com/j/AppGateway";
req = WebRequest.Create(uri);
//req.Proxy = WebProxy.GetDefaultProxy(); // Enable if using proxy
req.Method = "POST"; // Post method
req.ContentType = "application/x-qbmsxml"; // content type
// Wrap the request stream with a text-based writer
StreamWriter writer = new StreamWriter(req.GetRequestStream());
// Write the XML text into the stream
writer.WriteLine(this.GetTextFromXMLFile(fileName));
writer.Close();
// Send the data to the webserver
rsp = req.GetResponse();
// var resp = (Object)rsp.GetResponseStream();
if (rsp != null)
{
StreamReader inStream = new StreamReader(rsp.GetResponseStream());
var data = inStream.ReadToEnd();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(data);
string path = Server.MapPath("~/XMLData/SampleXmlE2E.xml");
xmlDoc.Save(path);//regenerates the xml file in different system.
}
return View();
//XElement root = new XElement("root");
//root.Add(new XElement("element1"));
//root.Add(new XElement("element2"));
//root.Add(new XAttribute("attribute1", "a value"));
//return new XmlResult(root);
}
private string GetTextFromXMLFile(string file)
{
StreamReader reader = new StreamReader(file);
string ret = reader.ReadToEnd();
reader.Close();
return ret;
}
private string SendRequest(Uri UriObj, string data)
{
string _result;
var request = (HttpWebRequest)WebRequest.Create(UriObj);
request.Method = "POST";
request.ContentType = "text/xml";
var writer = new StreamWriter(request.GetRequestStream());
writer.Write(data);
writer.Close();
var response = (HttpWebResponse)request.GetResponse();
var streamResponse = response.GetResponseStream();
var streamRead = new StreamReader(streamResponse);
_result = streamRead.ReadToEnd().Trim();
streamRead.Close();
streamResponse.Close();
response.Close();
return _result;
}
Any help would be appreciated. Thanks
Varun,
[Edit -update]
Based on this XML:
<?qbmsxml version="4.5"?>
<QBMSXML>
<SignonMsgsRq>
<SignonDesktopRq>
<ClientDateTime>2012-07-25T17:13:45</ClientDateTime>
<ApplicationLogin>app.app.login.url</ApplicationLogin>
<ConnectionTicket>TGT-1-g42FGaMfOTQ82GcWFBpsuQ</ConnectionTicket>
</SignonDesktopRq>
</SignonMsgsRq>
<QBMSXMLMsgsRq>
<CustomerCreditCardChargeRq>
<TransRequestID>4540453787200</TransRequestID>
<CreditCardNumber>4111111111111111</CreditCardNumber>
<ExpirationMonth>12</ExpirationMonth>
<ExpirationYear>2016</ExpirationYear>
<IsCardPresent>false</IsCardPresent>
<Amount>10.00</Amount>
</CustomerCreditCardChargeRq>
</QBMSXMLMsgsRq>
</QBMSXML>
Here's the class structure that you'd need to deserialize into as per the example above:
[XmlRoot("QBMSXML")]
public class QbmsXml
{
[XmlElement("SignonMsgsRq")]
public SignonMsgsRq SignonMsgsRq { get; set; }
[XmlElement("QBMSXMLMsgsRq")]
public QbmsXmlMsgsRq QbmsXmlMsgsRq { get; set; }
}
public class SignonMsgsRq
{
[XmlElement("SignonDesktopRq")]
public SignonDesktopRq SignonDesktopRq { get; set; }
}
public class SignonDesktopRq
{
[XmlElement("ClientDateTime")]
public DateTime ClientDateTime { get; set; }
[XmlElement("ApplicationLogin")]
public string ApplicationLogin { get; set; }
[XmlElement("ConnectionTicket")]
public string ConnectionTicket { get; set; }
}
public class QbmsXmlMsgsRq
{
[XmlElement("CustomerCreditCardChargeRq")]
public CustomerCreditCardChargeRq CustomerCreditCardChargeRq { get; set; }
}
public class CustomerCreditCardChargeRq
{
[XmlElement("TransRequestID")]
public Int64 TransRequestID { get; set; }
[XmlElement("CreditCardNumber")]
public string CreditCardNumber { get; set; }
[XmlElement("ExpirationMonth")]
public int ExpirationMonth { get; set; }
[XmlElement("ExpirationYear")]
public int ExpirationYear { get; set; }
[XmlElement("IsCardPresent")]
public bool IsCardPresent { get; set; }
[XmlElement("Amount")]
public double Amount { get; set; }
}
Just use the xmlSerialiser along the lines of:
class Program
{
private static T DeSerialize<T>(string fromXmlFile) where T: class
{
if (!File.Exists(fromXmlFile))
{
return default(T);
}
T deserializedClass;
var serializer = new XmlSerializer(typeof(T));
// ToDo: add error catching etc
using (var reader = new StreamReader(fromXmlFile))
{
deserializedClass = (T)serializer.Deserialize(reader);
}
return deserializedClass;
}
static void Main(string[] args)
{
var yourXmlFilePath = #"d:\temp\xmltest.xml";
var deserializedClass = DeSerialize<QbmsXml>(yourXmlFilePath);
Console.WriteLine(deserializedClass
.QbmsXmlMsgsRq
.CustomerCreditCardChargeRq.Amount);
Console.Read();
}
}
hope this helps.
I have a list which is defined as
List<SoftwareTitles> softwareTitlesList = new List<SoftwareTitles>();
and the SoftwareTitles is a class which is defines as follows:
public class SoftwareTitles
{
string softwareTitle;
string invoiceNumber;
public SoftwareTitles(string softwareTitle, string invoiceNumber)
{
this.softwareTitle = softwareTitle;
this.invoiceNumber = invoiceNumber;
}
string InvoiceNumber
{
get
{
return this.invoiceNumber;
}
}
string SoftwareTitle
{
get
{
return this.softwareTitle;
}
}
}
And now I'm adding the values from the sql server database to the list defines as follows:
public List<SoftwareTitles> SoftwareListRetrieve()
{
ConnectionToSql con1 = new ConnectionToSql();
string connectionString = con1.ConnectionStringMethod();
SqlConnection sqlConnection = new SqlConnection(connectionString);
SqlCommand cmd2 = new SqlCommand("SelectionOfSoftwareTitles", sqlConnection);
cmd2.CommandType = CommandType.StoredProcedure;
sqlConnection.Open();
SqlDataReader dr2 = cmd2.ExecuteReader();
if (dr2.HasRows)
{
while (dr2.Read())
{
String softwareTitle = (String)dr2[0];
String invoiceNumber = (String)dr2[1];
SoftwareTitles s1 = new SoftwareTitles(softwareTitle, invoiceNumber);
softwareTitlesList.Add(s1);
}
}
sqlConnection.Close();
dr2.Close();
return softwareTitlesList;
}
I want to find out the software title for every occurence of invoice number by looping through List<>. And I don't know how ? I have tried to loop through the List<> by the following code. I wanted to use something like contains i.e., softwareTitlesList[i].contains but seems like there is no such property or method
for(int i=0; i<softwareTitlesList.Count;i++)
{
softwareTitlesList[i]. [BUT IT IS NOT SUGGESTING ME ANYTHING]
}
I'm stuck with this from morning. I don't how to solve this dilemma.
Please help me
Thanks in anticipation
search for an invoice number
string invoiceNumber = "111111111";
using linq
IList<string> titles = softwareTitlesList
.Where(st => st.InvoiceNumber == invoiceNumber)
.Select(st => st.SoftwareTitle);
or
IList<string> titles = softwareTitlesList
.Where(st => st.InvoiceNumber.Contains(invoiceNumber))
.Select(st => st.SoftwareTitle);
w/o using linq, it's still pretty basic
IList<string> titles = new List<string>();
foreach(var softwareTitle in softwareTitlesList)
{
if (softwareTitle.InvoiceNumber.Contains(invoiceNumber))
titles.Add(softwareTitle.SoftwareTitle);
}
you could also rewrite your class like this:
public class SoftwareTitles
{
public SoftwareTitles(string softwareTitle, string invoiceNumber)
{
SoftwareTitle = softwareTitle;
InvoiceNumber = invoiceNumber;
}
public string InvoiceNumber { get; private set; }
public string SoftwareTitle { get; private set; }
}