XAdES-BES countersignature cannot resolve reference error - bouncycastle

I implemented verification for XAdES-BES and after testing everything works now besides counter-signatures. The same error occurs not only for files signed with xades4j but also using other software so it is not related to any mistakes in my countersignature implementation. I wonder if I should implement additional ResourceResolver? I added a countersigned file as the attachment with 'REMOVED' for some private entries here.
Below is the code for verification. certDataList is a list with all certificates from the document in String and getCert will return List. DummyCertificateValidationProvider returns ValidationData with a list of previously constructed x509certs.
public boolean verify(final File file) {
if (!Dictionaries.valid()) {
return true;
}
certList = null;
try {
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
final DocumentBuilder db = dbf.newDocumentBuilder();
final Document doc = db.parse(file);
doc.getDocumentElement().normalize();
final NodeList nList = doc.getElementsByTagName("ds:Signature");
Element elem = null;
for (int temp = 0; temp < nList.getLength(); temp++) {
final Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
elem = (Element) nNode;
}
}
final NodeList nList2 = doc.getElementsByTagName("ds:X509Certificate");
final List<String> certDataList = new ArrayList<String>();
for (int temp = 0; temp < nList2.getLength(); temp++) {
final Node nNode = nList2.item(temp);
certDataList.add(nNode.getTextContent());
}
certList = getCert(certDataList);
final CertificateValidationProvider certValidator = new DummyCertificateValidationProvider(certList);
final XadesVerificationProfile p = new XadesVerificationProfile(certValidator);
final XadesVerifier v = p.newVerifier();
final SignatureSpecificVerificationOptions opts = new SignatureSpecificVerificationOptions();
// for relative document paths
final String baseUri = "file:///" + file.getParentFile().getAbsolutePath().replace("\\", "/") + "/";
LOGGER.debug("baseUri:" + baseUri);
opts.useBaseUri(baseUri);
v.verify(elem, opts);
return true;
} catch (final IllegalArgumentException | XAdES4jException | CertificateException | IOException | ParserConfigurationException | SAXException e) {
LOGGER.error("XML not validated!", e);
}
return false;
}
Here is the stacktrace:
21:31:48,203 DEBUG ResourceResolver:158 - I was asked to create a ResourceResolver and got 0
21:31:48,203 DEBUG ResourceResolver:101 - check resolvability by class org.apache.xml.security.utils.resolver.ResourceResolver
21:31:48,204 DEBUG ResolverFragment:137 - State I can resolve reference: "#xmldsig-5de7b1d0-be70-4dde-b746-3f4d4d6de39f-sigvalue"
21:31:48,204 ERROR SignComponent:658 - XML not validated!
xades4j.XAdES4jXMLSigException: Error verifying the signature
at xades4j.verification.XadesVerifierImpl.doCoreVerification(XadesVerifierImpl.java:284)
at xades4j.verification.XadesVerifierImpl.verify(XadesVerifierImpl.java:188)
at com.signapplet.sign.SignComponent.verify(SignComponent.java:655)
...
Caused by: org.apache.xml.security.signature.MissingResourceFailureException: The Reference for URI #xmldsig-5de7b1d0-be70-4dde-b746-3f4d4d6de39f-sigvalue has no XMLSignatureInput
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID xmldsig-5de7b1d0-be70-4dde-b746-3f4d4d6de39f-sigvalue
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID xmldsig-5de7b1d0-be70-4dde-b746-3f4d4d6de39f-sigvalue
at org.apache.xml.security.signature.Manifest.verifyReferences(Manifest.java:414)
at org.apache.xml.security.signature.SignedInfo.verify(SignedInfo.java:259)
at org.apache.xml.security.signature.XMLSignature.checkSignatureValue(XMLSignature.java:724)
at org.apache.xml.security.signature.XMLSignature.checkSignatureValue(XMLSignature.java:656)
at xades4j.verification.XadesVerifierImpl.doCoreVerification(XadesVerifierImpl.java:277)
... 39 more
Caused by: org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID xmldsig-5de7b1d0-be70-4dde-b746-3f4d4d6de39f-sigvalue
Edit:
The same error occurs when I try to validate file provided with xades4j unit tests document.signed.bes.cs.xml.
Caused by: org.apache.xml.security.signature.MissingResourceFailureException: The Reference for URI #xmldsig-281967d1-74f8-482c-8222-ed58dbd1909b-sigvalue has no XMLSignatureInput
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID xmldsig-281967d1-74f8-482c-8222-ed58dbd1909b-sigvalue
Caused by: org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID xmldsig-281967d1-74f8-482c-8222-ed58dbd1909b-sigvalue

