Solved: Issue with SharePoint Rest API Document Upload – Solving the case of the single apostrophe/quote in the URL POST

So I ran across an interesting mystery a while back that I thought I would share the fix for once I had time to document it. I have a client that uses an embeddable SharePoint page within CRM to allow document uploads right from the front entity screens without having to deviate to another screen and for the most part things have been going well. Until…the mystery began.

The problem: In some sporadic cases when uploading documents via POST to the REST API users would encounter an issue with the dynamically generated URLs from SharePoint that contain single apostrophes or quotes in the library name that would be used in the POST URL.

Errors may look like:

{"error":{code":"-1,Microsoft.SharePoint.Client.InvalidClientQueryException","message":{"lang":en-US","value":"The expression\"web/getfolderbyserverrelativeurl('yourfolder/O'Lastname, Firstname - 23424ID')/files/add(overwrite=true,url='filename.pdf')\" is not valid."}}}

The odd part about that? If you browse the library on its own, it’s fine! However, trying to post to the REST API with an improperly escape quote is not. So let’s fix that.

The solution: It’s all in how you build the URL with properly escaped characters.

Snippet in question:

    // Add the file to the file collection in the Shared Documents folder.
    function addFileToFolder(arrayBuffer) {

        // Get the file name from the file input control on the page.
        var parts = fileInput[0].value.split('\\');
        var fileName = parts[parts.length - 1];

        // Construct the endpoint.
        var fileCollectionEndpoint = String.format(
                "{0}/_api/web/getfolderbyserverrelativeurl('{1}')/files" +
                "/add(overwrite=true, url='{2}')",
                serverUrl, serverRelativeUrlToFolder, fileName);

        // Send the request and return the response.
        // This call returns the SharePoint file.
        return jQuery.ajax({
            url: fileCollectionEndpoint,
            type: "POST",
            data: arrayBuffer,
            processData: false,
            headers: {
                "accept": "application/json;odata=verbose",
                "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
                "content-length": arrayBuffer.byteLength
            }
        });

Fixed snippet:

    // Add the file to the file collection in the Shared Documents folder.
    function addFileToFolder(arrayBuffer) {

        // Get the file name from the file input control on the page.
        var parts = fileInput[0].value.split('\\');
        var fileName = parts[parts.length - 1];

        // Construct the endpoint.
        var fileCollectionEndpoint = String.format(
                "{0}/_api/web/getfolderbyserverrelativeurl('{1}')/files" +
                "/add(overwrite=true, url='{2}')",
                serverUrl, serverRelativeUrlToFolder.replace(/\%27/g,"''"), fileName);

        // Send the request and return the response.
        // This call returns the SharePoint file.
        return jQuery.ajax({
            url: fileCollectionEndpoint,
            type: "POST",
            data: arrayBuffer,
            processData: false,
            headers: {
                "accept": "application/json;odata=verbose",
                "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
                "content-length": arrayBuffer.byteLength
            }
        });

Conclusion? With the replace regex fix in place it will now take every occurance (and not just the first, thanks regex) of a single quote that come as a part of the folder directory and properly escape them when I want to post a file back with the API.

Key change:

serverRelativeUrlToFolder.replace(/\%27/g,"''")

Everybody wins now, espcially the people out there with apostrophes in there names and folder names with titles that still need the quotes in them! Hope this helps.

References:

Advertisements

Solved: The length of the URL for this request exceeds the configured maxUrlLength value.

Anyone ever run into the following before? I ran into this regarding a request into the SharePoint Rest API.

The length of the URL for this request exceeds the configured maxUrlLength value.

This because the IIS default maximum length for an URL is 260 characters. If a URL request is longer, the above error will occur.

To fix this you can increase the maxURLlength value, add it to your web.config file in the IIS virtual Directory.

<configuration>

  <system.web>

    <httpRuntime maxUrlLength="5000" />

  </system.web>

</configuration>

It will be likely you will already have most of this snippet in place so don’t break your config; just add the maxUrlLength property into your existing httpRuntime section and you should be good to go. Do know any web.config changes may cause a service interruption so test in dev, beta, QA and pre-prod before ever changing in prod! Hope this helps, questions are welcome!

Solved: Method not found: ‘!!0[] System.Array.Empty()’.

If you are getting a message for your recently developed .Net application when you publish to the server to the effect of:

ssnetframeworkerror

Chances are the server you are deploying to does not have the appropriate framework to support your app.

Download the Microsoft .Net Framework 4.6.1 and install it to resolve this. It will likely require a server reboot to complete it so don’t do it on prod mid-day! Hope this helps, questions are welcome!

Troubleshooting “Could not load file or assembly ‘DotNetOpenAuth.Core, Version=4.1.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246’ or one of its dependencies”

The Issue:

After I had updated my .Net Core on my developer machine to a newer version I went to debug a web application I had and received this error:

Could not load file or assembly 'DotNetOpenAuth.Core, Version=4.1.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

The Problem:

Here is what I had in my config prior to the update install:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="DotNetOpenAuth.Core" publicKeyToken="2780ccd10d57b246" />
        <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="DotNetOpenAuth.AspNet" publicKeyToken="2780ccd10d57b246" />
        <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

I had outdated references in my config file.

The Solution:

Ensure your references get updated after you update your development environment.

Here is what I updated to:

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="DotNetOpenAuth.AspNet" publicKeyToken="2780ccd10d57b246" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="DotNetOpenAuth.Core" publicKeyToken="2780ccd10d57b246" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

Hope that helps. Questions are always welcome.

How To Fix “no exports were found that match the constraint” In Visual Studio

So, you have that “no exports were found that match the constraint” message in Visual Studio, eh?

The first thing I would try doing on the affected version of visual studio is to go to programs and features, select the version and pick change: VSbugss3

When that loads let it repair. Once it does see if that resolves the issue.

VSbugss2

If it does not a more manual method that is to delete all of the contents of the ComponentModelCache folder from the following area (of which VS version is affected):

Put your username in the path:

VS 2012:

C:\Users\username\AppData\Local\Microsoft\VisualStudio\11.0\ComponentModelCache

VS 2013:

C:\Users\username\AppData\Local\Microsoft\VisualStudio\12.0\ComponentModelCache

VS 2015:

C:\Users\username\AppData\Local\Microsoft\VisualStudio\14.0\ComponentModelCache

It should look something like:

VSbugss1

If that fails there is also a patch that they released in response: https://www.microsoft.com/en-in/download/confirmation.aspx?id=36020#

Help! Need Help Diagnosing A 500 Errors In SharePoint? Try This…

Imagine the nightmare…you decided to sneak in a web part deployment in right before the start of the business day. Right after your deployment you see that the site is about to come back up…and…then nothing. A blank screen. In desperation you open Internet Explorer to try and see if it loads there as well..nothing but a 500 error. Then, the feeling rushes over you that this was a very bad decision. While we should address why you were doing an early morning deployment we shall spare you. 🙂 So what do you do now?

One of the best ways to see what is going on with a 500 error is to enabled Failed Request Tracing in IIS for the web site in question. Once enabled you can replicate the issue by refreshing the browser a few times; this should be more than enough to capture a few. Once captured then you will usually see where the issue is identified (especially with web.config changes that happen).

To do this:

1) Open IIS

2) Select the web site in question and open the Features View

3) Under the IIS section select “Failed Request Tracing” by double-clicking it

FRT1

4) In the top right hand corner click the message in the Alerts section

FRT2

5) When the pop-up comes up then select to enable and take the default directory (unless you need it elsewhere, then specify another location) and hit OK

FR3

6) Next, under actions select “Add…” and select “All content (*)” and click Next

FRT4

7) Indicate the status code of 500 (and others where applicable) and click next again

Frt5

8) Indicate your trace providers and click Finish

FRT6

You should now see your created Failed Request Tracing Rules.

FRT7

Now go and refresh the browser a couple times to see your error again. Once that is logged then go to the trace logs. To find that location go back to the site in features view, select Failed Request Tracing and select “View Trace Logs…”

FR8

Double click to view the recorded log (you can use IE):

FRT9

Viewing these should at least help to identify the obvious when it is a line in the web.config or when there has been a setting changed as a result of saving a configuration option in SharePoint (or 3rd party products or web parts in SharePoint). Hope this helps, happy troubleshooting. Questions are always welcome.