I need to create and read a user preferences XML file with Adobe Air. It will contain around 30 nodes.
<id>18981</id>
<firstrun>false</firstrun>
<background>green</background>
<username>stacker</username>
...
What's a good method to do this?
Write up an "XML parser" that reads the values and is aware of the data types to convert to based on the "save preferences model." So basically you write a method/class for writing the data from the "save preferences model" to XML then write a method/class for reading from the XML into the "save preferences model", you can use describeType for both. Describe type will return an XML description of the model classes properties and the types of those properties and accessibility (read/write, readonly, write only). For all properties that are read/write you would store them into the XML output, when reading them back in you would do the same thing except you could use the type property from the describeType output to determine if you need to do a string to boolean conversion (if(boolValue == "true")) and string to number conversions, parseInt or parseFloat. You could ultimately store the XML in a local SQL database if you want to keep history, or else just store the current preferences in flat file (using FileReference, or in AIR you can use FileStream to write directly to a location).
Edit:
Agree with Joshua's comment below local shared objects was the first thing I thought of when seeing this, you can eliminate the need to write the XML parser/reader since it will handle serializing/de-serializing the objects for you (but manually looking at the LSO is probably ugly)... anyhow I had done something similar for another project of mine, I tried stripping out the relevant code, to note in my example here I didn't use describe type but the general concept is the same:
http://shaunhusain.com/OnePageSaverLoader/index.php
Related
I want to make some basic math stuff like Sum in Diagrams.net (old Draw.io).Is it possible ?
Exemple : I create a new parameter on a shape, like "Elec : T16" and make several copy on this shape. Is it possible to have a Text which can give me the total of the shape with this parameter ?
Best Regards.
I search a lot in the Diagrams.net blog but anything relevent.
This is not supported.
Regards,
I also wanted to do something similar and while it doesn't seem possible to do it completely in the software (as of v20.3.0), I did find a bit of a workaround: If you add properties to the shape data, then do File > Export As > XML, the properties will be there in the XML data. You can then count them one of two ways:
Open the XML file with a text editor like Notepad++, do a find on the value you want to count. If you choose "Find All" it will tell you how many times it appears.
Use a programming language like Python to read through the file and count the instances of that value.
Example:
I created a red circle in a new diagram, edited the text to say "RedCircle" and used Edit Data to add a property called TestValue, to which I assigned a value of 1. When I exported to XML it contained this element:
<object label="RedCircle" TestValue="1" id="6byQ5fOap-RXn7mFit_J-1">
Notes
When you export, make sure you turn off the Compressed option, this will create an unusable file.
Don't use Save As > XML, this will also use compression.
Diagrams.net natively saves in a compressed XML format, with only slight differences between that and the other compressed XML options, but it seems happy to also read in the exported uncompressed XML. I didn't test but if you go the programming route and want to take it a step further, it seems you could have the program update the value of a given "counter" element with the count, then open the XML file in diagrams.net to see the updated value and save it as a native .drawio file or publish in whatever format you like.
Edit: I discovered that under File > Properties you can turn off the compression on the actual .drawio file. If you do that you can just work from this file instead of exporting, but you might want to check the size of your file with and without it.
I'm sure a plugin could be created to do all of that within the app itself, but the other methods are enough for me at this point.
Hope this helps you!
I need a snippet to check file for validity (I'm allowing users to upload xml files). So I need to check whether uploaded file is XML.
The best I can think of is just check if extension is ".xml". What if its replaced?
You can try loading it like this and catch the exception:
XDocument xdoc = XDocument.Load("data.xml"));
Presumably, if they're uploading XML, then you're going to use it for something afterwards. In this case you should validate the XML against a Schema (XSD etc) so that you know you aren't going to hit unexpected values/layouts etc.
In Urlmon.dll, there's a function called FindMimeFromData.
From the documentation
MIME type detection, or "data
sniffing," refers to the process of
determining an appropriate MIME type
from binary data. The final result
depends on a combination of
server-supplied MIME type headers,
file extension, and/or the data
itself. Usually, only the first 256
bytes of data are significant.
So, read the first (up to) 256 bytes from the file and pass it to FindMimeFromData.
If you must validate the xml (assuming you want to validate the entire thing) you can use the XmlDocument class and catch an exception if it's not XML.
I am using file upload mechanism to upload file for an employee and converting it into byte[] and passing it to varBinary(Max) to store into database.
Now I what I have to do is, if any file is already uploaded for employee, simply read it from table and show file name. I have only one column to store a file and which is of type VarBinary.
Is it possible to get all file information from VarBinary field?
Any other way around, please let me know.
If you're not storing the filename, you can't retrieve it.
(Unless the file itself contains its filename in which case you'd need to parse the blob's contents.)
If the name of the file (and any other data about the file that's not part of the file's byte data) needs to be used later, then you need to save that data as well. I'd recommend adding a column for the file name, perhaps one for its type (mime type or something like that for properly sending it back to the client's browser, etc.) and maybe even one for size so you don't have to calculate that on the fly for each file (useful when displaying a grid of files and not wanting to touch the large blob field in the query that populates the grid).
Try to stay away from using the file name for system-internal identity purposes. It's fine for allowing the users to search for a file by name, select it, etc. But when actually making the request to the server to display the file it's better to use a simple integer primary key from the table to actually identify it. (On a side note, it's probably a good idea to put a unique constraint on the file name column.)
If you also need help displaying the file to the user, you'll probably want to take the approach that's tried and true for displaying images from a database. Basically it involves having a resource (generally an .aspx page, but could just as well be an HttpHandler instead) which accepts the file ID as a query string parameter and outputs the file.
This resource would have no UI (remove everything from the .aspx except the Page directive) and would manually manipulate the response headers (this is where you'd set the content type from the file's type), write the byte stream to the client, and end the response. From the client's perspective, something like ~/MyContent/MyFile.aspx?fileID=123 would be the file. (You can suggest a file name to the browser for saving purposes in the response headers, which you'd probably want to do with the file's stored name.)
There's no shortage of quick tutorials (some several years old, it's been around for a while) on how to do this with images. Just remember that there's essentially no difference from the server's perspective if it's an image or any other kind of file. All the server needs to do is send the type in the response headers and write the file's bytes to the client. How the client handles the file is up to the browser. In the vast majority of cases, the browser will know what to do (display an image, display via a plugin a PDF, save a .doc, etc.).
I am working on an iPad app that is fed data via web service returning JSON. Watching some iTunes U episodes, it looks like sending back Plist would save me a ton of time and speed up my app quite a bit on the parsing side of things.
Does anyone know of a .net library that converts objects into this Plist to return instead?
EDIT (this is my very limited understanding of this topic):
An Plist is a Property List that iOS can use to easily encode and/or parse data. It is very similar to JSON except parsing takes a fraction of the time and can be done in 1 line of code. If your server uses WebObjects then encoding can also be done in 1 line of code, I am using IIS so I need a solution for this if one exists before I write my own.
You can see the videos here:
http://developer.apple.com/videos/wwdc/2010/
In particular watch Session 117 - Building a Server-Driven User Experience
You may checkout this project. Sample usage:
object value = ...
string plist = Plist.PlistDocument.CreateDocument(value);
The only requirement is to decorate your object with [Serializable] attribute.
If you're using WebObjects, the appserver from apple, there's a java mirror class of NSPropertyListSerialization that does all of this for you; you can pass it NSArray's, NSDictionaries, etc and it will just work. Not sure if that's what you're talking about; confused as to the WebObjects in your question. HTH's.
I am going to add file upload control to my ASP.NET 2.0 web page so that users can upload files. Files will be stored in the server in the folder with the name as of the user. I want to know what is the best option to name the files when saving to server. Needs to consider security, performance, flexibility to handle files etc.
Options I am considering now :
Upload with the same name as of the input file name
Add User Id+Random Number +File name as of the input file name
Create random numbers +Current Time in seconds and save files with that number. Will have one table to map this number with users upload
Anything else? What is the best way?
NEVER EVER use user input for filenames. Don't use the username. User the user id instead (I assume your users have an unique id).
NEVER use the original filename. Use your solution number 3, plus the user id instead of the username.
For your information, PHP had a vulnerability a few years ago: one could forge a HTTP POST request with a file upload, and with a file name like "../../anything.php", and the php _FILES array, supposed to contain sanitized values, didn't detect these kind of file names, so one could write files anywhere in the filesystem.
I'd use a combination of
User ID
A random generated string (e.g. a GUID)
Example PDF file name: 23212-dd503cf8-a548-4584-a0a3-39dc8be618df.pdf
This way, the user can upload as many files as he/she wants, without file name conflict, and you are also able to point out which files belong to which users, just by looking at the file names.
I don't see the need to include any other information in the file name, since upload time/date and such can be retrieved from the file's attributes.
Also, you should store the files in a safe location, which external users, such as visitors of your website, cannot access. Instead, you deliver the file to them through a proxy web page (you read the file from the safe location, and pass the data on to the user). For this solution, a database is needed to keep track of files, their location, etc.
This also makes you able to control which users have access to which files through your code.
Update: Here's a description of how the solution with the proxy web page could be implemented.
Create a Web Form with the name GetFile.aspx
GetFile.aspx takes one query parameter named fileid, which is used to identify the file to get. E.g.: http://www.mypage.com/GetFile.aspx?fileid=100
Use the fileid parameter to lookup the file location in the database, so that it can be read and sent to the user. In the Web Form you use Request.QueryString("fileid") to get the file ID and use it in a query that will look something like this (SQL): SELECT FileLocation FROM UserFiles WHERE FileID = 100
Read the file using a System.IO.FileStream and output its contents through Response.Write. Remember to set the appropriate content type using Response.ContentType first, so that the client browser handles the requested file correctly (see this post on asp.forums.net and the MDSN article which is also referred to in the post, which both discuss a method of determining the appropriate content type automatically).
If you choose this approach, it's easy to implement your own simple security or custom actions later on, such as making sure a user is logged into your web site before you send the file, or that users can only access files they uploaded themselves, or logging which users download which files, etc. The possibilities are endless ;-)
Take a look at the System.IO.Path class as it has lots of useful functions you can utilise, such as:
Check which characters are invalid in a file name:
System.IO.Path.GetInvalidPathChars();
Get a random file name:
System.IO.Path.GetRandomFileName();
Get a unique, randome filename in the temporary directory
System.IO.Path.GetTempFileName();
I would go with option #3. A table mapping these files with users will provide other uses down the road, it always does. If you use the mapping, the only advantage of appending the user name or id to the file is if you are trying to debug a problem.
I'd probably use a GUID instead of a random number but either would work. The important things in my opinion are
No username as part of the filename as any part of the stored file
Never use the original file name as any part of the stored file
Use a random number or GUID to ensure no duplicate file
Adding an user id to the file will help with manual debugging issues
There is more to this than meets the eye...which I am thinking that you already knew!
What sort of files are you talking about? If they are anything even remotely big or in such quantity that the group of files could be big I would immediately suggest that you add some flexibility to your approach.
create a table that stores the root paths to various file stores (this could be drives, unc paths, what ever your environment supports). It will initially have one entry in it which will be your first storage location. An nice attribute to maintain with this data is how much room can be stored here.
maintain a table of file related data (id {guid}, create date, foreign key to path data, file size)
write the file to a root that still has room on it (query all file sizes stored in a root location and compare to that roots capacity)
write the file using a GUID for the name (obfuscates the file on the file system)..can be written without the file extension if security requires it (sensitive files)
write the file according to its create date starting from the root/year{number}/month{number}/day{number}/file.extension
With a system of this nature in place - even though you won't/don't need it up front - you can now more easily relocate the files. You can better manage the files. You can better manage collections of files. Etc. I have used this system before and found it to be quite flexible. Dealing with files that are stored to a file system but managed from a database can get a bit out of control once the file store becomes so large and things need to get moved around a bit. Also, at least in the case of windows...storing zillions of files in one directory is usually not a good idea (the reason for breaking things up by their create date).
This complexity is only really needed when you have high volumes and large foot prints.