The problem was with ds:Signature. In counter signatures you will have more than one ds:Signature entry. In my verification method I used the for loop:
for (int temp = 0; temp < nList.getLength(); temp++) {
final Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
elem = (Element) nNode;
}
}
As you can see, there was no break when element was found so I ended up with the last ds:Signature, not the first one so all previous signatures could not be found.

Related

How To Use CompUtil To Parse With Plugin

When using the Alloy API to perform parsing on the following string:
Module mod = CompUtil.parseEverything_fromString("run {} for 5")
I receive the following error:
Fatal error:
Parser Exception
at edu.mit.csail.sdg.alloy4compiler.parser.CompParser.alloy_parseStream(CompParser.java:2260)
at edu.mit.csail.sdg.alloy4compiler.parser.CompUtil.parseRecursively(CompUtil.java:178)
at edu.mit.csail.sdg.alloy4compiler.parser.CompUtil.parseEverything_fromFile(CompUtil.java:280)
at edu.mit.csail.sdg.alloy4compiler.parser.CompUtil.parseEverything_fromString(CompUtil.java:333)
at edu.mit.csail.sdg.alloy4compiler.parser.CompUtil$parseEverything_fromString.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
at MyOM.MyOMPlugin.Modularize(MyOMPlugin.groovy:107)
...
--------------------------------------------------------------------------
class file:
package MyOM
class MyOMPlugin extends Plugin{
void Modularize() throws Err{
//line 107 is the only line in the method and is below
Module mod = CompUtil.parseEverything_fromString("run {} for 5")
}
}
I am performing this task in a groovy class file within a groovy project. The code works fine until I run it in conjunction with the plugin I am using.
EDIT:
The parse function is what causes the parse exception and the code for that method is included below for reference:
#Override public Symbol parse() throws java.lang.Exception {
int act; // current action code
Symbol lhs_sym = null; // the Symbol/stack element returned by a reduce
short handle_size, lhs_sym_num; // information about production being reduced with
boolean logging = "yes".equals(System.getProperty("debug"));
production_tab = production_table();
action_tab = action_table();
reduce_tab = reduce_table();
init_actions();
user_init();
// start
cur_token = scan();
stack.removeAllElements();
stack.push(getSymbolFactory().startSymbol("START", 0, start_state()));
tos = 0;
for (_done_parsing = false; !_done_parsing; ) {
act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym);
if (act > 0) { // "shift"; thus, we shift to the encoded state by pushing it on the stack
if (logging) System.out.println("shift " + cur_token.sym);
cur_token.parse_state = act-1;
stack.push(cur_token);
tos++;
cur_token = scan();
} else if (act<0) { // "reduce"
if (logging) System.out.println("reduce " + ((-act)-1));
lhs_sym = do_action((-act)-1, this, stack, tos);
lhs_sym_num = production_tab[(-act)-1][0];
handle_size = production_tab[(-act)-1][1];
for (int i = 0; i < handle_size; i++) { stack.pop(); tos--; }
act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num);
lhs_sym.parse_state = act;
stack.push(lhs_sym);
tos++;
} else { // "error"
if (logging) System.out.println("error");
syntax_error(cur_token);
done_parsing();
}
}
return lhs_sym;
}

System.OutOfMemoryException: Exception of Type 'System.OutOfMemory' was thrown

