I'd like to upload shapefiles using GeoServer REST API and C#. So far, I can create workspaces using the REST API and C#. From GeoServer documentation (specific to cURL), the difference between creating a workspace and uploading a shapefile is in the HTTP Method (workspace creation uses POST
, shapefile uploading uses PUT
), ContentType (workspace creation uses application/xml
, shapefile uploading uses application/zip
), and finally there is the --data-binary
parameter in shapefile uploading.
The code I use for creating workspace is shown below.
How do I refactor this code so that I can use it to upload a shapefile?
String gUrl = "http://localhost:8081/geoserver/rest/workspaces";
WebRequest request = WebRequest.Create(gUrl);
request.ContentType = "text/xml";
request.Method = "POST";
request.Credentials = new NetworkCredential("geoServer-username", "password");
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes("<workspace><name>new_workspace_csharp_2</name></workspace>");
Stream requestStream = request.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Close();
WebResponse response = request.GetResponse();
Console.Write("Response from GeoServer: " + response);
I've managed to make some headway, and I can now upload a shapefile using C# and the GeoServer REST API. My refactoring effort, which now works, is shown below:
public bool UploadShapeFile(string workspace, string dsName, Uri zipUri)
{
String fileUri = zipUri.AbsolutePath;
Console.Write(fileUri);
byte[] localShapeFile = readLocalShapeFile(fileUri);
String sUrl = "http://localhost:8081/geoserver/rest/workspaces/cs_ws1/datastores/cs_ds1/file.shp";
WebRequest request = WebRequest.Create(sUrl);
request.ContentType = "application/zip";
request.Method = "PUT";
request.Credentials = new NetworkCredential("gs-username", "password");
// byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes(@fileUri);
Stream requestStream = request.GetRequestStream();
requestStream.Write(localShapeFile, 0, localShapeFile.Length);
requestStream.Close();
WebResponse response = request.GetResponse();
Console.Write("Response from GeoServer: " + response);
return false;
}
private byte[] readLocalShapeFile(string filePath)
{
byte[] buffer;
FileStream fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
try {
int length = (int)fStream.Length;
buffer = new byte[length];
int count;
int sum = 0;
// Read until Read method returns 0 - End of stream reached
while ((count = fStream.Read(buffer, sum, length - sum)) > 0)
sum += count;
}
finally {
fStream.Close();
}
return buffer;
}
However, I still believe there can be a more elegant way of doing this.