Search code examples
javascriptdynamics-crm-2011odatacrmdynamics-crm-online

How to query for Image saved in records Annotation using Javascript in CRM Online 2013


I have one image attached with each record in my entity. I want to show these images in the records in a web resource just like a record picture. I am using the following code:

function GetData(){
//  var base64image = document.getElementById('image').src.substr(document.getElementById('image').src.indexOf('base64')+7);

    var recordId = window.parent.Xrm.Page.data.entity.getId();  
    var serverUrl = Xrm.Page.context.getServerUrl().toString();
    var ODATA_ENDPOINT = "XRMServices/2011/OrganizationData.svc";
    var objAnnotation = new Object();
    var ODATA_EntityCollection = "/AnnotationSet";
    var temp= "/AnnotationSet?$select=DocumentBody,FileName,MimeType,ObjectId&$filter=ObjectId/Id eq guid'" + recordId + "'";
    var result =serverUrl + ODATA_ENDPOINT + ODATA_EntityCollection + temp; 


    // Parse the entity object into JSON 
    var jsonEntity = window.JSON.stringify(objAnnotation);

    // Asynchronous AJAX function to Create a CRM record using OData 
    $.ajax({
        type: "GET",
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        url: result ,
        //data: jsonEntity,
        async: false,
        beforeSend: function (XMLHttpRequest) {
            XMLHttpRequest.setRequestHeader("Accept", "application/json");
        },
        success: function(status){
            alert("success paa jee!!");
        },
        error: function (xmlHttpRequest, textStatus, errorThrown) {
            alert("Status: " + textStatus + "; ErrorThrown: " + errorThrown);
        }
    });
}
</script>

But I get an error $ is undefined when I reach the Ajax part. Basically every record has one Image in its notes attached to the entity's record and I want to show this image in a web resource as a record picture.

I am open to suggestions if there is a better/another way.

EDIT: I have edited the code and have updated the ODATA url.


Solution

  • In CRM 2011, I have used two Custom Aspx pages to show, the attached image.

    Page 1: AccountImage.aspx have the following Control:

    <asp:Image ID="IMG_Logo" runat="server" Height="50px" ImageUrl="AccountImageForm.aspx" Visible="false"  />
    

    In AccountImage.aspx On PageLoad

    if (Request.QueryString["id"] != null)
    {
       Id = new Guid(Request.QueryString["id"]);
       if (!IsPostBack)
       {
          ResetCache();
       }
       ShowImages();
    }
    

    The ShowImages() functions has below code:

    function ShowImages()
    {
      IMG_Logo.Visible = false;
      QueryExpression query = new QueryExpression("annotation");
      query.Criteria.AddCondition("objectid", ConditionOperator.Equal, Id);
      query.Criteria.AddCondition("mimetype", ConditionOperator.In, new string[] { "image/x-png", "image/pjpeg", "image/png", "image/jpeg" });
      query.Criteria.AddCondition("subject", ConditionOperator.NotEqual, "membershipcardthumbnail");
      query.Criteria.AddCondition("subject", ConditionOperator.NotEqual, "membershipcardimage");
      query.ColumnSet = new ColumnSet(true);
      EntityCollection AllLogoImageNotes = Common.Common.RetrieveMultiple(query);
      if (AllLogoImageNotes.Entities.Count > 0)
            {
             foreach (Entity Note in AllLogoImageNotes.Entities)
                {
                if (Note.Attributes.Contains("subject") && Note.Attributes.Contains("documentbody"))
                    {
                        if (Note["subject"].ToString().ToLower() == "accountlogoimage")
                        {
                            HttpRuntime.Cache.Remove("AccountLogoImage");
                            HttpRuntime.Cache.Remove("AccountLogoImageType");
                            HttpRuntime.Cache.Add("AccountLogoImage", Convert.FromBase64String(Note["documentbody"].ToString()), null, DateTime.Now.AddMinutes(5), TimeSpan.Zero, CacheItemPriority.Normal, null);
                            HttpRuntime.Cache.Add("AccountLogoImageType", Note["mimetype"].ToString(), null, DateTime.Now.AddMinutes(5), TimeSpan.Zero, CacheItemPriority.Normal, null);
                            IMG_Logo.ImageUrl = "AccountImageForm.aspx" + "?time=" + DateTime.Now.ToString();
                            IMG_Logo.Visible = true;
                           }
                    }
                }
            }
      }
    

    As you can see, the line below:

    IMG_Logo.ImageUrl = "AccountImageForm.aspx" + "?time=" + DateTime.Now.ToString();

    In AccountImageForm.aspx write below code:

    protected void Page_Load(object sender, EventArgs e)
        {
            Response.Clear();
            if (HttpRuntime.Cache["AccountLogoImage"] != null)
            {
                Response.ContentType = HttpRuntime.Cache["AccountLogoImageType"].ToString();
                byte[] data = (byte[])HttpRuntime.Cache["AccountLogoImage"];
                Response.BinaryWrite(data);
    
            }
        }
    

    In ODATA you can do the following:

      retrieveImages("/AnnotationSet?$select=DocumentBody,MimeType&$filter=ObjectId/Id eq guid'" + Xrm.Page.data.entity.getId()+ "'", function (JsonObject) {
        if (JsonObject != null) {
            //  debugger;
                var ByteString= JsonObject[0].DocumentBody;
                var MimeType =  JsonObject[0].MimeType
        }
    
    
     function retrieveImages(query, SuccessFunc) {
    var retrieveRecordsReq = new XMLHttpRequest();
    var ODataPath = Xrm.Page.context.getServerUrl() + "/xrmservices/2011/OrganizationData.svc";
    retrieveRecordsReq.open('GET', ODataPath + query, false);
    retrieveRecordsReq.setRequestHeader("Accept", "application/json");
    retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    retrieveRecordsReq.onreadystatechange = function () {
        if (this.readyState == 4 /* complete */) {
            if (this.status == 200) {
                this.onreadystatechange = null; //avoids memory leaks
                var data = JSON.parse(this.responseText, SDK.REST._dateReviver);
                if (data && data.d && data.d.results)
                    SuccessFunc(JSON.parse(this.responseText, SDK.REST._dateReviver).d.results);
            }
            else {
                alert(SDK.REST._errorHandler(this));
            }
        }
    };
    retrieveRecordsReq.send();
    }