19 January 2011

Silverlight Web Resources

Dynamics CRM 2011 supports Silverlight application as Web Resource. I have created with testing purpose my first Silverlight Web Resource.
How to do that you can find out in file crmsdk2011.chm in SDK folder. I can't give you direct web link for now because Microsoft still not published this in MSDN. But you can download SDK here.
I used Visual Studio 2010, but you also need to install Microsoft Silverlight 4 Tools for Visual Studio 2010. To be able to work with all OData service capabilities application must be developed for Silverlight version 4.
When you are developing Silverlight Web Resource you need to know does your Web Resource need some contextual information or not. If not you are able to place your web resource either on some entity edit form or in another HTML Web Resource. In case if Silverlight Web Resource need context information but it's placed not on entity form, you have to add reference to ClientGlobalContext.js.aspx.
In SDK is available sample of Silverlight Web Resource sdk\samplecode\cs\generalprogramming\dataservices\crmodatasilverlight. Look at crmodatasilverlight\utilities\serverutility.cs file. It's designed to retrieve server url from context. But there available another properties. I've extended these class in order to able you retrieve them all.


public static class ServerUtility
{
  private static ScriptObject PageContext
  {
    get
    {
    var xrm = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
    var page = (ScriptObject)xrm.GetProperty("Page");
    return (ScriptObject)page.GetProperty("context");
    }
  }


  public static string GetAuthenticationHeader()
  {
    return (string)PageContext.Invoke("getAuthenticationHeader");
  }


  public static double GetOrgLcid()
  {
    return (double)PageContext.Invoke("getOrgLcid");
  }


  public static string GetOrgUniqueName()
  {
    return (string)PageContext.Invoke("getOrgUniqueName");
  }


  public static JsonValue GetQueryStringParameters()
  {
    ScriptObject a = (ScriptObject)PageContext.Invoke("getQueryStringParameters");


    DataContractJsonSerializer sr = new DataContractJsonSerializer(a.GetType());
    MemoryStream ms = new MemoryStream();


    sr.WriteObject(ms, a);


    JsonValue o = JsonObject.Load(ms);


    ms.Close();


    return o;
  }


  public static string GetServerUrl()
  {
    return (string)PageContext.Invoke("getServerUrl");
  }


  public static Guid GetUserId()
  {
    return new Guid ((string)PageContext.Invoke("getUserId"));
  }


  public static double GetUserLcid()
  {
    return (double)PageContext.Invoke("getUserLcid");
  }


  public static Guid[] GetUserRoles()
  {
    IList<Object> nonCastedRoles = ((ScriptObject)PageContext.Invoke("getUserRoles")).ConvertTo<List<Object>>();
    List<Guid> castedRoles = new List<Guid>(nonCastedRoles.Count);
    foreach (var currentNonCastedRole in nonCastedRoles)
    {
    castedRoles.Add(new Guid((string)currentNonCastedRole));
    }
    return castedRoles.ToArray();
  }
}


Context is ScriptObject class object. And you can access its properties using Invoke method like PageContext.Invoke("getAuthenticationHeader")GetUserRoles and GetQueryStringParameters methods are more complicated than other. They returns not single value but JsonValue and array of Guid. In case GetUserRoles of we  used ConvertTo to convert value to List<Object>


IList<Object> nonCastedRoles = ((ScriptObject)PageContext.Invoke("getUserRoles")).ConvertTo<List<Object>>();


But in case of GetQueryStringParameters we have Json object as ScriptObject. We do ScriptObject serialization and next deserialize them into JsonValue.



ScriptObject a = (ScriptObject)PageContext.Invoke("getQueryStringParameters");

DataContractJsonSerializer sr = new DataContractJsonSerializer(a.GetType());
MemoryStream ms = new MemoryStream();

sr.WriteObject(ms, a);

JsonValue o = JsonObject.Load(ms);

Also you can use Json.Net to convert Json object directly into Dictionary<string, string>:



public static IDictionary<String, String> GetQueryStringParameters2()
{
  ScriptObject json = (ScriptObject)PageContext.Invoke("getQueryStringParameters");


  DataContractJsonSerializer sr = new DataContractJsonSerializer(json.GetType());
  MemoryStream ms = new MemoryStream();


  sr.WriteObject(ms, json);


  ms.Position = 0;
  
  var srd = new StreamReader(ms);
  var jsonstring = srd.ReadToEnd();


  IDictionary<String, String> dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonstring);


  ms.Close();


  return dic;
}


No comments:

Post a Comment