BizTalk "New" SharePoint Adapter Send Document Silent Fail - sharepoint

I have a BizTalk 2016 solution. It's collecting a document (Pdf or Word) from a varbinary(max) column of a Sql Server database, along with some metadata. So, the message that makes its way to the messagebox from the Sql Receive Port looks like:
<TypedPolling xmlns="http://schemas.microsoft.com/Sql/2008/05/TypedPolling/ReadyForBizTalk">
<TypedPollingResultSet0>
<TypedPollingResultSet0>
<Id>3</Id>
<DocId>104</DocId>
<Uprn>76675</Uprn>
<Address1>48 Cardinal Square </Address1>
<Address2>City</Address2>
<Address3>County</Address3>
<Postcode>AF1 5FF</Postcode>
<Title>Doc title</Title>
<DocType>Pdf</DocType>
<Version>-1</Version>
<Date>30/01/2019 14:46:26</Date>
<Description>Description</Description>
<FilePath />
<Extension>.pdf</Extension>
<SystemGenerated>false</SystemGenerated>
<Content>/9j/4AAQSkZJRgAB...</Content>
<ProcessedByBizTalk>false</ProcessedByBizTalk>
</TypedPollingResultSet0>
</TypedPollingResultSet0>
I want BizTalk to send this to send the binary document (content of the Content element) and the metadata "Title" value to a SharePoint 2013 document library. I have created a send port and configured the following properties:
Use Cleint OM = Yes
Destination Folder URL
SharePoint Site URL
Column 01 = Title
Column 01 Value = %XPATH=//Title%
I realise that I've not made any attempt to send the "Content" yet but I thought I'd try to get this simple case working first.
When I set a new rec to be collected from the Sql Server table, it is collected ok by BizTalk and I can see from Tracked Messages that a send is made through the SharePoint adaptor. There are no errors either in the BizTalk admin console or event log, but new item appears in the document library
I have a couple of questions:
Any ideas why nothing new is appearing on the doc library?
Once I'm able to persist "something" to SharePoint library, does anyone know how I can get the binary document into the library?

Related

Automatically open Office documents on a Sharepoint Server 2013 in Firefox (full Office integration)

I recently switched to Firefox. Unfortunately my company still uses Sharepoint Server 2013 (migration to Sharepoint Online is planned somewhere in the future) which no longer offers a fluid integration with Office.
Every time I want to edit an Office document, it gets downloaded instead of being 'forwarded' to be opened by Word, Excel, etc. Modifications need to be saved locally and than uploaded afterwards. This is hugely annoying.
Is there some way that I can automate this in code, using a Firefox extension? Does Sharepoint expose some kind of hook or metadata containing the document's URL?
(Self-answer originally provided by Dotsoltecti; copied from question body into a proper answer).
Sharepoint 2013 passes the document's URL via the right-click contextual menu.
There exists a very neat add-on for Firefox called "custom right-click menu" by Sander Ronde. After installing this extension I added the script below:
var feedback = crmAPI.getClickInfo();
var url = feedback.linkUrl;
if (url.endsWith("docx") || url.endsWith("doc")) { var uri = "ms-word:ofe|u|" }
if (url.endsWith("xlsx") || url.endsWith("xls")) { var uri = "ms-excel:ofe|u|" }
if (url.endsWith("pptx") || url.endsWith("ppt")) { var uri = "ms-powerpoint:ofe|u|"}
var toOpen = uri.concat(url);
window.open(toOpen);
Et voilĂ : right clicking on a Word/Excel/PowerPoint-document executes the script and correctly forwards the document to the said program (you have to whitelist your SharePoint-site with the pop-up blocker). Modifications are handled directly by the Office-program.
Only drawback so far is that every time a document is opened, a new blank window is generated. I haven't found a solution for that yet, so suggestions are always welcome.

What is the Sharepoint Document Location endpoint really returning?

