My xml file look like this:
<?xml version="1.0" encoding="utf-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>abcdefg </loc>
<lastmod>2017-12-10</lastmod>
</sitemap>
</sitemapindex>
After running my program for adding new node it look like this:
<?xml version="1.0" encoding="utf-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>laksdjfs </loc>
<lastmod> 453w43e5</lastmod>
</sitemap>
<sitemap xmlns="">
<loc>abcdefghoh_20170501181500715.xml</loc>
<lastmod>2017-05-01</lastmod>
</sitemap>
</sitemapindex>
The xmlns="" is added to the node - and I don't want to have it there. How can I remove it?
My Asp.Net Core 2.0 program look like this:
public void AddIndexFileToSiteMap(string IndexFileName)
{
string filenavn = GetSiteMapDir();
DateTime time = DateTime.Now;
string lastmoddate = time.Year.ToString("0000") + "-" + time.Month.ToString("00") + "-" + time.Day.ToString("00");
try
{
FileStream fileStream = new FileStream(filenavn, FileMode.Open);
XmlDocument doc = new XmlDocument();
doc.Load(fileStream);
// Create the child nodes. This code demonstrates various ways to add them.
XmlNode newElem = doc.CreateNode(XmlNodeType.Element,"sitemap", "");
newElem.InnerXml = "<loc></loc><lastmod></lastmod>";
newElem["loc"].InnerText = IndexFileName;
newElem["lastmod"].InnerText = lastmoddate;
newElem.Attributes.RemoveAll();
// 2. Add the new element to the end of the item list.
doc.DocumentElement.AppendChild(newElem);
fileStream.Position = 0;
doc.Save(fileStream);
fileStream.Flush();
}
catch
{
}
//doc.Save(fileStream);
}
Related
In my MVC application, I am using a dropzone control to allow users to upload a file from their local system to the SQL database.
if (Request.Files.Count > 0)
{
var name = Request.Files[0].FileName;
var size = Request.Files[0].ContentLength;
var type = Request.Files[0].ContentType;
var fileStream = Request.Files[0].InputStream;
byte[] documentBytes = new byte[fileStream.Length];
fileStream.Read(documentBytes, 0, documentBytes.Length);
Documents databaseDocument = new Documents
{
FileContent = documentBytes,
DocumentName = System.IO.Path.GetFileName(name),
DocumentSize = size,
DocumentType = type
};
bool result = this.updateService.SaveDocument(databaseDocument);
}
"updateService" is actually a reference to the WCF service.
I get the error on the "SaveDocument" call in above code.
I have set uploadReadAheadSize (in applicationHost.config), and maxReceivedMessageSize (in WCF and Web configuration files) as suggested on other forums.
Still this error is not resolving for me.
This gives an error saying "The remote server returned an error: (413) Request Entity Too Large "
You could use a stream as parameter to your service operation if you don't want to have issues with transmitting too large objects.
Service interface:
[ServiceContract]
public interface IStreamedService
{
[OperationContract]
void PrepareUpload(long fileLength, string fileName);
[OperationContract]
void UploadFile(Stream fileStream);
}
Service implementation:
public class StreamedService : IStreamedService
{
private static long lengthOfFile;
private static string nameOfFile;
public void PrepareUpload(long fileLength, string fileName)
{
lengthOfFile = fileLength;
nameOfFile = fileName;
}
public void UploadFile(Stream fileStream)
{
if(lengthOfFile==0 || string.IsNullOrEmpty(nameOfFile))
throw new ArgumentException("Upload must be prepared");
var bytes = new byte[lengthOfFile];
var numberOfBytesToRead = bytes.Length;
var numberOfReadBytes = 0;
while (numberOfBytesToRead > 0)
{
var n = fileStream.Read(bytes, numberOfReadBytes, numberOfBytesToRead);
if (n == 0)
break;
numberOfReadBytes += n;
numberOfBytesToRead -= n;
}
var fsOut = new FileStream(string.Format(#"c:\temp\{0}", nameOfFile), FileMode.Create);
fsOut.Write(bytes, 0, numberOfReadBytes);
fsOut.Close();
}
}
Service config:
system.serviceModel>
<services>
<service name="StreamedService.StreamedService">
<endpoint address="net.tcp://localhost:60000/StreamedService"
binding="netTcpBinding" bindingConfiguration="NewBinding0" contract="Contracts.IStreamedService" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="NewBinding0" transferMode="Streamed" maxReceivedMessageSize="67108864" />
</netTcpBinding>
</bindings>
Client implementation:
var proxy = new ChannelFactory<IStreamedService>("MyEndpoint").CreateChannel();
var fs = new FileStream(#"c:\temp\FileToUpload.zip", FileMode.Open);
proxy.PrepareUpload(fs.Length, "uploadedFile.zip");
proxy.UploadFile(fs);
Client config:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NewBinding0" transferMode="Streamed" maxReceivedMessageSize="67108864" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:60000/StreamedService"
binding="netTcpBinding" bindingConfiguration="NewBinding0"
contract="Contracts.IStreamedService" name="MyEndpoint">
</endpoint>
</client>
</system.serviceModel>
The above works with basicHttpBinding as well. And you could of course use a MemoryStream on the server side instead of a FileStream, and then deserialize it to some entity that you want to save to a DB.
I am trying to get the values inside this soap fault's "detail", but I haven't found any ways of doing so.
The response from the server:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>Many Errors</faultstring>
<detail>
<error_id>2</error_id>
<errors>
<error>
<error_id>1</error_id>
<error_description>Unknown Error</error_description>
</error>
<error>
<error_id>5</error_id>
<error_description>Not Authorized</error_description>
</error>
<error>
<error_id>9</error_id>
<error_description>Password should be at least 6 characters including one letter and one number</error_description>
</error>
</errors>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I need to get the error_ids along with their respective error_descriptions. So far I've only managed to get the detail via kSOAP with the following way:
if (envelope.bodyIn instanceof SoapObject) {
return envelope.bodyIn.toString();
} else if (envelope.bodyIn instanceof SoapFault) {
SoapFault e = (SoapFault) envelope.bodyIn;
Node details = ((SoapFault) envelope.bodyIn).detail;
}
but I haven't managed to get a single value I need when I try to "navigate" through it.
Any help is greatly appreciated. I have found little to non information about handling soap faults with ksoap2 online...
The following code handles better
Iterator it = soapFaultClientException.getSoapFault().getFaultDetail().getDetailEntries();
while (it.hasNext())
{
Source errSource = it.next().getSource();
#SuppressWarnings("unchecked")
JAXBElement errJaxb = (JAXBElement) springWebServiceTemplate.getUnmarshaller().unmarshal(errSource);
ServerCustomizedError err = errJaxb.getValue();
....
}
Figured it out after all. Here is the way to do it:
Node details = ((SoapFault) envelope.bodyIn).detail;
Element detEle = details.getElement(NAMESPACE, "detail");
List<Error> errorList = new ArrayList<NewConnector.Error>();
Element idEle = detEle.getElement(NAMESPACE, "error_id");
str.append("id: " + idEle.getText(0));
str.append("\n");
Integer id = Integer.valueOf(idEle.getText(0));
if (id == 2) {
// many errors
Element errors = detEle.getElement(NAMESPACE, "errors");
int errorChildCount = errors.getChildCount();
for (int i = 0; i < errorChildCount; i++) {
Object innerError = errors.getChild(i);
if (innerError instanceof Element) {
Element error_id = ((Element) innerError).getElement(
NAMESPACE, "error_id");
Element error_descrion = ((Element) innerError)
.getElement(NAMESPACE, "error_description");
Error singleError = new Error(Integer.valueOf(error_id
.getText(0)), error_descrion.getText(0));
errorList.add(singleError);
str.append(singleError.toString() + "\n");
}
}
str.append("Found " + errorList.size() + " errors.\n");
str.append("errorscount:" + errors.getChildCount());
The code obviously needs improvements, but it's just a showcase of how to get each value. Cheers
I use the following method:
/**
* Method to retrieve the errorMessage from the given SoapFault.
* #param soapFault
* #return String representing the errorMessage found in the given SoapFault.
*/
private static String getSoapErrorMessage (SoapFault soapFault) {
String errorMessage;
try {
Node detailNode = soapFault.detail;
Element faultDetailElement = (Element)detailNode.getElement(0).getChild(1);
Element errorMessageElement = (Element)faultDetailElement.getChild(0);
errorMessage = errorMessageElement.getText(0);
}
catch (Exception e) {
e.printStackTrace();
errorMessage = "Could not determine soap error.";
}
return errorMessage;
}
I have scoured the net for days, unsuccessfully just looking for a working example of a YouTube batch request using the C# API. So much of the documentation is out of date.
These tell me what the XML should look like:
https://developers.google.com/gdata/docs/batch
https://developers.google.com/youtube/2.0/developers_guide_protocol_batch_processing
and this is an example with Google Spreadsheets:
https://developers.google.com/google-apps/spreadsheets/#updating_multiple_cells_with_a_batch_request
Though I'm frightfully close time and again, I keep falling short of the mark with that gloriously descriptive GDataRequestException "Execution of request batch failed".
Help!
Finally cracked it!
Now, so you don't have to go through the same blind trial & terror experience I endured:
using Google.GData.Client;
using Google.GData.YouTube;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
...
YouTubeService service = new YouTubeService("YouTube API Client", Properties.Settings.Default.YouTubeDeveloperKey);
const String searchFields = "entry(id,title,link[#rel='alternate'],author(name,yt:userId),media:group(media:category(#label),media:credit,yt:videoid,yt:uploaderId),yt:statistics,yt:rating,gd:rating(#average),gd:comments/gd:feedLink(#countHint))";
String urlBase = String.Format("https://{0}gdata.youtube.com/feeds/api/videos", (testing ? "stage." : ""));
String url = String.Format("{0}?v=2&fields={1}", urlBase, searchFields);
Debug.Print(url);
YouTubeQuery searchQuery = new YouTubeQuery(url);
searchQuery.Query = keyword;
searchQuery.NumberToRetrieve = Properties.Settings.Default.NumVideosToRetrieve;
searchQuery.OrderBy = "relevance";
lblTagStats.Text = "Retrieving Top " + searchQuery.NumberToRetrieve + " Videos...";
YouTubeFeed searchResults = service.Query(searchQuery);
DebugSaveToXml(searchResults, "searchResults");
foreach (YouTubeEntry entry in searchResults.Entries)
{
titles.Add(entry.Title.Text);
if (entry.Statistics != null)
viewCounts.Add(long.Parse(entry.Statistics.ViewCount));
if (entry.Comments != null)
commentCounts.Add(long.Parse(entry.Comments.FeedLink.CountHint.ToString()));
if (entry.Rating != null)
ratings.Add(entry.Rating.Average);
if (entry.YtRating != null)
{
likeCounts.Add(long.Parse(entry.YtRating.NumLikes));
dislikeCounts.Add(long.Parse(entry.YtRating.NumDislikes));
}
videoURLs.Add(new Uri(entry.AlternateUri.ToString()));
uploaders.Add(entry.Authors[0].Name);
foreach (var category in entry.Media.Categories)
if (category.Attributes["label"] != null)
categories.Add(category.Attributes["label"].ToString());
}
lblTagStats.Text = "Retrieving Subscriber Counts...";
AtomFeed batchRequest = new AtomFeed(searchResults);
batchRequest.BatchData = new GDataBatchFeedData();
batchRequest.BatchData.Type = GDataBatchOperationType.query;
foreach (YouTubeEntry entry in searchResults.Entries)
{
AtomEntry batchEntry = searchResults.CreateFeedEntry();
String uploaderId = entry.Media.ChildNodes.Find(x => x.Name == "yt:uploaderId").InnerText;
batchEntry.Id = new AtomId("tag:youtube.com,2008:user:" + uploaderId); //not returned in search, so reconstruct it
batchEntry.BatchData = new GDataBatchEntryData();
urlBase = String.Format("https://{0}gdata.youtube.com/feeds/api/users", (testing ? "stage." : ""));
url = String.Format("{0}/{1}?v=2", urlBase, entry.Media.Credit.Value);
Debug.Print(url);
batchEntry.EditUri = url;
batchRequest.Entries.Add(batchEntry);
}
DebugSaveToXml(batchRequest, "batchRequest_Profiles");
const String profileFields = ""; // "&fields=id,yt:username,yt:statistics(#subscriberCount)"; // YouTube API bug: cant handle colons in batch request fields
urlBase = String.Format("https://{0}gdata.youtube.com/feeds/api/users/batch", (testing ? "stage." : ""));
url = String.Format("{0}?v=2{1}", urlBase, profileFields);
Debug.Print(url);
YouTubeFeed profilesFeed = (YouTubeFeed)service.Batch(batchRequest, new Uri(url));
DebugSaveToXml(profilesFeed,"profilesFeed");
foreach (ProfileEntry entry in profilesFeed.Entries)
if (entry.BatchData.Status.Code == 200)
subscriberCounts.Add(long.Parse(entry.Statistics.SubscriberCount));
lblTagStats.Text = "Retrieving Full Descriptions...";
batchRequest = new AtomFeed(searchResults);
batchRequest.BatchData = new GDataBatchFeedData();
batchRequest.BatchData.Type = GDataBatchOperationType.query;
foreach (YouTubeEntry entry in searchResults.Entries)
{
AtomEntry batchEntry = searchResults.CreateFeedEntry();
batchEntry.Id = entry.Id;
batchEntry.BatchData = new GDataBatchEntryData();
urlBase = String.Format("https://{0}gdata.youtube.com/feeds/api/videos", (testing ? "stage." : ""));
url = String.Format("{0}/{1}?v=2", urlBase, entry.VideoId);
Debug.Print(url);
batchEntry.EditUri = url;
batchRequest.Entries.Add(batchEntry);
}
DebugSaveToXml(batchRequest, "batchRequest_Descriptions");
const String descriptionFields = ""; // "&fields=media:group/media:description"; // YouTube API bug: cant handle colons in batch request fields
urlBase = String.Format("https://{0}gdata.youtube.com/feeds/api/videos/batch", (testing ? "stage.":""));
url = String.Format("{0}?v=2{1}", urlBase, descriptionFields);
Debug.Print(url);
YouTubeFeed descriptionsFeed = (YouTubeFeed)service.Batch(batchRequest, new Uri(url));
DebugSaveToXml(descriptionsFeed,"descriptionsFeed");
foreach (YouTubeEntry entry in descriptionsFeed.Entries)
if (entry.BatchData.Status.Code == 200)
descriptions.Add(entry.Media.Description.Value);
And FYI, this posts the following batch request XML for the profiles, which differs considerably from other samples, but still works like a charm:
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:batch="http://schemas.google.com/gdata/batch">
<link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml" />
<link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" />
<link rel="self" type="application/atom+xml" />
<link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" />
<batch:operation type="query" />
<entry xmlns:gd="http://schemas.google.com/g/2005">
<id>tag:youtube.com,2008:user:UC7UgD2HIyslGofSyX811fsQ</id>
<link href="https://stage.gdata.youtube.com/feeds/api/users/inspiredtennis?v=2" rel="edit" type="application/atom+xml" />
</entry>
<entry xmlns:gd="http://schemas.google.com/g/2005">
<id>tag:youtube.com,2008:user:UClXdxsQW4AqykIq2Fu4YXvQ</id>
<link href="https://stage.gdata.youtube.com/feeds/api/users/azishertanto?v=2" rel="edit" type="application/atom+xml" />
</entry>
<entry xmlns:gd="http://schemas.google.com/g/2005">
<id>tag:youtube.com,2008:user:UC1Diq4duvGuTUaGxk61-LOQ</id>
<link href="https://stage.gdata.youtube.com/feeds/api/users/atamaiidotcom?v=2" rel="edit" type="application/atom+xml" />
</entry>
...
</feed>
I need to upload files (with different extensions ie .txt, .jpg, .pdf....) on a server.
I created a site that accepts http requests an maps a virtual directory to a physical one.
all thi works fine in dowload, now I have to implement the upload.
here is my code
private void UploadFile(string uploadFileName, string localFileName)
{
//long length = 0;
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(uploadFileName);
httpWebRequest2.ContentType = "multipart/form-data; boundary=" + boundary;
httpWebRequest2.Method = "POST";
httpWebRequest2.KeepAlive = true;
httpWebRequest2.Credentials = new NetworkCredential("USER", "PASSWORD", "DOMAIN");
Stream memStream = new System.IO.MemoryStream();
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +boundary + "\r\n");
string formdataTemplate = "\r\n--" + boundary +"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
memStream.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";
string header = string.Format(headerTemplate, "uplTheFile", localFileName);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(localFileName, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
fileStream.Close();
httpWebRequest2.ContentLength = memStream.Length;
Stream requestStream = httpWebRequest2.GetRequestStream();
//error returned in lenght field: "This stream does not support seek operations."
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
WebResponse webResponse2 = httpWebRequest2.GetResponse();
//error returned from getResponse: "The remote server returned an error: (405) Method Not Allowed."
//I guess cause my folder is in read only
Stream stream2 = webResponse2.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
MessageBox.Show(reader2.ReadToEnd());
webResponse2.Close();
httpWebRequest2 = null;
webResponse2 = null;
}
firstly I got this error: The remote server returned an error: (405) Method Not Allowed.
so I tried to enable POST by adding a mapping onto the web site.
now in the folder on te server I have a web.config file that is:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<directoryBrowse enabled="true" />
<handlers>
<add name="File TXT" path="*.*" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\System32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="Script" preCondition="bitness64" />
</handlers>
</system.webServer>
</configuration>
in this way I do not get any error, but the application does not upload any file.
how do I solve this problem?
A much simpler solution would be to use the System.Net.Webclient class to upload the file.
System.Net.WebClient client = new System.Net.WebClient();
client.UploadFile("www.myfileuploadendpoint.com",#"c:\myfiletoupload.txt");
The client also has an OnUploadFileCompleted event that will call a handler when its done.
client.OnUploadFileCompleted += UploadCompleted(sender,args) => { //do whatever you want}
This will save you code and bugs. Good Luck! :)
Both of the above sample not working,
"The remote server returned an error: (405) Method Not Allowed." is the exception caught on trying both the above codes
Expect someone to share their thought on these exceptions, Please.
rgds,
thiru
I want to use ANT build to translate .properties file into text file (code).
Input file my.properties:
FOO=foo bar
BAR=bar bar foo
Desired output file Constants.as:
package foo.bar {
public final class Constants {
public static const FOO:String = "FOO";
public static const BAR:String = "BAR";
}
}
Note: ActionScript can't use properties files like Java, so I need to use this translation as a pre-build task. My properties file is localization and I want the keys as constants.
You could do this by including a filterchain in a concat task.
<concat destfile="Constants.as">
<header filtering="false">
package foo.bar {
public final class Constants {
</header>
<footer filtering="false">
}
}
</footer>
<fileset file="my.properties"/>
<filterchain>
<tokenfilter>
<ignoreblank/>
<trim/>
<replaceregex pattern="(.*)=(.*)" replace=" public static const \1:String = "\2";"/>
</tokenfilter>
</filterchain>
</concat>
I've managed to hack it through scriptdef in JavaScript.
Any ideas how to do it better?
<scriptdef name="localization-regen" language="javascript">
<attribute name="input.file.path"/>
<attribute name="output.file.category"/>
<attribute name="output.file.package"/>
<attribute name="output.file.dir"/>
<attribute name="output.property"/>
<![CDATA[
importPackage(java.io);
inputFilePath = attributes.get("input.file.path");
outputFileCategory = attributes.get("output.file.category");
outputFilePackage = attributes.get("output.file.package");
outputFileDir = attributes.get("output.file.dir");
outputFileClass = "LocalizationKeys" + outputFileCategory.substring(0, 1).toUpperCase() + outputFileCategory.substring(1, outputFileCategory.length());
inputFile = new File(inputFilePath);
inputStream = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile)));
outputLines = "";
for(line = inputStream.readLine(); line != null; line = inputStream.readLine())
{
vars = line.split("=");
c = vars[0];
if(c.substring(0, 1) == "#") continue;
outputLines += "\t\tpublic static const " + c + ":String = \"" + c + "\";\n";
}
output = "";
output = "package " + outputFilePackage + "\n"
+ "{\n"
+ "\tpublic final class " + outputFileClass + "\n"
+ "\t{\n"
+ outputLines
+ "\t}\n"
+ "}";
outputFilePath = outputFileDir + "/" + outputFileClass+ ".as";
out = new BufferedWriter(new FileWriter(outputFilePath));
out.write(output, 0, output.length);
out.flush();
out.close();
]]>
</scriptdef>