How to write a kml file to publicly accessible server? - c#

I want to render a KML file in google maps from my asp.net MVC 3 app.
From Google Maps JavaScript API V3, I'm using KmlLayer('url') to render the kml in google maps.
I have read that kml file needs to be in a publicly accessible server. I could render the kml file locally with third party javascripts but they can be prone to errors.
(Loading a local .kml file using google maps?)
The kml files I want to render are stored in a SQL server database as byte arrays. So for one Kml file I have to write the byte array into a path with kml extension. I have done this with File.WriteAllBytes(path, byte), where path = local path and byte = byte array from Database. THis is done in the Controller of MVC app.
This is the code:
public ActionResult MapView(int id)
{
Incident inc = db.Incidents.Find(id);
if (inc.IncidentDatas.Count != 0)
{
ViewBag.ListKmlUrls = kmlFileStore(inc);
}
return View(inc);
}
public List<string> kmlFileStore(Incident inc)
{
List<string> listKmlUrls = new List<string>();
// Specify a "currently active folder"
string activeDir = #"c:\incident" + inc.incId + #"\incidentData";
//Create a new subfolder under the current active folder
string newPath = System.IO.Path.Combine(activeDir, "kmlFiles");
// Create the subfolder
System.IO.Directory.CreateDirectory(newPath);
String url;
foreach(var d in inc.IncidentDatas) {
url = #"c:\incident" + inc.incId + #"\incidentData\kmlFiles\" + d.id + ".kml";
//dataContent is byte[]
System.IO.File.WriteAllBytes(url, d.dataContent);
listKmlUrls.Add(url);
}
return listKmlUrls;
}
The idea is the view will access the list of urls through viewbag to pass urls to javascript method KmlLayer(...). But the urls here are only local paths.
So how can the MVC app store the kml file to a publicly accessible server so that it can pass a url to KmlLayer(...)? This would have to be done programmatically.
I'm currently accessing my MVC app and database from localhost. I have a static Ip and name. I would also like to publish the app and database for online access. Not sure how to proceed, please give me some advice/guidance. Thanks.

There are some problem to make kml file publicly accessible. Say the file location must be accessible by google.
If you want to embed Google Earth in website then there are three methods of importing KML into the plugin.
1. KmlNetworkLink
2. fetchKml
3. ParseKml
Both 1 & 2 need kml file stored in server that must publicly accessible but 3. ParseKml works better way.
<head>
<title>parsekml_example.html</title>
<script src="//www.google.com/jsapi?key=ABQIAAAA5El50zA4PeDTEMlv-sXFfRSsTL4WIgxhMZ0ZK_kHjwHeQuOD4xTdBhxbkZWuzyYTVeclkwYHpb17ZQ"></script>
<script type="text/javascript">
var ge;
var placemark;
var object;
google.load("earth", "1");
function init() {
google.earth.createInstance('map3d', initCB, failureCB);
}
function initCB(instance) {
ge = instance;
ge.getWindow().setVisibility(true);
var kmlString = ''
+ '<?xml version="1.0" encoding="UTF-8"?>'
+ '<kml xmlns="http://www.opengis.net/kml/2.2">'
+ '<Document>'
+ ' <Camera>'
+ ' <longitude>-122.444633</longitude>'
+ ' <latitude>37.801899</latitude>'
+ ' <altitude>139.629438</altitude>'
+ ' <heading>-70.0</heading>'
+ ' <tilt>75</tilt>'
+ ' </Camera>'
+ ' <Placemark>'
+ ' <name>Placemark from KML string</name>'
+ ' <Point>'
+ ' <coordinates>-122.448425,37.802907,0</coordinates>'
+ ' </Point>'
+ ' </Placemark>'
+ '</Document>'
+ '</kml>';
var kmlObject = ge.parseKml(kmlString);
ge.getFeatures().appendChild(kmlObject);
ge.getView().setAbstractView(kmlObject.getAbstractView());
}
function failureCB(errorCode) {
}
google.setOnLoadCallback(init);
</script>
</head>
<body>
<div id="map3d" style="height: 400px; width: 600px;">
</div>
</body>
For more detail see http://code.google.com/apis/earth/documentation/kml.html

Related

Trusted Scripts Setting in Windows Registry or IE

