Adding items to a SharePoint list using UpdateList - c#

I've come across a SharePoint problem that I hope someone can help with. Basically, when I am trying to add a column called "MigratedChemist" to a list called "WorkCards" (pListName in the method parameters). No matter what I try I am getting a FaultException error raised when calling UpdateList. I am connecting using the SharePoint web service. I have confirmed the following:
The column doesn't already exist and I do have permissions to create it in SharePoint
The connection to SharePoint is established corectly to /_vti_bin/lists.asmx
The list name is correct as I have another method which returns items from the list and that works perfectly.
The xVersion and xId values are set correctly when the program runs and passed as parameters - as far as I am concerned I should just be able to pass the list name, as opposed to the GUID, but neither method works.
My code is as follows:
public static bool AddColumnToList(string pUri, string pListName, string pViewName, string pMaxRecords)
{
string version = string.Empty;
XAttribute xId = null;
XAttribute xVersion = null;
try
{
XElement listDetails = client.GetList(pListName);
xVersion = listDetails.Attribute("Version");
xId = listDetails.Attribute("ID");
}
catch { throw; }
XElement ndNewFields = new XElement ("Fields", "");
string newXml = "<Method ID='1' Cmd='New'><Field Name='MigratedChemist' Type='Text' DisplayName='MigratedChemist' /></Method></Fields>";
ndNewFields.Add(newXml);
XElement result;
try
{
result = client.UpdateList(xId.Value, null, ndNewFields, null, null, xVersion.Value);
}
catch (FaultException fe)
{
}
return true;
}
In addition to this does anyone know how to get any decent information from FaultRequest? At the moment I get the following error message, which is of no use and there appears to be no extra detail. I have tried, as some have suggested removing the error handling and letting the program halt, but that doesn't give me any extra information either.
{"Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown."}

