Sunday, June 20, 2021

SharePoint JSOM retrieve app url

 To retrieve app url using JSOM in sharepoint we need to reconstruct the standard tokens. This can be done as follows:


function loadAppUrl(redirectUrl, appName) {

 

    // Here, I am fetching the URL to the root site. I want to connect to this app always

    // even when in a sub site collection

    var siteUrl = _spPageContextInfo.siteAbsoluteUrl.toLowerCase().replace("https://", "").split("/")[0];

    var documentPath = "https://" + siteUrl + "/_api/contextinfo";

    $.ajax({

        url: documentPath,

        type: "POST",

        contentType: "application/x-www-url-encoded",

        dataType: "json",

        headers: {

            "Accept": "application/json; odata=verbose"

        },

        success: function (data) {

            if (data.d) {

                var webUrl = data.d.GetContextWebInformation.WebFullUrl;

 

                // Need to create a new ClientContext to create cross site collecton call

                var clientContext = new SP.ClientContext(webUrl);

                var web = clientContext.get_web();

 

                // Fetch all app instances

                var appInstances = SP.AppCatalog.getAppInstances(clientContext, web);

 

                clientContext.load(web);

                clientContext.load(appInstances);

 

                clientContext.executeQueryAsync(

                    function () {

                        var url = "";

                        if (appInstances.get_count() > 0) {

                            for (var i = 0; i < appInstances.get_count(); i++) {

                                var v = appInstances.getItemAtIndex(i);

                                try {

                                    url = v.get_appWebFullUrl();

 

                                    // Compare the name of the app with the app key, or part of the

                                    // URL to match

                                    if (url.toLowerCase().indexOf(appName.toLowerCase())) {

                                        break;

                                    }

                                } catch (e) { }

                            }

                        }

 

                        var appurl = redirectUrl +

                            "?SPLanguage=en%2DUS" +

                            "&SPClientTag=13&SPProductNumber=" +

                            _spPageContextInfo.siteClientTag.split('$$')[1] +

                            "&SPHostUrl=" + encodeURIComponent("https://" + siteUrl) +

                            "&SPAppWebUrl=" +

                            encodeURIComponent(url);

 

                        //... call another method or update a top level

                        //... parameter here to store the appurl parameter

 

                    }, function (sender, args) {

                        // .. log error here using your preferred framework

                    });

            }

        },

        error: function (err) {

            // .. log error here using your preferred framework

        }

    });

}

 

 
Reference: https://blog.lekman.com/2017/11/retrieving-sharepoint-app-url-using-jsom.html

 

Another way which I have used in my projects is to use redirect.aspx as follows

 

function AddIRISSubmisisonsUrl(appName) {

    SP.SOD.executeFunc("sp.js", "SP.ClientContext", function () {

        SP.SOD.executeFunc("sp.runtime.js", "SP.ClientContext", function () {

            var currentContext = new SP.ClientContext.get_current();

            var currentWeb = currentContext.get_web();

 

            // Fetch all app instances

            var appInstances = SP.AppCatalog.getAppInstances(currentContext, currentWeb);

 

            currentContext.load(currentWeb);

            currentContext.load(appInstances);

 

            currentContext.executeQueryAsync(

                function () {

                    console.log('Current web url is ' + currentWeb.get_url());

 

                    var url = "";

                    if (appInstances.get_count() > 0) {

 

                        for (var i = 0; i < appInstances.get_count(); i++) {

                            var v = appInstances.getItemAtIndex(i);

                            try {

                                url = v.get_appWebFullUrl();

 

                                console.log('AppWebFullUrl is ' + url);

                                // Compare the name of the app with the app key, or part of the

                                // URL to match

                                if (v.get_title().toLowerCase() === appName.toLowerCase()) {

 

                                    var appRedirectUrl = currentWeb.get_url() + '/_layouts/15/appredirect.aspx?instance_id={' + v.get_id().toString().toUpperCase() + '}';

                                    var a = document.createElement('a');

                                    var linkText = document.createTextNode("Go to My App");

                                    a.appendChild(linkText);

                                    a.title = "Go to My App";

                                    a.href = appRedirectUrl;

 

                                    var contentDiv = document.getElementsByClassName("article-content")[0];

                                    var newDiv = document.createElement('div');

                                    newDiv.appendChild(a);

                                    newDiv.setAttribute('id', 'appLinkDiv');

                                    $(contentDiv).append(newDiv);

                                    break;

                                }

                            } catch (e) { }

                        }

                    }

                },

                function (sender, args) {

                    console.log(args.get_message());

                }

            );

        });

    });

}