private List<T> ReadCurrentFile(string currentExtractedFile, PurgingDetails purgingParams)
{
List<T> thinLogDoList = new List<T>();
using (StreamReader sr = new StreamReader(currentExtractedFile))
{
string currentLine = string.Empty;
Dictionary<string, string> ColumnNamesDictionary = null;
while ((currentLine = sr.ReadLine()) != null)
{
if (currentLine.IsNotNullOrEmpty() && currentLine.Contains("Æ"))
{
string[] columnNames = currentLine.Split(new char[] { 'Æ' });
ColumnNamesDictionary = FillColumnNameDictionary(columnNames);
if (CheckForValidConditions(ColumnNamesDictionary, purgingParams))
{
thinLogDoList.Add(FillThinLogDO(ColumnNamesDictionary));
}
}
}
}
return thinLogDoList;
}
(Above code is for Reading a File and adding data to the List by filling the object.)
The function is reading file of size 10 MB which is inside a zip file, first I am extracting the zip files, then reading the data, using this function and storing it into List and then deleting the extracted zip files. It is working for approximately 6L(6,00,000) Data but above that data it throws exception.
I want to read More data 10L(10,00,000) how should I do that ?
Do not return a list. Instead, use yield return to just run through the data:
private IEnumerable<i1LogThinDO> ReadCurrentFile(string currentExtractedFile,
PurgingDetails purgingParams)
{
using (StreamReader sr = new StreamReader(currentExtractedFile))
{
string currentLine = string.Empty;
Dictionary<string, string> ColumnNamesDictionary = null;
while ((currentLine = sr.ReadLine()) != null)
{
if (currentLine.IsNotNullOrEmpty() && currentLine.Contains("Æ"))
{
string[] columnNames = currentLine.Split(new char[] { 'Æ' });
ColumnNamesDictionary = FillColumnNameDictionary(columnNames);
if (CheckForValidConditions(ColumnNamesDictionary, purgingParams))
{
yield return FillThinLogDO(ColumnNamesDictionary);
}
}
}
}
}
This way, the ball is in the caller's yard. The caller must be able to process the data returned from this method without keeping them all in memory. This could mean that you have to redesign the calling methods as well, but it would bring a huge cut down in memory footprint of the application if you could do all the processing without keeping the data in memory.

Entity Framework - IQueryable to DataTable