For future reference I have solved both the problem of the SharePoint update failing AND the FaultException problem, so am including it here for posterity:
Problem 1 - Problem with UpdateList
This problem was caused because my XML was malformed. When I called ndNewFields.Add(newXml) then XML that was being returned was replacing < and > than with control characters, as shown below (I have added an extra space because this editor converts them automatically.
<Method ID="1" Cmd="New"&gt ;&lt ;Field Name="MigratedChemist"&gt ;&lt ;/Field&gt ;&lt ;/Method&gt ;
Now, I did notice this pretty early on but wasn't sure whether it would cause a problem or not. However using the XElement.Parse command I was able to remove these characters and this resolved the problem:
ndNewFields.Add(XElement.Parse (newXml));
Problem 2 - Problem with the SharePoint error coming back as FaultException
This has been bugging for me ages so I am glad I have finally solved it. I can't take credit for it, as I took it from another page, but the following code was how I got the details.
catch (FaultException fe)
{
MessageFault msgFault = fe.CreateMessageFault();
XmlElement elm = msgFault.GetDetail<XmlElement>();
}
Hopefully this will save someone some frustration in the future!
Andrew

Related

Umbraco 7.3.1 "HasProperty" return always FALSE

I develop a website on Umbraco CMS for one year already.
I have a Search code which i take from old website to new one every time for year without any problem.
In this case I download Umbraco 7.3.1 and now when i try to check if content Has Property i'm getting FALSE even if the property exist.
Can someone please explain where is my mistake or how to solve it on the new version of Umbraco?
Example function:
public void GlobalSearch(DynamicPublishedContent content, string field, string searchTerm, StringBuilder sb)
{
try
{
if (content.HasProperty(field)) // Return always NULL!!! even the "Name" field
{
if (!string.IsNullOrEmpty(content.GetPropertyValue(field).ToString()))
{
SpecifyPageSearch(content, field, searchTerm, sb);
}
}
}
catch (Exception ex)
{
return;
}
}
Thanks in advance.
Have you re-indexed your content. Go to Developer section and the Examine Management tab. Hit Rebuild for the internal index. Then do a Republish Entire Site.

Delving into the world of XML (Windows Phone) Error I dont understand (The ' ' character, hexadecimal value 0x20, cannot be included in a name.)

So I am starting to learn how to use XML data within a app and decided to use some free data to do this however I cannot for the life of me get it working this is my code so far. (I have done a few apps with static data before but hey apps are designed to use the web right? :p)
public partial class MainPage : PhoneApplicationPage
{
List<XmlItem> xmlItems = new List<XmlItem>();
// Constructor
public MainPage()
{
InitializeComponent();
LoadXmlItems("http://hatrafficinfo.dft.gov.uk/feeds/datex/England/CurrentRoadworks/content.xml");
test();
}
public void test()
{
foreach (XmlItem item in xmlItems)
{
testing.Text = item.Title;
}
}
public void LoadXmlItems(string xmlUrl)
{
WebClient client = new WebClient();
client.OpenReadCompleted += (sender, e) =>
{
if (e.Error != null)
return;
Stream str = e.Result;
XDocument xdoc = XDocument.Load(str);
***xmlItems = (from item in xdoc.Descendants("situation id")
select new XmlItem()
{
Title = item.Element("impactOnTraffic").Value,
Description = item.Element("trafficRestrictionType").Value
}).ToList();***
// close
str.Close();
// add results to the list
xmlItems.Clear();
foreach (XmlItem item in xmlItems)
{
xmlItems.Add(item);
}
};
client.OpenReadAsync(new Uri(xmlUrl, UriKind.Absolute));
}
}
I am basically trying to learn how to do this at the moment as I am intrigued how to actually do it (I know there are many ways but ATM this way seems the easiest) I just don't get what the error is ATM. (The bit in * is where it says the error is)
I also know the display function ATM is not great (As it will only show the last item) but for testing this will do for now.
To some this may seem easy, as a learner its not so easy for me just yet.
The error in picture form:
(It seems I cant post images :/)
Thanks in advance for the help
Edit:
Answer below fixed the error :D
However still nothing is coming up. I "think" it's because of the XML layout and the amount of descendants it has (Cant work out what I need to do being a noob at XML and pulling it from the web as a data source)
Maybe I am starting too complicated :/
Still any help/tips on how to pull some elements from the feed (As there all in Descendants) correctly and store them would be great :D
Edit2:
I have it working (In a crude way) but still :D
Thanks Adam Maras!
The last issue was the double listing. (Adding it to a list, to then add it to another list was causing a null exception) Just using the 1 list within the method solved this issue, (Probably not the best way of doing it but it works for now) and allowed for me to add the results to a listbox until I spend some time working out how to use ListBox.ItemTemplate & DataTemplate to make it look more appealing. (Seems easy enough I say now...)
Thanks Again!!!
from item in xdoc.Descendants("situation id")
// ^
XML tag names can't contain spaces. Looking at the XML, you probably just want "situation" to match the <situation> elements.
After looking at your edit and further reviewing the XML, I figured out what the problem is. If you look at the root element of the document:
<d2LogicalModel xmlns="http://datex2.eu/schema/1_0/1_0" modelBaseVersion="1.0">
You'll see that it has a default namespace applied. The easiest solution to your problem will be to first get the namespsace from the root element:
var ns = xdoc.Root.Name.Namespace;
And then apply it wherever you're using a string to identify an element or attribute name:
from item in xdoc.Descendants(ns + "situation")
// ...
item.Element(ns + "impactOnTraffic").Value
item.Element(ns + "trafficRestrictionType").Value
One more thing: <impactOnTraffic> and <trafficRestrictionType> aren't direct children of the <situation> element, so you'll need to change that code as well:
Title = items.Descendants(ns + "impactOnTraffic").Single().Value,
Description = item.Descendants(ns + "trafficRestrictionType").Single().Value

Lists.AddAttachment throws object reference error

I'm trying to add an attachment to a list item I just created on a sharepoint server using CAML. The code below is simplified (for example the path is normally a variable and the 2nd field (the item id, here 16847) is normally the id I get back from my insert statement in CAML).
This is my code:
String desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
String savePath = desktopPath + #"\" + "tutorials.txt";
byte[] data = GetData(savePath);
lists.AddAttachment("Tasks", "16847", "tutorials.txt", data);
I'm getting this error:
Unable to update the security according your changes. The following exception occurred during ItemUpdating: Object reference not set to an instance of an object.
See Event Viewer for more information.0x81020089
getdata is a method which converts the file on my desktop to a byte[]. data is not empty and it looks okay.
Other than that Tasks is the List needed and 16847 is the task id in which to add the attachment.
Most of the info I can find is about a different error: the index out of range exception (like on the msdn page: http://msdn.microsoft.com/en-us/library/lists.lists.addattachment(v=office.12).aspx).
I've also tried a http put (unauthorized access, obviously) and the copy service (I can post this code if we can't find the solution to the simpler way above).
Can anyone tell me what is wrong?
EDIT 1:
private dcp.Lists lists = new dcp.Lists();
lists.Credentials = System.Net.CredentialCache.DefaultCredentials;
lists.Url = Values.SERVERADDRESS + "/_vti_bin/lists.asmx";
This initializes the connection to our web service. It works perfectly fine for updates, inserts...
GetData code:
private byte[] GetData(String savePath)
{
byte[] contents;
using (FileStream fStream = File.OpenRead(savePath))
{
contents = new byte[fStream.Length];
sFileName = fStream.Name;
fStream.Read(contents, 0, Convert.ToInt32(fStream.Length));
}
return contents;
}
EDIT 2:
Note that the following does work (I get a correct list of existing attachments from the task):
XmlNode ndAttach = lists.GetAttachmentCollection("Tasks", "16847");
MessageBox.Show(ndAttach.OuterXml);
And the following doesn't (same error as for the AddAttachment method):
lists.DeleteAttachment("Tasks", "16847", ndAttach.ChildNodes[0].InnerText);
Whereas I'm quite certain this should work since it does exactly the same as the example code on msdn: http://msdn.microsoft.com/en-us/library/lists.lists.deleteattachment(v=office.12).aspx
The code above is fine, the error occured on our server. When adding an attachment, no contenttype is given in the xml. This was programmed to throw an error because we've always used this method to update and add new items. So we removed the contenttype out of the underlying code and it works like a charm.

How to reset digital signature of an InfoPath form during c# workflow in Sharepoint 2010?

As the question says, I have an InfoPath form running on SP2010 using a c# workflow upon submission. If the form is rejected during workflow, then I need to reset it. I have everything under control, EXCEPT how to reset digital signatures to null, nill, nada, nothing, non-extant! Any ideas? I'm looking at Google now, but at current, I'm not even sure of an om for digital signatures?
Wow, i notice this question suddenly gaining alot of pop with bounty almost gone. Just putting it out there, I did not intend to not bounty someone, but i needed the answer earlier this week (2nd week Nov 2012) and thus i searched and played and teetered with code as much as possible till i ended up finding my own answer before anyone else answered me. However, for future reference, if someone gives a better answer, i'll gladly come back and rep them. Thank you all for the support and I really hope my answer is as useful to another as it was to me.
NOW Bloggered && Gisted May no one ever again have to search as hard as I did for this answer, :P
¡¡¡ I F O U N D M Y F R I G G I N ' A N S W E R ! ! !
¡¡¡ And it works from the workflow !!!
Through much trial and tribulation I was finally able to come up with a solution. It involves a few steps. One, elevate security! Otherwise, non-admin users will cause the workflow to error. Seems like it should work this way, but ... Secondly, get the right schema! It took me a while to find mine, i forgot the exact steps, but, it's not hard to find. UPDATED: Can be found as an attribute of xmlDoc.Document, see updated code Step through (debug) your workflow, without the namespace/schema and highlight your document when it gets to it. One of the properties is an url that is the schema link. Anyway, you wanna see the solution!? Do ya? Look down!
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPFile formFile = workflowProperties.Item.File;
MemoryStream ms = new MemoryStream(formFile.OpenBinary());
XmlTextReader rdr = new XmlTextReader(ms);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(rdr);
rdr.Close();
ms.Close();
XmlNamespaceManager nsm = new XmlNamespaceManager(xmlDoc.NameTable);
String schemaUri = xmlDoc.DocumentElement.GetAttributeNode("xmlns:my") != null ? xmlDoc.DocumentElement.GetAttributeNode("xmlns:my").Value : "http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-09-04T20:19:31";
nsm.AddNamespace("my", schemaUri);
XmlNode nodeSignatureCollection = xmlDoc.DocumentElement.SelectSingleNode("my:signatures1", nsm);
if (nodeSignatureCollection != null)
{
if (nodeSignatureCollection.HasChildNodes)
{
foreach (XmlNode nodeSignature in nodeSignatureCollection.ChildNodes)
{
// HERE IT IS!!!
if (nodeSignature.HasChildNodes && !nodeSignature.IsReadOnly) nodeSignature.RemoveAll();
}
}
}
byte[] xmlData = System.Text.Encoding.UTF8.GetBytes(xmlDoc.OuterXml);
formFile.SaveBinary(xmlData);
formFile.Update();
});
Keep in mind, this setup is for going through multiple signatures. Although I doubt anything would change if there was only one signature.
Any suggestions on making this sweeter and smaller are accepted, however, I must request an explanation. Honestly, I barely understand what is going on here!
The following answer only HALF works. It is left here for instructional purpose. (Full working answer can be found here.) It works for admin users, but nothing less. It also only works from the InfoPath form behind code. NOT from the workflow.
Adding elevated privlage seems to have 0 effect
I'm leaving this answer up here along with my other so that someone may learn from both examples or possibly even instruct others (including myself) via comments and what not on why one way may be better than the other. At this point, I really don't care to explain anymore as I really don't care to see any of this code ever again! LoL!
public void FormEvents_Loading(object sender, LoadingEventArgs e)
{
string[] actionFields = new string[] { "/my:myFields/my:.../my:...", "/my:myFields/my:.../my:...", etc... };
for (int i = 0; i < actionFields.Length; i++)
{
String field = actionFields[i];
XPathNavigator node = this.MainDataSource.CreateNavigator().SelectSingleNode(field, this.NamespaceManager);
if (node.Value.ToLower() == "reject")
{
XPathNavigator sigNode = this.MainDataSource.CreateNavigator();
if (this.Signed) //then unsign it
{
for (int ii = 2; ii <= 13; ii++)
{
try
{
XPathNavigator xSignedSection = sigNode.SelectSingleNode(String.Format("my:myFields/my:signatures1/my:signatures{0}", ii), this.NamespaceManager);
if (xSignedSection.HasChildren)
{
xSignedSection.MoveToChild(XPathNodeType.Element); xSignedSection.DeleteSelf();
};
}
catch (Exception ex) { };
};
};
};
};
}

