How to save and read a xml file from another website? - c#

I have this link: http://www.bnro.ro/nbrfxrates.xml to an xml file with daily Currency.
I want to save this xml in folder of my website ex. (~/Content/CurrencyXml).
I want to save it every day, first time when a user is accessing my website (must replace the old file).
I want also to read it in a static method which return an object with each currency type like property, in order to access it something like this:
price=model.Eur * 100;
Can you help me with an example of how to save a copy of this xml and how to read it?

You can try something like this to read the file and save it
public void readFile()
{
XmlDocument document = new XmlDocument();
document.Load("http://www.bnro.ro/nbrfxrates.xml");
document.Save(Path.Combine(
Server.MapPath("~/Content/CurrencyXml"),"myFile.xml"));
}
and in here you can find very usefull information:
XmlDocument Microsoft

Here's an example for the windows service:
Walkthrough: Creating a Windows Service Application in the Component Designer
Here's an example on how to download xml using WebClient:
How can I download an XML file using C#?
Here's an example on how to save a file to your server:
C# save files to folder on server instead of local
Then use what #Augustin suggested.
If you do use the flag file scenario, I would advice to save the xml file to a temporary file and only when fully downloaded, overwrite your original one and make sure to handle locking, overwriting time, etc... One other solution would be to use a temp variable that holds the current filename and when you download a new file, just give it a new name and when downloaded, set that variable name to the new filename and make sure that your load function uses that variable and loads the data from the new filename. Don't forget to delete your old file(s), but at least it will avoid locking issues if any and you can always try to delete the file later again.
If will very much depend if your website if being access 24/7 or not. If it isn't it is less of an issue as you could use the windows service to download this file when you know it's not being used. If you use the windows service, while being used, same as above would apply. If you're using Azure, you could use a WebJob. I'm sure there are many different solutions to handle this and you just have to find the one that will meet your needs.

Related

Filesystem Hook for .doc open C#

I'm writing an application that needs to be notified of every doc file that is opened, I've tried using the FileSystemWatcher but it seems that these days NotifyFilter.LastAccess is disabled due to a large overhead.
There is LastWrite which I suppose I could use but it would mean I'd need to try and figure out the original file name from the temporary file that word creates when it opens a document.
I also need to keep watch on 4 directories so ideally I don't want to be polling them.
I'm aware I could write a WordAddin which is one option but that means another deployment to manage, another codebase and another product to support along with the problem that many users always see addins as a source of slowdowns.
Is there a straightforward way to tell windows Vista upward that I want to know about doc or docx that is opened?
One thing I was wondering about is if I could alter the default program associated with .doc to mine, which is running as a service and then passing the details through it to mine to be opened? This seems like a bit of a hack so I was wondering if there was an easy way to hook into these sorts of file open?
UPDATE
From talking it through with various people here the most reliable way(and most resource effective) would seem to be to replace the existing file association for .doc. & .docx to my own program and then use Microsoft.Office.Interop.Word to launch word and then hook into the DocumentOpen event.
That way I get the file name thats being opened along with any future documents that are open in word.
If I recall correctly, the temporary file that is created in the same folder has the file name format of ~$ + filename, for example:
~$very_important_file.doc
It contains the name of the user that opened the file. Note that the file has the hidden attribute set.
This makes it quite easy to figure out which document is actually open and by whom.
Such tasks are usually accomplished using filesystem filter drivers. Procmon works this way. You can create your own filter driver or use the precreated one (eg. our CallbackFilter).

Update file, not replace or overwrite

this is more of a question because I am experimenting with this.
All over the internet I see how you can update a .txt file. Well that is all good and well, but lets say I have a .doxc or even an .exe or even a .dll file.
If we make a minor change to a file, do we really have to replace(overwrite) the whole file?
Is it possible to "update" the file so that we don't use too mush data (over the internet).
What I am trying to achieve is to create a FTP client with a FileSystemWatcher. This will monitor a certain folder on the Computer. If anything changes in this folder (even sub directories) then it uploads, deletes, renames, or changes the file. But at the moment I am wondering if I have, lets say, a 20MB .exe file or whatever, if it is possible to change something in that .exe, instead of just overwriting the whole thing... thus, sparing some cap.
In general, it's possible to update the remote file only partially, but not in your case.
What would work:
1) track the file change using a filesystem filter driver, which gives you information about what parts of the file have been updated.
2) use the protocol which allows partial upload or remote modification of the file (eg. SFTP).
As for your scenario:
Step 1 is not possible with FileSystemWatcher.
Step 2 is not possible with FTP protocol which doesn't support modification of file blocks.
Since your are experimenting, I can provide some pointers. But I dont know for sure if the below operations are just updates or replaced newly by the underlysing os calls
Have different cases for each file type. Try with a basic types first, a txt file, then a binary file etc.
You should have the entire copy of the current file somewhere, sine you "should" compare the old file to know what changes
Then when a change is made to the file compare it with the old file e.g) in a text file with 1 MB and the change is only 1 KB you will need to build a format like
[Text][Offset][[operation]
e.g) [Mrs.Y][40][Delete] then [Mr.X][40][Add]
Then your ftp client should be able to implement this format and make changes to the local copy on the client.
No it is not possible to only upload the changes to .exe file.we have to overwrite it.
#Frederik - It would be possible if FTP supports an updating of resource like HTTP's PUT command. Try exploring that angle. Let us know if you find something.

Why isn't my XML file being saved, even though the program sees the updated values next time I start it?