This method can only work if the app has been added to current web

Thursday, May 27, 2021

MVC download pdf generated from a view iText

 This is a little tricky as it involves converting html to pdf by using a tool such as iText. 

To generate the html I used a normal view like:

public ActionResult PdfView(int id)

{

    var entity = db.Customers.Find(id);

    return View(entity);   

}

Then I added a utility class which converts html to pdf using iText library

public class PdfCreator

    {

        public static byte[] ConvertToPdf(string html, string baseUri)

        {

 LicenseKey.LoadLicenseFile(HttpContext.Current.Server.MapPath(@"~/iText7/itextkey_0.xml"));

            ConverterProperties properties = new ConverterProperties();

            // Add solely one Typeface, Helevetica.

            FontProvider fp;

            properties = new ConverterProperties();

            var Helvetica = FontProgramFactory.CreateFont(StandardFonts.HELVETICA);

            var HelveticaBold = FontProgramFactory.CreateFont(StandardFonts.HELVETICA_BOLD);

            var HelveticaOblique = FontProgramFactory.CreateFont(StandardFonts.HELVETICA_OBLIQUE);

            var HelveticaBoldItalic = FontProgramFactory.CreateFont(StandardFonts.HELVETICA_BOLDOBLIQUE);

            fp = new FontProvider();

            fp.AddFont(Helvetica);

            fp.AddFont(HelveticaBold);

            fp.AddFont(HelveticaOblique);

            fp.AddFont(HelveticaBoldItalic);

            properties.SetFontProvider(fp);

            properties.SetBaseUri(baseUri);

            using (MemoryStream memoryStream = new MemoryStream())

            {

                PdfWriter writer = new PdfWriter(memoryStream);

                writer.SetCompressionLevel(CompressionConstants.BEST_COMPRESSION);

 

                // This is a crucial call. Otherwise, when we close the document, as we must do, the PDF created contains errors.

                writer.SetCloseStream(false);

 

                PdfDocument pdf = new PdfDocument(writer);

                pdf.SetDefaultPageSize(PageSize.A4);

               

                using (Document document = HtmlConverter.ConvertToDocument(html, writer, properties))

                {

                    document.SetMargins(100,100,100,100);

                }

                memoryStream.Seek(0, SeekOrigin.Begin);

                return memoryStream.ToArray();

            }

        }

    }

Next, I added another method with return type FileResult which converts this view's html to pdf and writes it to the response stream.


public FileResult DownloadPdf(int id)

        {

            var controllerContext = this.ControllerContext;

            var result = ViewEngines.Engines.FindView(controllerContext, "PdfView", null);

            ViewDataDictionary viewData = new ViewDataDictionary();

            viewData.Model = db.Entities.Find(id);

            StringWriter output;

            using (output = new StringWriter())

            {

                var viewContext = new ViewContext(controllerContext, result.View, viewData, controllerContext.Controller.TempData, output);

                result.View.Render(viewContext, output);

                result.ViewEngine.ReleaseView(controllerContext, result.View);

            }

 

            string baseUrl = Request.Url.Scheme + "://" + Request.Url.Authority + Request.ApplicationPath.TrimEnd('/') + "/Content";

            byte[] fileBytes = PdfCreator.ConvertToPdf(output.ToString(), baseUrl);

            string fileName = string.Format("Entity_{0}", id.ToString());

            return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);

        }


References:

  1. https://stackoverflow.com/questions/30121340/how-to-return-a-pdf-in-an-action-result-in-mvc
  2. https://stackoverflow.com/questions/21994933/open-pdf-in-new-tab-c-sharp
  3. https://itextpdf.com/en/products/itext-7/convert-html-css-to-pdf-pdfhtml
  4. https://stackoverflow.com/questions/18442343/get-html-from-mvc-4-view-into-a-string


Regex Email validation in c# dot net core

 Use this regex /^_?[a-zA-Z0-9]([a-zA-Z0-9]*[._+-])*[a-zA-Z0-9_]+@(?!-)[A-Za-z0-9-]{1,63}(?<!-)(\.(?!-)[A-Za-z0-9-]{1,63}(?<!-))*\.[A-...