I'm trying to convert an IQueryable object to a DataTable. Here's an example of a query that I would like to convert to a DataTable:
var query = DbContext.SomeObjectSet.Select(x => new { PropertyName1 = x.ColumnName1, PropertyName2 = x.ColumnName2 });
Please note the anonymous object that is created in the Select method and the names of the properties:
new { PropertyName1 = x.ColumnName1, PropertyName2 = x.ColumnName2 }
After Googling this issue, I came across the following code that converts an IQueryable object to a DataTable:
public static DataTable EntityToDatatable(this IQueryable result)
{
ObjectQuery query = (result as ObjectQuery);
ObjectContext context = query.Context;
EntityConnection entityCon = (context.Connection as EntityConnection);
using (SqlConnection sqlCon = new SqlConnection(entityCon.StoreConnection.ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(query.ToTraceString(), sqlCon))
{
foreach (var param in query.Parameters)
{
cmd.Parameters.AddWithValue(param.Name, param.Value);
}
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd))
{
using (DataTable dataTable = new DataTable())
{
dataAdapter.Fill(dataTable);
return dataTable;
}
}
}
}
}
The code above "works" and the SQL statement from the ToTraceString() method is as follows:
SELECT [Extent1].[ColumnName1] AS [ColumnName1], [Extent1].[ColumnName2] AS [ColumnName2] FROM [dbo].[TableName] AS [Extent1]
Problem: The column names of the SQL statement (i.e. columnName1 and columnName2) do not correspond to the names of the properties of the objects (i.e. PropertyName1 and PropertyName2) that would be materialized if a ToList() or AsEnumerable() method was called on the query. This wouldn't be so bad if the SQL statement columns were in the same order as the anonymous object properties...but, this is not always the case. Somewhere (I guess inside of the IQueryable object) there must be a mapping between the SQL statement column names and the resulting anonymous object property names.
Does anyone know how to get at this mapping?
I've managed to find a solution to my problem:
First, you need the following code (from How does Entity Framework manage mapping query result to anonymous type?) which maps the positions of my anonymous object properties to the SQL statement column position:
public static Int32[] GetPropertyPositions(this ObjectQuery query)
{
// get private ObjectQueryState ObjectQuery._state;
// of actual type internal class
// System.Data.Objects.ELinq.ELinqQueryState
Object queryState = GetProperty(query, "QueryState");
AssertNonNullAndOfType(queryState, "System.Data.Objects.ELinq.ELinqQueryState");
// get protected ObjectQueryExecutionPlan ObjectQueryState._cachedPlan;
// of actual type internal sealed class
// System.Data.Objects.Internal.ObjectQueryExecutionPlan
Object plan = GetField(queryState, "_cachedPlan");
AssertNonNullAndOfType(plan, "System.Data.Objects.Internal.ObjectQueryExecutionPlan");
// get internal readonly DbCommandDefinition ObjectQueryExecutionPlan.CommandDefinition;
// of actual type internal sealed class
// System.Data.EntityClient.EntityCommandDefinition
Object commandDefinition = GetField(plan, "CommandDefinition");
AssertNonNullAndOfType(commandDefinition, "System.Data.EntityClient.EntityCommandDefinition");
// get private readonly IColumnMapGenerator EntityCommandDefinition._columnMapGenerator;
// of actual type private sealed class
// System.Data.EntityClient.EntityCommandDefinition.ConstantColumnMapGenerator
Object columnMapGenerator = GetField(commandDefinition, "_columnMapGenerator");
AssertNonNullAndOfType(columnMapGenerator, "System.Data.EntityClient.EntityCommandDefinition+ConstantColumnMapGenerator");
// get private readonly ColumnMap ConstantColumnMapGenerator._columnMap;
// of actual type internal class
// System.Data.Query.InternalTrees.SimpleCollectionColumnMap
Object columnMap = GetField(columnMapGenerator, "_columnMap");
AssertNonNullAndOfType(columnMap, "System.Data.Query.InternalTrees.SimpleCollectionColumnMap");
// get internal ColumnMap CollectionColumnMap.Element;
// of actual type internal class
// System.Data.Query.InternalTrees.RecordColumnMap
Object columnMapElement = GetProperty(columnMap, "Element");
AssertNonNullAndOfType(columnMapElement, "System.Data.Query.InternalTrees.RecordColumnMap");
// get internal ColumnMap[] StructuredColumnMap.Properties;
// array of internal abstract class
// System.Data.Query.InternalTrees.ColumnMap
Array columnMapProperties = GetProperty(columnMapElement, "Properties") as Array;
AssertNonNullAndOfType(columnMapProperties, "System.Data.Query.InternalTrees.ColumnMap[]");
Int32 n = columnMapProperties.Length;
Int32[] propertyPositions = new Int32[n];
for (Int32 i = 0; i < n; ++i)
{
// get value at index i in array
// of actual type internal class
// System.Data.Query.InternalTrees.ScalarColumnMap
Object column = columnMapProperties.GetValue(i);
AssertNonNullAndOfType(column, "System.Data.Query.InternalTrees.ScalarColumnMap");
//string colName = (string)GetProp(column, "Name");
// can be used for more advanced bingings
// get internal int ScalarColumnMap.ColumnPos;
Object columnPositionOfAProperty = GetProperty(column, "ColumnPos");
AssertNonNullAndOfType(columnPositionOfAProperty, "System.Int32");
propertyPositions[i] = (int)columnPositionOfAProperty;
}
return propertyPositions;
}
static object GetProperty(object obj, string propName)
{
PropertyInfo prop = obj.GetType().GetProperty(propName, BindingFlags.NonPublic | BindingFlags.Instance);
if (prop == null) throw EFChangedException();
return prop.GetValue(obj, new object[0]);
}
static object GetField(object obj, string fieldName)
{
FieldInfo field = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
if (field == null) throw EFChangedException();
return field.GetValue(obj);
}
static void AssertNonNullAndOfType(object obj, string fullName)
{
if (obj == null) throw EFChangedException();
string typeFullName = obj.GetType().FullName;
if (typeFullName != fullName) throw EFChangedException();
}
static InvalidOperationException EFChangedException()
{
return new InvalidOperationException("Entity Framework internals has changed, please review and fix reflection code");
}
Then I can modify the EntityToDatatable method as follows:
public static DataTable EntityToDatatable(this IQueryable query)
{
SqlConnection sqlConnection = null;
SqlCommand sqlCommand = null;
SqlDataAdapter sqlDataAdapter = null;
DataTable dataTable = null;
try
{
ObjectQuery objectQuery = (query as ObjectQuery);
ObjectContext objectContext = objectQuery.Context;
EntityConnection entityConnection = (objectContext.Connection as EntityConnection);
sqlConnection = new SqlConnection(entityConnection.StoreConnection.ConnectionString);
sqlCommand = new SqlCommand(objectQuery.ToTraceString(), sqlConnection);
foreach (var parameter in objectQuery.Parameters)
{
sqlCommand.Parameters.AddWithValue(parameter.Name, parameter.Value);
}
sqlDataAdapter = new SqlDataAdapter(sqlCommand);
dataTable = new DataTable();
sqlDataAdapter.Fill(dataTable);
// Get the mapping between the object property position and
// the SQL statment column position.
Int32[] propertyPositions = objectQuery.GetPropertyPositions();
// Create a column name to column position (ordinal) lookup.
Dictionary<String, Int32> mapColumnNameToColumnPosition = new Dictionary<string, int>();
// Populate the lookup.
for (Int32 i = 0; i < propertyPositions.Length; ++i)
{
mapColumnNameToColumnPosition.Add(dataTable.Columns[propertyPositions[i]].ColumnName, i);
}
// Get the object's property information.
PropertyInfo[] pi = query.GetType().GetGenericArguments()[0].GetProperties();
// Iterate through the lookup and change the position of the datatable columns.
// The order of the datatable columns will now correspond to the order of the object
// properties.
foreach (var map in mapColumnNameToColumnPosition)
{
// Change the column position.
dataTable.Columns[map.Key].SetOrdinal(map.Value);
// Change the column name.
dataTable.Columns[map.Key].ColumnName = pi[map.Value].Name;
}
return dataTable;
}
catch (Exception ex)
{
// Something went wrong and we're going to raise an exception...we
// might as well dispose of the datatable if it exists because it's
// not going to be used.
if (dataTable != null) dataTable.Dispose();
throw new Exception("IQueryable to DataTable conversion error.", ex);
}
finally
{
// Do some cleanup on objects that are no longer needed.
if (sqlDataAdapter != null) sqlDataAdapter.Dispose();
if (sqlCommand != null) sqlCommand.Dispose();
if (sqlConnection != null) sqlConnection.Dispose();
}
}

