GeoJSON File Read Exception Handling in .NET? - c#

Getting this error, somewhere, within a 1gb GeoJSON file.
System.ArgumentOutOfRangeException: 'According to the GeoJSON v1.0
spec a LineString must have at least two or more positions. (Parameter
'coordinates')'
The input file is an open-source US roadway file, made up of LineString. I need to log what is causing the Exception and continue processing. How can that be done? The code looks like this:
var featuresAll = "jsonfiles\\MotorVehicleUseMapRoads.json".CreateFromJsonFile<FeatureCollection>();
...
public static T CreateFromJsonFile<T>(this String fileName)
{
T data;
using (FileStream fileStream = new FileStream(fileName, FileMode.Open))
{
data = CreateFromJsonStream<T>(fileStream);
}
return data;
}
Thanks.

Related

How to save a list of objects in a file in ASP.NET MVC

I am trying to save a list of objects (containing files URI) to a file in ASP.NET MVC so that when I load the page, the saved files URI will be loaded and displayed. When I tried it in Windows Forms, it works perfectly, however, I cannot get it working in MVC.
As a reference, the following is the code which I am using in Windows Forms to save the list of objects in a file and to load the contents of the file.
private void Save(List<Uri> list)
{
BinaryFormatter b = new BinaryFormatter();
FileStream file = File.Create(fileName);
b.Serialize(file, list.ToList());
file.Close();
}
private void LoadFile()
{
try
{
BinaryFormatter b = new BinaryFormatter();
FileStream file = File.Open(fileName, FileMode.Open);
fileList = (List<Uri>)b.Deserialize(file);
file.Close();
}
catch
{
MessageBox.Show("Error Loading File!");
}
}
When I put the same code in the Controller class, I am getting an error in the following lines:
FileStream file = File.Create(fileName);
FileStream file = File.Open(fileName, FileMode.Open);
Error:
'Controller.File(byte[], string)' is a method, which is not valid in the given context
My controller name is "FilesController" but I don't think that it is conflicting the names.
Any help would be very appreciated! :)
Thank you very much!
'Controller.File(byte[], string)' is a method, which is not valid in the given context
The Controller class has a member called File already. (A method, as the error states.) So when you do this in your controller:
File.Create(fileName);
The first reference to something called File is that method, which makes this line invalid. If you want to use the System.IO.File object, you have to specify that:
System.IO.File.Create(fileName);
Ideally such dependency-based operations wouldn't happen in a controller. But for simplicity it's not entirely uncommon to do these in a controller if the app doesn't do much in the first place.

C# generics code-bloat - should I be worried?

I'd like to ask something about generics.
I am trying to keep the code simple, and thus I will be making a single class to handle load/save for a game's savegame files. As each portion of the game has different requirements I'd like to keep this as easily accessible as possible:
public void Load<T>(string path, out T obj)
{
BinaryFormatter bf = new BinaryFormatter();
using (FileStream file = File.Open(Application.persistentDataPath + path, FileMode.Open))
{
obj = (T)bf.Deserialize(file);
}
}
Now I can call this with a simple
TurnData x; s.Load("test.txt", out x);
The alternative would be to make the Load function return the object and then convert it to a TurnData type.
TurnData x = (TurnData)s.Load("test.txt");
I do not know much about C#. I assume that the code inside using(...) { ... } does not get executed if there is an error opening the file for example? If someone can confirm this that would be nice. The example code I have seen did not have any error handling, which seemed weird to me, so I added using?
So in this secondary version where the function returns the object instead of using an out parameter would need more complicated code for error checking and possible return null? It doesn't seem great.
So the real question is ... can I use the next version I have here or are there concerns that I should have due to the use of generics?
There is no generic code bloat for reference types - code is reused. With value types, though, CLR will generate a separate method for each type. See
.NET Generics and Code Bloat.
The using statement has nothing to do with error handling. Using File.Open method you can expect to get the exceptions you will find here. You could avoid the abruptly stop of your program from any such an exception by wrapping your using statement in a try/cath construct like below:
public T Load<T>(string path)
{
T obj = default(T);
var bf = new BinaryFormatter();
try
{
using (var file = File.Open(Application.persistentDataPath + path, FileMode.Open))
{
obj = (T)bf.Deserialize(file);
}
}
catch(Exception exception)
{
// Log the exception
}
return obj;
}
Essentially you attempt to Open the file specified in the path. If that fails you just log the failure and your return null from the function.
Regarding the using statement, it provides
a convenient syntax that ensures the correct use of IDisposable
objects.
as you can read more thoroughly here
As a side note regarding the signature of your method I would make a few comments. Consider the following method body and spot the differences with that we have above.
public T Load<T>(string path, IFormatter formatter)
{
if(path ==null) throw new ArgumentNullException(nameof(path));
if(formatter == null) throw new ArgumentNullException(nameof(formatter));
T obj = default(T);
try
{
using (var file = File.Open(path, FileMode.Open))
{
obj = (T)formatter.Deserialize(file);
}
}
catch(Exception exception)
{
// Log the exception
}
return obj;
}
and
var path = Path.Combine(Application.persistentDataPath, "test.txt");
var binaryFormatter = new BinaryFormatter();
var x = s.Load(path, binaryFormatter);
Making the above changes you make your method more easily to be tested through a unit test and more reliable since you make some precondition checking before the meat and potatoes of your method. What would had happened if you had passed a null path? What would had happened if you had passed a null formatter ? etc...

