AWG Blogs

Thursday, January 24, 2013

XML/Javascript Mapping with Jsonix

I needed a way to edit an XML config pulled from a SharePoint List (via SPServices). So that's when I found Jsonix, which so far in my testing appears to do the job quite well.

The steps I took were:
- Load the XML in Visual Studio and click XML, Create Schema. This created two .xsd files "MySettings.xsd" and "MySettings1.xsd" (in the same directory) as Visual Studio 2010 split them out by namespace apparently. At any rate, what I had to do was edit the xs:import element in the parent XSD, adding a schemaLocation attribute with the unqualified name of the second .xsd file.

- Downloaded jsonix-scripts-1.2-all.js and jsonix-full-1.2.jar   from http://repo2.maven.org/maven2/org/hisrc/jsonix/  -- note, I tried 1.0 per the how-to on the author's site, but it didn't seem to work for me (got errors which I didn't have the time to troubleshoot); however 1.2 worked like a charm, although the generated objects are rather cryptic.

- Ran C:\temp\jsonix-samples-po-1.0>java -jar lib/jsonix-full-1.2.jar -d src/main/webapp/js src/main/resources/MySettings.xsd
This generated two folders with a Mappings.js in each folder, corresponding to the two .xsd files. I combined these two .js files into one, putting the code from generated\Mappings.js at the top of the file and the code from settingsuri\Mappings.js (assuming "SettingsURI" is the root xmlns) at the bottom.

- I then uploaded my sample .xml and the .js files to the SharePoint list and placed the following code in a test .html page.


<script type="text/javascript" language="javascript" src="jquery-1.8.3.min.js"></script>
<script type="text/javascript" language="javascript" src="jquery.SPServices-0.7.2.min.js"></script>
<script type="text/javascript" language="javascript" src="jsonix-scripts-1.2-all.js"></script>
<script type="text/javascript" language="javascript" src="BothMappings.js"></script>

<script type="text/javascript" language="javascript">

    $(document).ready(function () {
 
var context = new Jsonix.Context([ settingsuri]);

var unmarshaller = context.createUnmarshaller();
var myURL = "MySettings.xml";
unmarshaller.unmarshalURL(myURL,
function (data) {
var objectFromURL = data;
alert(objectFromURL);
});

    });

</script>

- Turn on Debugging in IE Developer tools and place a breakpoint in the callback. The local watch clearly shows objectFromURL reflects the mappings of the XML file. Pretty sweet.

Sunday, January 13, 2013

Dev on Alternate Machine

This is for when you want to work on a different SharePoint 2007 dev machine but not have to change host name configuration entries in your Silverlight code.

- edit the Windows hosts file adding
127.0.0.1 yourPrimaryServerName

- add yourPrimaryServerName as a public url for the intranet zone of your web app in the alternate access mappings

- add a host header value of "yourPrimaryServerName" to the site's IIS 6 configuration

- set DisableLoopbackCheck see http://support.microsoft.com/kb/896861
- add the following files to c:\inetpub\wwwroot (or a subdir, check IIS for the actual root dir the 80 site)

clientaccesspolicy.xml

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>

<grant-to>
<resource include-subpaths="true" path="/"></resource>
</grant-to>
</policy>
</cross-domain-access>

</access-policy>

crossdomain.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- The file must be configured to allow access to the service from any other domain,
or it is not recognized by Silverlight 4.
Save the crossdomain.xml file to the root of the domain where the service is hosted.
If, for example, the service is hosted in http://fabrikam.com,
then the file must be located at http://fabrikam.com/crossdomain.xml.
-->
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>

</cross-domain-policy>
ref

Thursday, December 13, 2012

Testing Email in SharePoint Dev Environment

Tried this. Installing local dummy SMTP not possible. Finally just configured the local SMTP Virtual Server in IIS 6.0 Manager, setting the FQDN of the local server in Advanced Delivery, leaving Smart host empty. Then in used the local server for Outbound SMTP server in CA Outgoing E-Mail Settings.

Try adding a user to a group and leaving send email checked, and, bingo, email appears in c:\inetpub\mailroot\Queue.

Monday, December 3, 2012

Finding Collapsed Groups in DataGrid

This question came up here, which I found when searching a solution to same problem.