How to Get Project Type Guid of selected project in the Solution Explorer by using VS Package

I've created the simple VS Package for adding new item in the context menu of solution explorer. In that I need to check Selected Project's Project Type GUID. How can i get this.
For example, One Solution contains the three different type of projects, like WindowFormsApplication, MVC Projects,WebApplication. While select the MVC Projects, we need to get that ProjectType GUID.
I've tried the followings in my Package.cs,
IVsMonitorSelection monitorSelection = (IVsMonitorSelection)Package.GetGlobalService(typeof(SVsShellMonitorSelection));
monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);
IVsHierarchy hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;
if (hierarchy != null)
{
object prjItemObject;
hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_ExtObject, out prjItemObject);
string projectTypeGuid;
Project prjItem = prjItemObject as Project;
projectTypeGuid = prjItem.Kind;
}
In that I get GUID as "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC" for all selected Projects.
Could anyone please help me this?
I've found answer for this,
Reference: https://www.mztools.com/articles/2007/MZ2007016.aspx
public string GetProjectTypeGuids(EnvDTE.Project proj)
{
string projectTypeGuids = "";
object service = null;
Microsoft.VisualStudio.Shell.Interop.IVsSolution solution = null;
Microsoft.VisualStudio.Shell.Interop.IVsHierarchy hierarchy = null;
Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject aggregatableProject = null;
int result = 0;
service = GetService(proj.DTE, typeof(Microsoft.VisualStudio.Shell.Interop.IVsSolution));
solution = (Microsoft.VisualStudio.Shell.Interop.IVsSolution)service;
result = solution.GetProjectOfUniqueName(proj.UniqueName, out hierarchy);
if (result == 0)
{
aggregatableProject = (Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject)hierarchy;
result = aggregatableProject.GetAggregateProjectTypeGuids(out projectTypeGuids);
}
return projectTypeGuids;
}
public object GetService(object serviceProvider, System.Type type)
{
return GetService(serviceProvider, type.GUID);
}
public object GetService(object serviceProviderObject, System.Guid guid)
{
object service = null;
Microsoft.VisualStudio.OLE.Interop.IServiceProvider serviceProvider = null;
IntPtr serviceIntPtr;
int hr = 0;
Guid SIDGuid;
Guid IIDGuid;
SIDGuid = guid;
IIDGuid = SIDGuid;
serviceProvider = (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)serviceProviderObject;
hr = serviceProvider.QueryService(ref SIDGuid, ref IIDGuid, out serviceIntPtr);
if (hr != 0)
{
System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
}
else if (!serviceIntPtr.Equals(IntPtr.Zero))
{
service = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(serviceIntPtr);
System.Runtime.InteropServices.Marshal.Release(serviceIntPtr);
}
return service;
}
}
Its working fine for my requirement.

