Uploading an XML file, referencing an XSD, in ASP.Net - asp.net

I have an XML file which is being uploaded to an ASP.Net page via the normal file upload control. When it gets up, I am attempting to validate and deserialize the XML. However, the code below is really very handy for validating an XML file which references it's XSD like this:
xsi:schemaLocation="someurl ..\localSchemaPath.xsd"
However, if I upload this XML file, only the XML file gets uploaded, so ..\localSchemaPath.xsd doesn't exist, so it can't validate.
Even if I stored the XSD locally, it still wouldn't be quite right as the XML file could be written with a schema location like:
xsi:schemaLocation="someurl ..\localSchemaPath.xsd"
or
xsi:schemaLocation="someurl localSchemaPath.xsd"
or
xsi:schemaLocation="someurl ..................\localSchemaPath.xsd"
if it so wished.
Dilemma!
(For the purposes of this question, I have pinched the code below from: Validating an XML against referenced XSD in C#)
using System.Xml;
using System.Xml.Schema;
using System.IO;
public class ValidXSD
{
public static void Main()
{
// Set the validation settings.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
// Create the XmlReader object.
XmlReader reader = XmlReader.Create("inlineSchema.xml", settings);
// Parse the file.
while (reader.Read()) ;
}
// Display any warnings or errors.
private static void ValidationCallBack(object sender, ValidationEventArgs args)
{
if (args.Severity == XmlSeverityType.Warning)
Console.WriteLine("\tWarning: Matching schema not found. No validation occurred." + args.Message);
else
Console.WriteLine("\tValidation error: " + args.Message);
}
}

Here is a chunk of code I use to validate xml with a local schema:
string errors = string.Empty;
try
{
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(string.Empty, Page.MapPath("~/xml/Schema.xsd"));
XmlDocument doc = new XmlDocument();
doc.Schemas = schemas;
doc.Load(Page.MapPath("~/xml/sampleXML.xml"));
//use this line instead of the one above for a string in memory.
//doc.InnerXml = xmlToValidate;
ValidationEventHandler validator = delegate(object send, ValidationEventArgs ve)
{
errors += "\n" + ve.Severity + ": " + ve.Message;
};
doc.Validate(validator);
}
catch (XmlException xe)
{
errors += "\n" + xe.Message;
}
catch (XmlSchemaValidationException xe)
{
errors += "\n" + xe.Message;
}

I can't quite make out whether you are attempting a generic validate-against-any-referenced-schema, or if you have a specific schema that you validate against every time, and are just not sure how to handle the references.
If it's the latter, then make the schema public on the internet, and tell people to reference it by URI.
If it's the former, then I would suggest the following:
First the user uploads an XML file.
Parse the XML file for a schema reference. Tell them "References to yourSchema.xsd were found; please upload this file below" with a new upload box.
Then, validate the file against the uploaded schema. To do this, modify the Schemas property of your settings object, instead of modifying the ValidationFlags property.

Related

Resource (resx) lookup returns doesnt return the contents

I've created a .net core class library that needs to embed external text files. I have added a Resource.resx to the project root and added my text files to the resx. I can now access the text files through code
var a = Resource.MyTxtResourceFile
The intellisense lets me know that MyTxtResourceFile "Looks up a localized string similar to [the correct contents of the file]
When I run the code Resource.MyTxtResourceFile actually returns the string
directory1\directory2\mytxtresourcefile.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8
not the contents of the text file.
The Resource.Designer looks something like this
/// <summary>
/// Looks up a localized string similar to [the contents of my text file]
/// </summary>
public static string MyTxtResourceFile {
get {
return ResourceManager.GetString("MyTxtResourceFile ", resourceCulture);
}
}
Can anyone help?
I no longer add things directly to the resx file. I just include text files in the project and use the GetManifestResourceStream method to get the contents, then use a StreamReader to turn the stream into a string.
For example, I have a project called Stamina.World.DataAccess.SqlClient. There is a file called ReadAll.sql in a subfolder AuthenticationAttempt\Script. I'd like to get the contents of that file. Here's the code
var manifestResourceName = "Stamina.World.DataAccess.SqlClient.AuthenticationAttempt.Script.ReadAll.sql";
var contents = string.Empty;
// this assumes the file is in the current assembly
var currentAssembly = this.GetType().Assembly;
using (var manifestResourceStream = currentAssembly.GetManifestResourceStream(manifestResourceName))
{
if (manifestResourceStream == null)
{
// TODO : handle this
}
using (var streamReader = new System.IO.StreamReader(manifestResourceStream))
{
contents = streamReader.ReadToEnd();
}
}
// do something with the file contents

Lose HttpServletRequest Parts After Reading Them

I have a servlet that receives an uploaded file. We've been having issues with a certain client's request not having a file attached or so the servlet thinks. The upload servlet is a replacement for an old one and we're using the Apache Commons FileUpload library to parse the file from the request. The old code uses the JavaZoom library. The requests client we're having issues with work perfectly fine in the old code.
In order to troubleshoot the problem, I added a bunch of logging to look at the request headers and parts to compare requests from a client that works with the one that doesn't. This is a snippet of how I'm looking at the parts:
Collection<Part> parts = request.getParts();
for(Part part : parts)
{
String partName = part.getName();
log.debug("Part=" + partName);
Collection<String> headerNames = part.getHeaderNames();
for(String headerName : headerNames)
{
String headerValue = part.getHeader(headerName);
log.debug(headerName + "=" + headerValue);
InputStream inputStream = part.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
StringBuilder builder = new StringBuilder();
try
{
for(String line=bufferedReader.readLine(); line!=null; line=bufferedReader.readLine())
{
builder.append(line);
builder.append('\n');
}
}
catch (IOException ignore)
{
// empty
}
finally
{
inputStream.reset();
}
log.debug("InputStream=" + builder.toString());
}
}
All this code works fine and I get the logging I'm expecting. However, this next bit of code doesn't act as expected:
if (isMultipart)
{
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
#SuppressWarnings("rawtypes")
List items = null;
// Parse the request
try
{
items = upload.parseRequest(request);
log.debug("items=" + items);
}
catch (FileUploadException ex)
{
log.warn("Error parsing request", ex);
response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());
}
the items variable is empty when it's logged. If I comment out the code for logging the request parts, this bit of code works and the items variable contains the uploaded file.
I can only assume that the act of getting/reading the parts from the request somehow removes them from it and are no longer available for further processing. Is there some way to read them for logging purposes and still retain them in the request for further processing?
The Collection<Part> parts = request.getParts(); is an Sevlet 3.0 API which is replacement for Commons Apache File Upload API.
You should be using only one of the two methods. Both have the support for processing uploaded files and parameters along with it.
Here is the Example for File Upload Using Servlet 3.0
The problem you are facing is because you are invoking this Collection<Part> parts = request.getParts(); request will consume the request input stream. And then you are using Apache Commons API to read the parts again. Because the stream is already read you are seeing no parts are available.
References for Servlet 3.0 File Upload:
Posting Data along with File
Servlet 3.0 Multipart Example
Servlet 3.0 MultipartConfig

ASP.NET Photo Upload

When uploading a photo to my server using the following code, I'm receiving an erroneous value. This is working fine in the debug mode and when published in localhost.
string filePath = Path.Combine(HttpContext.Server.MapPath("../Uploads"), date);
if (!Directory.Exists(HttpContext.Server.MapPath("../Uploads")))
{
Directory.CreateDirectory(HttpContext.Server.MapPath("../Uploads"));
}
file.SaveAs(filePath);
Can someone please point out what I've done incorrectly?
ok I am assuming that you are using File Upload control or you can use the below sample code if you want to use the FileUpload control in your asp.net page.
Add the FileUpload control (Here im adding ajax async FileUpload control and named as asyncFileUpload.
Write A Method and Call it whenever you want.
public int AsyncFileUpload()
{
string xlsFile = AsyncFileUpload1.FileName;
if (AsyncFileUpload1.HasFile)
{
string FileName = Path.GetFileName(AsyncFileUpload1.PostedFile.FileName);
string Extension = Path.GetExtension(AsyncFileUpload1.PostedFile.FileName);
string FilePath = Server.MapPath("~/Uploads/" + FileName);
if (Extension == ".doc")//check the file extension here
{
AsyncFileUpload1.SaveAs(FilePath);
}
}
}

Tridion 2009 SP1: Is it possible to publish a .htaccess file?

I am using ISAPI rewrite on a project and would like to know if it is possible to publish a .htaccess file from Tridion?
I have tried creating a Page Template with the .htaccess extension but can't create a page with no name.
Any ideas?
Could I use a C# TBB to change the page name?
I would also choose to use a binary to achieve this, but if you want to manage the htaccess file using text, rather than as a multimedia component, you can push a binary into your package using the following technique:
1) Push the text of the Htaccess file into the package with an accessible name (i.e. Binary_Text)
2) Use code similar to the following to create a text file from the text in the variable and add it to the package
class publishStringItemAsBinary : ITemplate
{
public void Transform(Engine engine, Package package)
{
TemplatingLogger log = TemplatingLogger.GetLogger(typeof(publishStringItemAsBinary));
TemplateUtilities utils = new TemplateUtilities();
System.IO.Stream inputStream = null;
try
{
string strInputName = package.GetValue("InputItem");
string strFileName = package.GetValue("strFileName");
string sg_Destination = package.GetValue("sg_Destination");
string itemComponent = package.GetValue("mm_Component");
inputStream = new MemoryStream(Encoding.UTF8.GetBytes(package.GetValue(strInputName)));
log.Debug("InputObject:" + strInputName);
log.Debug("Filename for binary:" + strFileName);
log.Debug("Destination StructureGroup:" + sg_Destination);
Publication contextPub = utils.getPublicationFromContext(package, engine);
TcmUri uriLocalSG = TemplateUtilities.getLocalUri(new TcmUri(contextPub.Id), new TcmUri(sg_Destination));
TcmUri uriLocalMMComp = TemplateUtilities.getLocalUri(new TcmUri(contextPub.Id), new TcmUri(itemComponent));
StructureGroup sg = (StructureGroup)engine.GetObject(uriLocalSG);
Component comp = (Component)engine.GetObject(uriLocalMMComp);
String sBinaryPath = engine.PublishingContext.RenderedItem.AddBinary(inputStream, strFileName, sg, "nav", comp, "text/xml").Url;
//Put a copy of the path in the package in case you need it
package.PushItem("BinaryPath", package.CreateStringItem(ContentType.Html, sBinaryPath));
}
catch (Exception e)
{
log.Error(e.Message);
}
finally
{
if (inputStream != null)
{
inputStream.Close();
}
}
}
}
I think the code is pretty self explanatory. This publishes a binary of type text/xml, but there should be no issue converting it to do a plain text file.
I think you can use multimedia component to store your .htaccess. Even if you will not be able to upload file without name (Windows limitation), you will be able to change filename later, by modifying BinaryContent.Filename property of multimedia component. You can then publish this component seperately, or use AddBinary method in one of your templates.
There's also a user schema where you can change some other rules: "\Tridion\bin\cm_xml_usr.xsd", but you will not be able to allow empty filenames