I'm reading the contents of an XML file and parsing that into an object model.
When I modify the values in the object model, then use the following code to save it back to the xml:
XElement optionXml = _panelElement.Elements("options").FirstOrDefault();
optionXml.SetAttributeValue("arming", value.ToString());
_document.Save(_fileName);
This works, as far as I can see, because when I close the application and restart it the values that I had saved are reflected in the object model next time I view it.
However, when I load the actual XML file, the values are still as they were originally.
Why is this? What do I need to do to save the actual XML file with the new values?
You are most likely experiencing file system virtualisation, which was introduced in Windows Vista.
Basically what this means is that you are saving your file, just not where you think you're saving it. For example, you might think that you are saving to C:\Program Files\Your App\yourFile.xml, but what is happening under the hood is that the OS is silently redirecting that to %APPDATA%\Your App\yourFile.xml. When you go to reload it, once again the OS silently redirects from that location.
This is a security measure designed to better encapsulate applications and their data and to prevent unauthorised writes to locations where damage can occur. You can still force a save to %PROGRAMFILES%\Your App, but to do that you either need to relax the ACLs applied to that folder, or you need to elevate the privilege level your application runs at.
I wasn't sure whether to put this as a comment or as an answer, but I think it could be a potential answer. It sounds like the XML file is being saved because the data is being persisted across instances of the application. It may be file system virtualization like slugster mentioned, but it might be a simple as the fact that you are looking at the wrong copy of the XML file. If you are using a relative path, the file may have been copied to the new location. I would suggest you do a quick file search for that file name and see what you get back.
It turns out the file was being copied to and read from the Output Directory. I can see that it's being updated as expected from there.

C# file path mimic via database

Here is a challenge for you - .NET C# 4.0 or below.
I have a basic C# application which has a single button on a form.
The button uses an API which takes a file path as a parameter for the location of an audio file.
The API then allows the calling of the file e.g. someoneElsesAPI.Play("C:\myfile.vox") to play the file.
I do not have control over the API. I have to use the API - no choice there.
The problem is, the audio file (.vox) is stored in a database (as a blob).
How do I supply a file name to the API yet provide something that is streamed from the database in order to play the file?
For example, in ASP.NET one can display an image dynamically by using a handler or aspx page and response outputting as an image. I want to do the same trick for an audio file in a C# desktop application.
The type of audio file is irrelevant - I need to know how to call a file via a file path which doesn't exist (but does exist as a blob in a database).
hehe I don't ask for much do I?
Mucho thanks.
Best of luck in this challenge!
Dan.
I don't think that it can be done in any reasonable way. Instead you could easily fetch the blob. Save it to a temporary file and give the path of the temporary file to the API. It will not provide any kind of streaming, but as you can probably imagine, overriding the way .net handles the file system is not something that can easily be done. And why would you? If this is a real problem for you, I would recommend changing the API you use to another one that supports what you are trying to achieve instead of looking for hacky solutions.
Read the blob from the database, store the file into a temporary file, then pass the temp file name into the api
Depending on how the API opens files, you might be able to use a NamedPipe as a "virtual file".
This command line example creates a named pipe called hello.txt, and writes some "data" to it.
using System;
using System.IO;
using System.IO.Pipes;
namespace TestNamedPipe
{
class Program
{
static void Main(string[] args)
{
using (var pipe = new NamedPipeServerStream("hello.txt"))
{
pipe.WaitForConnection();
using (var writer = new StreamWriter(pipe))
{
writer.WriteLine("Hello, World!");
}
}
}
}
}
Now you can run "type \\.\pipe\hello.txt" from a command prompt to see how the pipe can be read by some apps as though it were a file. The "file name" will always be "\\.\pipe\" followed by the pipe name.
This doesn't work for all apps or APIs, though. For example "sort.exe \\.\pipe\hello.txt" works, but "more.exe \\.\pipe\hello.txt" doesn't.

Advantages and usefulness of adding an XML file to a Visual Studio 2008 project

What is the advantage of adding XML files to a visual studio 2008 project (windows form app project for example).
Once added to the project, how could I refer to this XML to use it in a class in the same project? In this case, I would be sending it as a query to a web service.
If you want to use the XML in some form, you could mark it as a "embedded resource" in the properties window, and then access it from your code like so:
Assembly a = Assembly.GetExecutingAssembly();
if(a != null)
{
Stream s = a.GetManifestResourceStream(typeof(yourType), "YourXmlName.xml");
if (s != null)
{
String xmlContents = new StreamReader(s).ReadToEnd();
}
}
Once you're done, you have the XML file's contents in "xmlContents", if all goes well.
Marc
I guess the advantage of having your XML reside there in your project (or solution even) is that you can maintain it in VS with nice formatting and even intelli-sense, but then using something like XML Spy or whatever can give you that too.
To refer to it in a class you'll need to ensure you have access to it, and that it resides in a reliable place.
In the past I've used post build events to move the latest copy of the file to where I need it. As Arnshea writes here is another answer, "to the output directory". You can use the "Copy to Output directory" property on the XML file itself to achieve this. Then your classes can use the XML file, knowing it will reside in a reliable place.
You'll need to make sure it's accessible though especially if you're writing back to it. Make sure it doesn't end up "Read Only" - as Source Control system could do to you. Storing these files in a folder under Program Files could also be problematic especially on Vista, where user privileges are (should be) restricted.
If your app needs to load the XML it can be copied to the output directory. Also simplifies use of Setup/Deployment projects...
Another major advantage would be (assuming it's in place--and it should be!) is that you can apply revision control to the XML file.
I guess that you won't be sending the same XML file to the WebService over and over again.
You will want to modify its content every time for that you have XML Serialization.
If all of the above apply then you don't need the XML file, you just need the class that generates the file at runtime. The XML is just the transport, today its XML and tomorrow it might be some other format (JSON).

Categories

Resources