ImportXmlWithProgress not updating result attribute of importjob

I tried to write some code to import a large customization containing 50+ entities. I used the microsoft article 'ImportXmlWithProgress Message (CrmService) as a bases, but was not getting the output I expected.
The 'job.data' in the following code was not changing from the original parameterxml data. So this implies to me that the import was not sucessful. I imported the same compressed importexportxml using the microsoft web ui, and it worked fine. So I'm wondering why my job.data is not being updated with 'result' attributes for each entity that is imported.
Below is my method to import.
private void ImportEntitySchema()
{
const string parameterXml = #"<importexportxml>
<entities>
{0}
</entities>
<nodes/>
<securityroles/>
<settings/>
<workflows/>
</importexportxml>";
var importRequest = new ImportCompressedXmlWithProgressRequest
{
ImportJobId = Guid.NewGuid(),
CompressedCustomizationXml = GetCompressedCustomizationXmlFromEmbeddedResource(),
ParameterXml = string.Format(parameterXml, string.Join("\n", _entitySchemaEntityNames.Select(item => string.Format("<entity>{0}</entity>", item)).ToArray()))
};
try
{
_crmService.Execute(importRequest);
}
catch (Exception e)
{
//Error resulted from import request
}
// Retrieve the results of the import.
XmlNode node;
do
{
Thread.Sleep(2000);
var job = (importjob)_crmService.Retrieve(EntityName.importjob.ToString(), importRequest.ImportJobId, new AllColumns());
var data = new XmlDocument();
data.LoadXml(job.data);
node = data.SelectSingleNode("importexportxml/entities/entity/#result");
} while (node == null);
//code below here never gets executed because the loop continues infinitely
}
I've been looking, but haven't found any/many [useful] examples on the net of the ImportXmlWithProgress being used. Hopefully someone has used it and has an idea of how to get it working.
I remember having trouble with this message, I just can't remember exactly what the trouble was. How big is your import file? We also brewed an import utility for importing our customizations and I use the ImportCompressedAllXmlRequest synchronously (no timeout) on a BackgroundWorker thread. For large amounts of customizations you may have to look at: http://support.microsoft.com/kb/918609. We typically split up our customizations into a bunch of small imports to avoid this.
Should the XPath be "importexportxml/entities/entity[#result]"?

Categories