How to rename a file in C#

Consider:
strPath= c:\images\gallery\add.gif
I need to rename this file from add.gif to thumb1.gid, and I should write one command method, whatever the file name. We need to
replace that name with this like below.
string strfilename = **"thumb"**
****Result thum.gif**
strPath= c:\images\gallery\thum.gif **
You have several problems, looking up the value in the XML file, and renaming the file.
To look up the number corresponding to Gallery2 or whatever, I would recommend having a look at Stack Overflow question How to implement a simple XPath lookup which explains how to look up nodes/values in an XML file.
To rename a file in .NET, use something like this:
using System.IO;
FileInfo fi = new FileInfo("c:\\images\\gallery\\add.gif");
if (fi.Exists)
{
fi.MoveTo("c:\\images\\gallery\\thumb3.gif");
}
Of course, you would use string variables instead of string literals for the paths.
That should give you enough information to piece it together and solve your particular lookup-rename problem.
I created a utility method to help encapsulate how to rename a file.
public class FileUtilities
{
public static void RenameFile(string oldFilenameWithPathWithExtension, string newFilenameWithoutPathWithExtension)
{
try
{
string directoryPath = Path.GetDirectoryName(oldFilenameWithPathWithExtension);
if (directoryPath == null)
{
throw new Exception($"Directory not found in given path value:{oldFilenameWithPathWithExtension}");
}
var newFilenameWithPath = Path.Combine(directoryPath, newFilenameWithoutPathWithExtension);
FileInfo fileInfo = new FileInfo(oldFilenameWithPathWithExtension);
fileInfo.MoveTo(newFilenameWithPath);
}
catch (Exception e)
{
//Boiler plate exception handling
Console.WriteLine(e);
throw;
}
}
}
I omitted several other file system checks that could optionally be done, but as #JoelCoehoorn pointed out in a comment on this page, the File System is Volatile, so wrapping it in a try-catch may be all that is necessary.
With that class in your library, now you can simply call:
var fullFilename = #"C:\images\gallery\add.gif";
var newFilename = "Thumb.gif";
FileHelper.RenameFile(fullFilename,newFilename);

Resources