Retrieve Image from Picture Library - REST

I am looking for some suggestion or sample around retrieving images (actual file, not URL), from a picture library using REST API.
Thanks for any input.
Task 1: Getting a List of Image libs on a given site
public static XmlNode GetPicLibListingXML(string imagingServiceURL)
{
Imaging wsImaging = new Imaging();
wsImaging.UseDefaultCredentials = true;
wsImaging.Url = imagingServiceURL;
XmlNode xnPicLibs = wsImaging.ListPictureLibrary();
return xnPicLibs;
}
Sample return XML:
<Library name="{3C1D52F5-5387-490A-9A2D-A9C99A208C00}" title="Tech Images" guid="3c1d52f5-5387-490a-9a2d-a9c99a208c00" url="Tech Images" xmlns="http://schemas.microsoft.com/sharepoint/soap/ois/" />
Task 2: Listing Images in a given library
public static XmlNode GetImageFileListing(string imagingServiceURL, string imageFileLibraryName)
{
Imaging wsImaging = new Imaging();
ImageInfo curImageInfo = new ImageInfo();
wsImaging.UseDefaultCredentials = true;
wsImaging.Url = imagingServiceURL;
XmlNode xnListItems = wsImaging.GetListItems(imageFileLibraryName, "");
return xnListItems;
}
Task 3: Download Image(s)
private const string ATTR_FILENAME = "name";
private const string FILENAMESPACEURI = "http://schemas.microsoft.com/sharepoint/soap/ois/";
public static bool DownloadImageFiles(string imagingServiceURL, string imageFileLibraryName, string[] fileNames, string saveToFolder)
{
Imaging wsImaging = new Imaging();
wsImaging.UseDefaultCredentials = true;
wsImaging.Url = imagingServiceURL;
XmlElement parent = (XmlElement)wsImaging.Download(imageFileLibraryName, string.Empty, fileNames, 0, true);
XmlNodeList files = parent.GetElementsByTagName("File", FILENAMESPACEURI);
foreach (XmlNode file in files)
{
if (Directory.Exists(saveToFolder) == false)
{
Directory.CreateDirectory(saveToFolder);
}
byte[] fileBytes = Convert.FromBase64String(file.InnerText);
using (FileStream fs = File.OpenWrite(saveToFolder + file.Attributes[ATTR_FILENAME].Value))
{
BinaryWriter writer = new BinaryWriter(fs);
writer.Write(fileBytes);
writer.Close();
}
}
return true;
}
Note:
Imaging() class is a web reference to imagining.asmx
The Download call natively returns XML so yo uneed to run it through a conversion to byte
If you need to get a reference on the Imagine web service check this on out on MSDN:
http://msdn.microsoft.com/en-us/library/imaging.imaging.aspx
source:
http://gourangaland.wordpress.com/2008/05/30/using-the-moss-imaging-web-service-to-download-imagesimaging-asmx/

Resources