I am creating a directory of files for an internal website. The user will access the page and insert the location and filename and submit the information to a database. I tried using file upload to open Windows Explorer so the user can locate the file and path. However, asp file upload will not allow me to capture the path on the client side. Since this is an internal website, does Internet Explorer or Windows Registry have a permissions setting for trusted scripts similar to trusted sites?
I created a JQuery Script to copy the the path to a textbox but I get a error message saying "C:\fakepath\test.pdf". test.pdf is the filename but c:\fakepath is not the path. I have tried multiple server variables but those just tell the paths on the server end.
<script>
$(document).ready(function(){
$("#button").click(function(){
$("#text1").val($("#text").val());
});
});
</script>
<input type="file" id="text" />
<input type="text" id="text1" />
<input type="button" value="Click Me!" id="button" />
To access the local path you need to use ActiveX object in your web page. It can help you to get the path in IE.
For working with Files and directory you should make a server object as Scripting.FileSystemObject then with GetDirectory() method can get a directory object.
Sample code:
var Fo =new ActiveXObject("Scripting.FileSystemObject");
var StrOut = new String();
var FileName = new String();
var Extention = new String();
function FindFile(FOo)
{
var FSo = new Enumerator(FOo.Files);
for(i=0;!FSo.atEnd();FSo.moveNext())
{
if(FileName == "*" || FSo.item().name.slice(0,FSo.item().name.lastIndexOf(".")).toLowerCase().indexOf(FileName)>-1)
if(Extention == "*" || FSo.item().name.slice(FSo.item().name.lastIndexOf(".")+1).toLowerCase().indexOf(Extention)>-1){
StrOut += "<tr "+ ((i%2)? "":"bgcolor=#DDAA55") +"><td width=50%><font class=find>" + FSo.item().path + "</font></td><td width=25%><font class=find>" + FSo.item().type + "</font></td><td width=50%><font class=find>"+ String(FSo.item().size/(1024*1024)).slice(0,3) +" MB</font></td></tr>";
i++
}
}
}
function Scan()
{
FileName = (search.value.lastIndexOf(".")>-1)? search.value.slice(0,search.value.lastIndexOf(".")):(search.value.length>0)? search.value.toLowerCase():"*"; //Get Searched File Name
Extention = (search.value.lastIndexOf(".")>-1)? search.value.slice(search.value.lastIndexOf(".")+1).toLowerCase():"*"; // Get Searched File Extention Name
if(path.value.length>0 && Fo.FolderExists(path.value)){
StrOut = "<table border=0 width=100% cellspacing=0>"
FindFile(Fo.GetFolder(path.value));
outPut.innerHTML = StrOut+"</table>";
}
else alert("Insert Correct Path Address");
}
For detailed information and example code, You can refer link below and download the sample file.
Find files with JavaScript