Isolated storage reading data : System.Xml.XmlException: Unexpected XML declaration

I am writing the data and reading it, i am getting the exception as "System.Xml.XmlException: Unexpected XML declaration",i am unable to figure it out whats the issue.
I have also added the exception that its printing.Please help me to solve the issue.
Here my code:
public static void WriteTopicState(Topic topic)
{
try
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (StreamWriter sw = new StreamWriter(store.OpenFile("Stats.xml", FileMode.Append, FileAccess.Write)))
{
XmlSerializer serializer = new XmlSerializer(typeof(Topic));
serializer.Serialize(sw, topic);
serializer = null;
}
}
}
catch (Exception)
{
throw;
}
}
public static Topic ReadMockTestTopicState()
{
Topic topic = null;
try
{
using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
// Read application settings.
if (isoStore.FileExists("Stats.xml"))
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (StreamReader SR = new StreamReader(store.OpenFile("Stats.xml", FileMode.Open, FileAccess.Read)))
{
XmlSerializer serializer = new XmlSerializer(typeof(Topic));
topic = (Topic)serializer.Deserialize(SR);
serializer = null;
}
}
}
else
{
// If setting does not exists return default setting.
topic = new Topic();
}
}
}
catch (Exception)
{
throw;
}
return topic;
}
Exception :
{System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. --->
System.InvalidOperationException: There is an error in XML document (9, 19). --->
System.Xml.XmlException: Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it. Line 9, position 19.
EDIT
If there is any other way that i can save the data to a txt file also is fine for me, but only thing is i need to append the data to the existing document and read it get back the data.
Your problem is because you are appending to your Stats.xml document, as a result it will contain multiple root elements once it has been written to more than once.
If you wish to only store the latest stats, you should use FileMode.Create:
using (StreamWriter sw = new StreamWriter(store.OpenFile("Stats.xml", FileMode.Create, FileAccess.Write)))
Valid XmlDocuments can only contain one root element, if you wish to store multiple 'stats' a different strategy is required:
If writes are only creates (eg not updates) write out each topic to a different file and combine them when reading
Create a container element that will store multiple topics and then parse this from disk, add to it, then subsequently overwrite the file on disk (you'll need to be careful with concurrency if you choose this option)
Use a different storage medium than the file system (eg a document database, a SQL database, etc)
Many other options

How can I access an existing byte[] in C#?

I have a small issue accessing a byte[]:
I have a binary object (byte[] saved to mssql db) which I get from the db and I want to read it. Whenever I access it, for its length or for its Read() method, I get a Cannot access a closed Stream exception.
What's the best way to treat binaries if they have to be updated in the code and than saved again to the db?
Thanks.
Edit - code
In this application we convert a test object to a generic data object we've created to simplify, so this is the data object:
public class DataObject
{
public Stream Content { get; set; }
public Descriptor Descriptor { get; set; }
}
The descriptor contains metadata only (currently only name and description strings) and is not relevant, I think.
The test is more complicated, I'll start by adding the mapping into data object. The serializer mentioned is NetDataContractSerializer.
public DataObject Map(Test test)
{
using(var stream = new MemoryStream())
{
Serialize(test, stream);
return new DataObject { Content = stream, Descriptor = test.Descriptor };
}
}
private void Serialize(Test test, MemoryStream stream)
{
serializer.WriteObject(stream, test);
stream.Flush();
stream.Position = 0;
}
and vice versa:
public Test Build(DataObject data)
{
using (var stream = data.Content)
{
var test = Deserialize(stream);
test.Descriptor = data.Descriptor;
return test ;
}
}
private Test Deserialize(Stream stream)
{
return serializer.ReadObject(stream) as IPythonTest;
}
Edit II - trying to change the test's content:
This is my first attempt handling streams, I'm not sure I'm doing it right, so I'll explain first what I want to do: The information in data field should be saved into the test's data object.
private static void UpdateTestObject(DataObject data, Test test)
{
var testData = new byte[data.Content.Length];
data.Content.Read(testData, 0, (int) data.Content.Length);
test.TestObject = testData;
}
The exception is thrown in UpdateTestObject when accessing data.Content. I get it after creating some test, mapping it, and trying to save it.
data.Content.Read(testData, 0, (int) data.Content.Length);
Here we go. The data object has a Content stream that it closed.
Result: Error.
Reasno? TOTALLY (!) unrelated to your question. Basically find out why / what is the problem there in your data handling.
Could be a design fubar in which the stream is not available after a certain point and youru sage of the object is past this point.
So the problem is caused by the Map() method - as far as I could understand, since it used:
using (var stream = new MemoryStream())
{ ... }
The stream was disposed of at the end of the block. Changing it to declaring a MemoryStream and then using it afterwards worked.
Thanks to everyone who gave it a thought (not mentioning reading all this code)! :)

JSON.NET writing invalid JSON?

It appears that JSON.NET is writing invalid JSON, although I wouldn't be surprised if it was due to my misuse.
It appears that it is repeating the last few characters of JSON:
/* ... */ "Teaser":"\nfoo.\n","Title":"bar","ImageSrc":null,"Nid":44462,"Vid":17}]}4462,"Vid":17}]}
The repeating string is:
4462,"Vid":17}]}
I printed it out to the console, so I don't think this is a bug in Visual Studio's text visualizer.
The serialization code:
static IDictionary<int, ObservableCollection<Story>> _sectionStories;
private static void writeToFile()
{
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
using (IsolatedStorageFileStream stream = storage.OpenFile(STORIES_FILE, FileMode.OpenOrCreate))
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.Write(JsonConvert.SerializeObject(_sectionStories));
}
}
#if DEBUG
StreamReader reader = new StreamReader(storage.OpenFile(STORIES_FILE, FileMode.Open));
string contents = reader.ReadToEnd();
JObject data = JObject.Parse(contents);
string result = "";
foreach (char c in contents.Skip(contents.Length - 20))
{
result += c;
}
Debug.WriteLine(result);
// crashes here with ArgumentException
// perhaps because JSON is invalid?
var foo = JsonConvert.DeserializeObject<Dictionary<int, List<Story>>>(contents);
#endif
}
Am I doing something wrong here? Or is this a bug? Are there any known workarounds?
Curiously, JObject.Parse() doesn't throw any errors.
I'm building a Silverlight app for Windows Phone 7.
When writing the file you specify
FileMode.OpenOrCreate
If the file exists and is 16 bytes longer than the data you intend to write to it (from an older version of your data that just happens to end with the exact same data) then that data will still be present when you're done writing your new data.
Solution:
FileMode.Create
From:
http://msdn.microsoft.com/en-us/library/system.io.filemode.aspx
FileMode.Create: Specifies that the operating system should create a new file. If the file already exists, it will be overwritten

Categories