I'm trying to get the OneNote notebook information that is linked to my organization's CRM accounts. Each account has a OneNote book created for it that can be accessed inside of CRM.
From what I understand, I can use the SharePointDocumentLocation endpoint (found here: https://learn.microsoft.com/en-us/dynamics365/customer-engagement/web-api/sharepointdocumentlocation?view=dynamics-ce-odata-9) to get the location of the specific file if I ask for location type to be 1.
However, SharePointDocumentLocationId and SiteCollectionId don't seem to be pointing to anything on my company's sites. Should I be getting my data somewhere else?
I started searching through my company's SharePoint structure to see if I can get any hints as to where these documents may be located. My initial Postman request (getting the sites off of the root site) don't show the site that hosts our CRM documents (sites/crmdocs). I was able to find where this was stored eventually, but trying to get the OneNote notebooks stored there returns an error since we have more than 20,000 notebooks there, so I can't fetch them all. As far as I know, I'm able to get notebooks if I have the specific ID I want.
Once I fetch the CRM information, I try to send a request like this:
https://graph.microsoft.com/v1.0/sites/{myCompanyUrl},{siteCollectionId},{sharepointDocumentLocationId}/onenote/notebooks/
SiteCollectionId and SharePointDocumentLocationId are from my CRM SharePointDocumentLocation request
The error I receive is:
The requested site was not found. Please check that the site is still accessible.
Assuming your environment is using the out of the box sharepoint site and sharepoint document location hierarchy, you can access One Note files using the following link structure:
[SharePointAbsoluteUrl]/[EntityLogicalName]/[RelativeUrl]_[RegardingObjectId]/[RelativeUrl]
How to get [SharePointAbsoluteUrl] :
Querying for sharepointdocumentlocations is actually not enough because Dynamics 365 stores this information in another entity called sharepointsite. This is how you can obtain it:
var query = new QueryExpression("sharepointsite")
{
ColumnSet = new ColumnSet("absoluteurl")
};
query.Criteria.AddCondition("IsDefault", ConditionOperator.Equal, true);
var entityCollection = _service.RetrieveMultiple(query);
var absoluteUrl = entityCollection[0].Attributes["absoluteurl"];
In Web API it is equivalent to:
GET https://[Your Org]/api/data/v9.0/sharepointsites?$select=absoluteurl&$filter=isdefault%20eq%20true
There can only be a default sharepoint site so this query will return a single record.
How to get the remaining parts:
Fetch for sharepointdocumentlocations that have Location Type dedicated to One Note Integration:
var query = new QueryExpression("sharepointdocumentlocation")
{
ColumnSet = new ColumnSet("regardingobjectid", "relativeurl")
};
query.Criteria.AddCondition("locationtype", ConditionOperator.Equal, 1);
var entityCollection = _service.RetrieveMultiple(query);
In Web API it is equivalent to the following get request, don't forget to add add Prefer: odata.include-annotations="*" to your HTTP Request Headers so that it gets the lookup lookuplogicalname field:
GET https://[Your Org]/api/data/v9.0/sharepointdocumentlocations?$select=relativeurl,_regardingobjectid_value&$filter=locationtype%20eq%201
This query can return many records, I've only used the first one in the examples below for explanation purposes.
[EntityLogicalName] will be your ((EntityReference)entityCollection[0].Attributes["regardingobjectid"]).LogicalName;
In Web Api will be your value._regardingobjectid_value#Microsoft.Dynamics.CRM.lookuplogicalname value.
[RelativeUrl] will be your entityCollection[0].Attributes["relativeurl"];
In Web Api will be your value.relativeurl value.
[RegardingObjectId] can be obtained with this expression ((EntityReference)entityCollection[0].Attributes["regardingobjectid"]).Id.ToString().Replace("-", "").ToUpper();
In Web Api id will be your _regardingobjectid_value value and you have to remove dashes and convert it to upper case in whatever language you are doing the request.
You should end up with an URL like this https://mycompany.sharepoint.com/account/A Datum Fabrication_A56B3F4B1BE7E6118101E0071B6AF231/A Datum Fabrication

DocLib Item stays checked out after edit

here are steps of my problem:
Go to custom DocumentLibrary (custom fields, custom ListForm with custom FieldIterator)
Select one of existing on production Word documents (*.doc)
Click "Edit document" in order to edit in a client Office application
Edit doc and click save, look at progress bar of changes uploading...
Close document, the view I`d opened before will be refreshed.
Problem:
The item becomes checked out by Administrator. It does not matter what user you use to edit, you will always see checked out document under Administrator.
Changes to document are applied time by time.
Results of my investigation:
I`ve loocked through Fiddler and found out this CellRequestFail error from CellStorage.svc:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ResponseVersion Version="2" MinorVersion="0" xmlns="http://schemas.microsoft.com/sharepoint/soap/"/>
<ResponseCollection WebUrl="http://kbstg.rt.ru" xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<Response Url="http://siteurl/Lists/DocumentationListInstance/02_D-link_DSL2640_UEBRUC2E_V2.doc" RequestToken="1" HealthScore="1">
<SubResponse SubRequestToken="1" ErrorCode="Success" HResult="0">
<SubResponseData/>
</SubResponse>
<SubResponse SubRequestToken="2" ErrorCode="CellRequestFail" HResult="2147500037">
<SubResponseData Etag=""{BB1B8453-5F6F-4D05-8210-E42DB21A6711},12"" CoalesceHResult="0" ContainsHotboxData="False" HaveOnlyDemotionChanges="False">DAALAJ3PKfM5lAabFgMCAAAOAgYAAwUBbgIgAL+u/no9AyhInDE5d6/lgklaAggAZgIAADcBBwGLAQ==</SubResponseData>
</SubResponse>
</Response>
</ResponseCollection>
</s:Body>
</s:Envelope>
ULS Logs gave me:
ttidLogCellStg Sub-request rtQueryChanges failed with error ICsiError: csierrBlobHeap_ClockReversed (0x266)
If I uploaded there any new document then all will be good. Even if I downloaded an problematic document and uploaded it after by creating new item then all will be fine again.
Updated:
I made some tests on a file, so I can say that ETag in the file properties is equal to ETag which figure in SubRequest.
This is the problem in MS-FSSHTTPS protocol. The protocol is responsible for file sync of Office documents between Office client (Word) and server (SharePoint). It should reduce the amount of data transferred between client and server. Better results are get for DOCX documents but it works also with DOC files. According to the protocol documentation:
Etag: A string that specifies a unique string value that gets updated
every time the file contents are changed. The unique string gets
updated irrespective of which protocol client updated the file
contents in a co-authorable file. Anytime the protocol client
specifies the Etag attribute in a cell sub request, the server MUST
check to ensure that the Etag sent by the client matches the Etag
specified for that file on the server. If there is a mismatch of Etag
between the version specified by the client and version stored by the
server, the protocol server MUST send an error code value set to
"CellRequestFail" in the cell sub response message. The protocol
server processes this value as specified in [RFC2616].
It seems that the ETAG metadata information is corrupted in your document.

Sharepoint 2010 - Custom Document ID Provider - Document ID generated - but /_layouts/DocIdRedir.aspx?ID=ID does not work

I use a custom document ID provider. The document id gets generated which may be seen when a new file is uploaded to one of the libraries. The Document ID column of the library displays the correct document ID as per the logic in the Document ID Provider. However, if I browse to /_layouts/DocIdRedir.aspx?ID=<<NEWID>> I get the following error message
"OPERATION COMPLETED SUCCESSFULLY" No documents with ID <> were found in this site collection.
To close this question, it was a timer job issue. There is nothing that can be done about it except change the timer execution delay.

Sharepoint task list doesn't send email on item creation

I've created a custom workflow which creates a task item when the workflow is kicked off.
alt text http://img19.imageshack.us/img19/2862/screenshot310200942100p.png
I've also created a few custom content types for the document library and task list.
For the document library:
First, I add a document library and configure it to allow custom content types. Then I add my content type, which is based off the document content type. After, I add a workflow under workflow settings. Here, I select my custom workflow, give it a name and tell sharepoint to create a New task list to store the tasks in.
For the task list:
Now that I have a sharepoint created task list, I go there and allow custom content types and make sure "Send e-mail when ownership is assigned?" is set to Yes. Then I add my two custom content types which are both based off a workflow task content type. Thats all I should do.
When I start my workflow, it does add the approval task (I'm using a CreateTaskWithContentType activity which is named createApprovalTask), but no email is sent out for the created task.
The code I'm using in the createApprovalTask activity is:
// make a new GUID for this task
createApprovalTask_TaskId = Guid.NewGuid();
// set simple properties of task
createApprovalTask.TaskProperties.AssignedTo = "a valid domain\user";
createApprovalTask.TaskProperties.Title = "Review Contract: " + approvalWorkflowActivated_WorkflowProperties.Item.DisplayName;
createApprovalTask.TaskProperties.SendEmailNotification = true;
If I create a document library and use one of Sharepoint's built-in workflows (Approval for example), and tell it to create a task list for it, when an item is added to that list, it sends out the email correctly. So, the setting for the outgoing mail server are correct, as we're receiving other emails just fine.
I'm using a SendEmail activity right after the createApprovalTask activity to send an email back to the submitter telling them we've received their approval request. The code for that is something similar to:
sendApprovalRecievedEmail.Body = emailBody;
sendApprovalRecievedEmail.Subject = emailSubject;
sendApprovalRecievedEmail.To = emailTo;
sendApprovalRecievedEmail.From = emailFrom;
This works, so the submitter receives their custom email, but the task owner never receives the task item email.
Unfortunately, our mail servers were blocking the emails for some reason. I wasted a good 2 1/2 days searching around for this problem...and it turns out our IT department didn't have their sh*t together.
Thanks everyone.
you have to make sharepoint outgoing email settings properly.
example is shown in below link
http://sharepoint-amila.blogspot.com/2008/02/outgoin-email-settings.html
if you need to send an email through the c#.net code you can use below method to send emails in custom workflows.
SPUtility.SendEmail Method (Microsoft.SharePoint.Utilities)
example is shown in below link
http://www.sharepoint-amila.blogspot.com/
Is it possible to point out a SharePoint user by "domain\user" like you do with createApprovalTask.TaskProperties.AssignedTo? Isnt the ID required?
"id;#domain\username"

Resources