Here is some code that solves this issue:

            List<string> grpItems = new List();
            string groupby = "";
            foreach (var control in dataGrid1.GetVisuals().OfType<DataGridRowGroupHeader>())
            {

                var tog = XamlUtils.FindVisualChild<ToggleButton>(control);
                var context = control.DataContext as CollectionViewGroup;
                string nm = context.Name.ToString();
                bool? chk = tog.IsChecked;
                if (chk != null && (bool)chk)
                {
                    grpItems.Add(nm);
                }
                groupby = control.PropertyName;
            }



The methods in XamlUtils are FindVisualChild and GetVisuals which can be found at http://blogs.msdn.com/b/wpfsdk/archive/2007/04/16/how-do-i-programmatically-interact-with-template-generated-elements-part-ii.aspx and http://blogs.msdn.com/b/kmahone/archive/2009/03/29/visualtreehelper.aspx respectively.
Note: To get this to work, for some reason, it required removal of any filters on the PagedCollectionView.

Thursday, November 1, 2012

GetListItemChangesSinceTokenAsync and Paging

It's possible to page with GetListItemChangesSinceTokenAsync. For instance, if the result returns a ListItemCollectionPositionNext value, you know there are more results.

When make the call to retrive those results however, you must set changeToken to null. When I inserted the changeToken in a query for more paged results, I got zero results, which may seem counterintuitive, but actually makes sense because adding a changeToken that implicitely pointed to the next result set would be redundant as ListItemCollectionPositionNext already indicates this.

Monday, October 1, 2012

Reproducing "The user does not exist or is not unique"

If you get this error, you may need to ensure the AD account exists:

The user does not exist or is not unique. at Microsoft.SharePoint.Library.SPRequestInternalClass.UpdateMembers(String bstrUrl, Guid& pguidScopeId, Int32 lGroupID, Int32 lGroupOwnerId, Object& pvarArrayAdd, Object& pvarArrayAddIds, Object& pvarArrayLoginsRemove, Object& pvarArrayIdsRemove, Boolean bSendEmail) at Microsoft.SharePoint.Library.SPRequest.UpdateMembers(String bstrUrl, Guid& pguidScopeId, Int32 lGroupID, Int32 lGroupOwnerId, Object& pvarArrayAdd, Object& pvarArrayAddIds, Object& pvarArrayLoginsRemove, Object& pvarArrayIdsRemove, Boolean bSendEmail)

To reproduce (in MOSS 2007):
-  Add Domain\user to AD and "Start full import" in User Profiles and Properties
- Login as user to a site collection site (assuming nt authority\authenticated users is added to default members groups)
- As user add an item to any list so that the user then appears under Peoples and Groups: All People for that site collection
- Delete user from AD and "Start full import"
- Try adding the user to a Site collection group, e.g. Members. The user will be found in the people picker but the above error occurs when you try to add user to group.
- If you re-add the exact same user (same username) to AD and do full import, the problem resolves and can add user to Members now.

Note: to avoid confusion, should probably perform "Delete Users from Site Collection" from People and Groups: All People, whenever user is removed from AD. Still looking for a way to automate this...

Monday, September 17, 2012

Debugging Silverlight to SSL'd SharePoint .asmx from VS

As explained here, there are a few steps you need to take to enable this scenario, i.e. to get around:

An error occurred while trying to make a request to URI 'https://machinename/_vti_bin/Lists.asmx'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.

Copy the following files to C:\inetpub\wwwroot\wss\VirtualDirectories\443: crossdomain.xml:
<?xml version="1.0" encoding="utf-8"?>
<!-- The file must be configured to allow access to the service from any other domain, 
or it is not recognized by Silverlight 4.
Save the crossdomain.xml file to the root of the domain where the service is hosted. 
If, for example, the service is hosted in http://fabrikam.com, 
then the file must be located at http://fabrikam.com/crossdomain.xml.
-->
<!DOCTYPE cross-domain-policy SYSTEM 
"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type"/>
  
</cross-domain-policy>
clientaccesspolicy.xml:
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
              <domain uri="http://*"/>
              <domain uri="https://*"/>
            </allow-from>

      <grant-to>
        <resource include-subpaths="true" path="/"></resource>
      </grant-to>
    </policy>
  </cross-domain-access>
  
</access-policy>
Note the subpaths="true"! Then open https://machinename/clientaccesspolicy.xml in browser (BTW verify its wellformed xml), accept the security warning, then click Certificate Error, View Certificate, then Install Certificate..., Next, then "Place all certificates in the following store", select "Trusted Root Certification Authorities", OK. After that, you should be able to F5 your Visual Studio 2010 Silverlight 5 app, and load your data from the SSL enabled Sharepoint 2007 web service. Ref1, ref2