Create folders and upload text files to server (php) in Unity3D (C#)

What I have :
I have a simple module that would convert a string to a text file & store it in my server
C#/Unity Code
private IEnumerator UploadUserData(string _fileName)
{
string _data = ("With text name " + System.DateTime.Now.ToString ());
string _postDataURL = "https://nameofserver.com/upload.php"
WWWForm _form = new WWWForm ();
_form.AddField ("name", _fileName);
_form.AddField ("data", _data);
UnityWebRequest _wwwRequest = UnityWebRequest.Post (_postDataURL, _form);
yield return _wwwRequest.Send ();
while (!_wwwRequest.isDone)
{ yield return null;}
if (_wwwRequest.error != null)
{
Debug.Log (_wwwRequest.error);
}
else
{
Debug.Log ("Uploaded");
}
Debug.Log (_wwwRequest.downloadHandler.text);
}
Server Side PHP
<?php
if(isset($_POST['name']) && isset($_POST['data'])){
file_put_contents($_POST['name'].".txt", $_POST['data']);
echo "uploaded.";
}else{
echo "invalid file uploaded.";
}
?>
Request
I want to build a system where I could upload files to specific folders. Let's say I to upload a text file (filename.txt) to a folder name "Folder1".
From php side
The php side should create a folder "Folder1" if it is not present
then upload the text file "filename.txt" to that folder
if "Folder1" exist in that directory, then I would like the php
script to upload that text file "filename.txt" to the existing folder
"Folder1"
From Unity Side
How should I mention the folder name from Unity webrequest?
Thank you very much for your time. Much appreciate it.
Like I was ranting at you on IRC, you should avoid allowing your file paths to be dictated by, or even include, data supplied by a user or even a user-accessible API.
I would suggest something along the lines of:
// always have something define the absolute path to your application root,
// then build your paths/filenames relative to that.
// let's say this is /usr/local/myapp/config/config.php
define('APPROOT', realpath(__DIR__ . '/..')); // APPROOT == '/usr/local/myapp'
define('USERUPLOADS', APPROOT . '/user_uploads');
// userid SHOULD be something you control, not a username or anything specified
// by the user. the focus is to prevent malformed and/or malevolent user data
// from breaking out of the upload directory sandbox.
function acceptUploadedUserData($userid, $name, $data) {
$userdir = USERUPLOADS . '/' . $userid;
if( ! is_dir($userdir) ) {
mkdir($userdir);
}
// just kinda baseline "OK"
if( strpos('..', $name) !== false || strpos('/', $name) !== false ) {
throw new Exception('Specified name cannot contain .. or /');
}
file_put_contents($userdir . '/' . $name, $data);
// better yet don't let the user have *any* control over any part of the path
// but also allows you to specify *any* string as the filename.
file_put_contents($userdir . '/' . md5($name), $data);
}
acceptUploadedUserData($_SESSION['user_id'], $_POST['name'], $_POST['data']);

URL absolute path not working with Linq To Excel on server. c#

I'm using Linq to Excel library for reading excel tables. Until now, it was working good locally, the method ExcelQueryFactory gets the route of the excel by this way:
var book = new ExcelQueryFactory(#"C:\data.xls");
Now, I would like to use it online on a Rest Api, the POST used for uploading the Excel to the web api is the following:
[HttpPost]
[Route("Upload")]
public Task<HttpResponseMessage> UploadFile() {
List<string> savedFilePath = new List<string>();
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string rootPath = HttpContext.Current.Server.MapPath("~/UploadedFiles");
var provider = new MultipartFileStreamProvider(rootPath);
var task = Request.Content.ReadAsMultipartAsync(provider).
ContinueWith<HttpResponseMessage>(t =>
{
if (t.IsCanceled || t.IsFaulted)
{
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
}
foreach (MultipartFileData item in provider.FileData)
{
try
{
string name = item.Headers.ContentDisposition.FileName.Replace("\"", "");
string newFileName = Guid.NewGuid() + Path.GetExtension(name);
Debug.WriteLine(item.LocalFileName);
File.Move(item.LocalFileName, Path.Combine(rootPath, newFileName));
Uri baseuri = new Uri(Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.PathAndQuery, string.Empty));
//RELATIVE PATH
string fileRelativePath = "~/UploadedFiles/" + newFileName;
//LeerExcel(fileRelativePath);
//ABSOLUTE PATH
Uri fileFullPath = new Uri(baseuri, VirtualPathUtility.ToAbsolute(fileRelativePath));
savedFilePath.Add(fileFullPath.ToString());
//LeerExcel(savedFilePath[0]);
}
catch (Exception ex)
{
string message = ex.Message;
}
}
// string rutaFin = "~" + savedFilePath[0];
// string rest = rutaFin.Replace("http://localhost:56618", "");
// LeerExcel(rest);
return Request.CreateResponse(HttpStatusCode.Created, savedFilePath);
});
return task;
}
So, by choosing the excel manually, neither the absolute path or relative path on the server work for the ExcelQueryFactory string route.
The routes get by this method are the following:
ABSOLUTE:
http://localhost:56618/UploadedFiles/9a27e785-e486-4807-8a80-7abb9b940d8b.xls
And the relative:
/UploadedFiles/9a27e785-e486-4807-8a80-7abb9b940d8b.xls
Is possible to use by the way I want to? During the server is online, the obtained absolute path is accesible, so if I access to that URL, the file is downloaded.
the problem is solved:
As I said, I thought only this library worked locally, but it wasn't.
Since Microsoft has launched a new big update, many people have notice some problems when using Database engine, “Unexpected error from external database driver (1). (Microsoft JET Database Engine)” after applying October security updates.
First, I created a Fake.txt file on /UploadedFiles, folder that is located on the project repository and I give it permission to be always copied, as follows:
Fake.txt properties
With this file, I´m achieving that UploadedFiles folder is copied every time I run the server.
Next step:
Due to Microsoft big update, the recomendation is to "download and install the Microsoft Access Database Engine 2010 Redistributable, and then modify the DB connection strings in Microsoft Excel to use ACE as a provider. Example: Change Provider=Microsoft.Jet.OLEDB.4.0 to Provider=Microsoft.ACE.OLEDB.12.0."
I only have downloaded and install that file, but during this day, 3 new windows updates were installed, so, I dont know if this 3 updates are related with the solution of this problem.
The updates are:
Update 1
Update 2
Update 3
After installing the 2010 database engine version file, I changed the excel extension from .xls to .xlsx and now all work.

How to find where my data files and log files stored using smo in c#

Can anybody please tell me how to find the location where my data and log files stored using SMO in c#?
public static void foo() {
Microsoft.SqlServer.Management.Smo.Server server = new ServerConnection("<server name>");
Microsoft.SqlServer.Management.Smo.Database db = server.Databases["<database name>"];
Console.WriteLine(db.FileGroups[0].Files[0].FileName);
Console.WriteLine(db.LogFiles[0].FileName);
}
This example assumes you have sufficient rights to the Server\Database, and only returns the full path\filename for the first db/log file in the filegroup.
FileGroups, Files, and LogFiles are SMO collections that will contain one or more of it's respective items.
apparently you can "get the names of the logical data and log files from the FileGroups and the Files collections."
see link text
$targetServerName = "localhost"
$targetDatabaseName = "dbname"
$targetServer = New-Object ("Microsoft.SqlServer.Management.Smo.Server")$targetServerName
$database = $targetServer.Databases[$targetDatabaseName]
foreach ($fg in $database.FileGroups)
{
foreach ($df in $fg.Files)
{
"Filegroup type : " + $fg.Name + " DataFiles : " + $df.FileName
}
}
foreach ($lf in $database.LogFiles)
{
"Log file : " + $lf.FileName
}
That should get you the exact paths.

C# WebBrowser HTML with references to scripts and images

I'm writing a C# app using the WebBrowser control, and I want all content I display to come from embedded resources - not static local files, and not remote files.
Setting the initial text of the control to an embedded HTML file works great with this code inspired by this post:
browser.DocumentText=loadResourceText("myapp.index.html");
private string loadResourceText(string name)
{
Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream(name);
StreamReader streamReader = new StreamReader(stream);
String myText = streamReader.ReadToEnd();
return myText;
}
As good as that is, files referred to in the HTML - javascript, images like <img src="whatever.png"/> etc, don't work. I found similar questions here and here, but neither is asking exactly what I mean, namely referring to embedded resources in the exe, not files.
I tried res://... and using a <base href='..." but neither seemed to work (though I may have not got it right).
Perhaps (following my own suggestion on this question), using a little embedded C# webserver is the only way... but I would have thought there is some trick to get this going?
Thanks!
I can see three ways to get this going:
1: write the files you need to flat files in the temp area, navigate the WebBrowser to the html file, and delete them once the page has loaded
2: as you say, an embedded web-server - herhaps HttpListener - but note that this uses HTTP.SYS, and so requires admin priveleges (or you need to pre-open the port)
3: like 1, but using named-pipe server to avoid writing a file
I have to say, the first is a lot simpler and requires zero configuration.
/// Hi try this may help u.
private string CheckImages(ExtendedWebBrowser browser)
{
StringBuilder builderHTML = new StringBuilder(browser.Document.Body.Parent.OuterHtml);
ProcessURLS(browser, builderHTML, "img", "src");
ProcessURLS(browser, builderHTML, "link", "href");
// ext...
return builderHTML.ToString();
}
private static void ProcessURLS(ExtendedWebBrowser browser, StringBuilder builderHTML, string strLink, string strHref)
{
for (int k = 0; k < browser.Document.Body.Parent.GetElementsByTagName(strLink).Count; k++)
{
string strURL = browser.Document.Body.Parent.GetElementsByTagName(strLink)[k].GetAttribute(strHref);
string strOuterHTML = browser.Document.Body.Parent.GetElementsByTagName(strLink)[k].OuterHtml;
string[] strlist = strOuterHTML.Split(new string[] { " " }, StringSplitOptions.None);
StringBuilder builder = new StringBuilder();
for (int p = 0; p < strlist.Length; p++)
{
if (strlist[p].StartsWith(strHref))
builder.Append (strlist[p].Contains("http")? strlist[p] + " ":
(strURL.StartsWith("http") ? strHref + "=" + strURL + " ":
strHref + "= " + "http://xyz.com" + strURL + " " ));
else
builder.Append(strlist[p] + " ");
}
builderHTML.Replace(strOuterHTML, builder.ToString());
}
}

Categories

Resources