Send Email with HTML Body in C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Mail;
using System.IO;
using System.Net.Security; 

namespace SendEmailUsingHTML
{
    class Program
    {
        static void Main(string[] args)
        {
            SendEmail(true);
        }
        private static void SendEmail(bool checkStaus)
        {
            try
            {
                if (checkStaus)
                {
                    WriteToFile("Email Started " + DateTime.Now);
                    MailMessage message = new MailMessage();
                    message.From = new MailAddress("Any Name < youremailaddress@email.com >");
                    
                    message.To.Add("towhomyouneedtosend@email.com");
                    message.Subject = "ROBO TESTING : Check " + DateTime.Now.ToShortDateString();
                    message.IsBodyHtml = true; //to make message body as html  

                    message.Body = "<html>" +
                        "<head>" +
                        "<style> " +
                            "table {width: 100 %;} table, th, td { border: 1px solid black; border-collapse: collapse; }" +
                            "th, td {padding: 15px;text-align: left;}tr: nth-child(even) {background-color: #eee;}+  tr: nth-child(odd) {background-color: #fff;}" + "th { background-color: blue;color: white;}" +
                        "</style>" +
                        "</head>" +

                        "<body>" +
                            "<table> " +
                                "<tr>" +
                                    "<th> TimeGID </th>" +
                                    "<th> Reporting Data Table</th>" +
                                    "<th> Reporting Row Count</th>  " +
                                "</tr>" +
                                " <tr>" +
                                    "<td> 101010100</td>" +
                                    "<td> Firo Reporting WFAMFIRO Portfolio </td>" +
                                    "<td> 10401 </td>" +
                                " </tr>" +
                                 " <tr>" +
                                    "<td> 1010101010</td>" +
                                    "<td> Firo Reporting WFAMFIRO Portfolio </td>" +
                                    "<td> 10401 </td>" +
                                " </tr>" +
                                 " <tr>" +
                                    "<td> 10101010010</td>" +
                                    "<td> Firo Reporting WFAMFIRO Portfolio </td>" +
                                    "<td> 10401 </td>" +
                                " </tr>" +

                             "</table>" +
                         "</body>" +
                         "</html>";

                    SmtpClient smtp = new SmtpClient();
                    smtp.Port = 587;
                    smtp.EnableSsl = true;//this is optional if your server is using SSL
                    smtp.Host = "smtpaddress"; //for gmail host  
                                                          

                    smtp.EnableSsl = false;
                    smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
                    smtp.Credentials = new NetworkCredential("emaildid", "password"); // if you are not using default credentials
                    smtp.Send(message);
                    WriteToFile("Email Sent successful " + DateTime.Now);
                }              
            }
            catch (Exception e)
            {
                var a = e.Message;
                WriteToFile("Error :SendEmail() " + a + " " + DateTime.Now);
            }
        }
        //Logging mechanism
        public static void WriteToFile(string Message)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "\\Logs";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
            if (!File.Exists(filepath))
            {
                // Create a file to write to. 
                using (StreamWriter sw = File.CreateText(filepath))
                {
                    sw.WriteLine(Message);
                }
            }
            else
            {
                using (StreamWriter sw = File.AppendText(filepath))
                {
                    sw.WriteLine(Message);
                }
            }
        }
    }
}


Sharepoint Installation issues in Windows server 2012 and 2016. http 404 issue

Tags

, , ,

While Configuring SharePoint in windows 2016 server I found the APP web list is not acceble via JSOM code. executequeryasync method was leading to failed method.

Issue message : unexpected response data from server . null

When I debugged in fiddler I found http 404 issue was coming. Intially i digged into database permissions but nothing helped.

The problem was http feature was not activated in server roles and features for .net 3.5 and 4.5/4.6.

Help : http://www.wictorwilen.se/office-web-apps-server-2013—machines-are-always-reported-as-unhealthy

Upload Files to Sharepoint Library using CSOM REST API

Tags

, , ,

public bool UploadWithRest(string orgFileName, string spFileName,  string hash, string filesFolderPath)
    {
        string resourceUrl = "";

        try
        {
            byte[] binary = System.IO.File.ReadAllBytes(filesFolderPath + orgFileName);
            string result = string.Empty;

            resourceUrl = siteUrl + "/_api/web/lists/getbytitle('" + SPLibraryName + "')/rootfolder/folders('" + hash + "')/files/add(url='" + spFileName + "',overwrite=true)";

            HttpWebRequest wreq = HttpWebRequest.Create(resourceUrl) as HttpWebRequest;
            wreq.UseDefaultCredentials = false;
            wreq.Credentials = credentials;

            wreq.Headers.Add("X-RequestDigest", currentFormDigest);
            wreq.Method = "POST";
            wreq.Timeout = 300000;
            wreq.Accept = "application/json; odata=verbose";
            wreq.ContentLength = binary.Length;

            using (System.IO.Stream requestStream = wreq.GetRequestStream())
            {
                requestStream.Write(binary, 0, binary.Length);
            }

            WebResponse wresp = wreq.GetResponse();


            using (System.IO.StreamReader sr = new System.IO.StreamReader(wresp.GetResponseStream()))
            {
                result = sr.ReadToEnd();
            }

            return true;
        }

Working with PNP Js Core .Sample code to add list items using PNP JS Core

Tags

, ,

<!--Js files can be found from Drive Folder- Sharepoint PNP JS folder for future reference -->
<html>
    <header>
        
<script  type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script> 
<script  type="text/javascript" src="http://servertfs/sites/AmRnd/RKS/PNPLibrary/es6-promise.min.js"></script> 
<script  type="text/javascript" src="http://servertfs/sites/AmRnd/RKS/PNPLibrary/fetch.js"></script> 
 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/sp-pnp-js/3.0.10/pnp.min.js"></script>  
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script>  

  
<script type="text/javascript">   
   function pnpReady() {
        
	$pnp.setup({
		baseUrl: "http://servertfs/sites/AmRnd/RKS",
		//siteUrl:"http://servertfs/sites/AmRnd/RKS",
		headers: {
            "Accept": "application/json; odata=verbose"
        },
		sp: { // If you are putting your JS files other than Siteassets
        headers: {
            "Accept": "application/json; odata=verbose"
        },
		baseUrl: "http://servertfs/sites/AmRnd/RKS"
    }
	});
	$pnp.sp.web.lists.getByTitle("Test").items.add({
    Title: "My Item Title"
});
}
   $(document).ready(function() {    
	pnpReady();
});
 
    </script>  
    </header>
    <body>
     <div id="message"></div>   
 
    </body>
</html>

 

Set People picker value Client side in Sharepoint 2013

function SetFieldValueForUser(columnNameText,userNameText)
{

ExecuteOrDelayUntilScriptLoaded(function () {
setTimeout(function () {
var ppDiv = $(“[id$=’ClientPeoplePicker’][title='”+columnNameText+”‘]”);
var ppEditor = ppDiv.find(“[title='”+columnNameText+”‘]”);
var spPP = SPClientPeoplePicker.SPClientPeoplePickerDict[ppDiv[0].id];
spPP.DeleteProcessedUser();// To delete the previous processed names (Not Mandatory to put this one)
ppEditor.val(userNameText);
spPP.AddUnresolvedUserFromEditor(true);
}, 1000);
}, “clientpeoplepicker.js”);
}

SetFieldValueForUser(‘myColumnInternalName’,”someserver\\ratikanta.sarangi”);

Infopath form publish to different server, Makecab to package

https://sharepoint.stackexchange.com/questions/17383/infopath-change-publish-location

https://blogs.msdn.microsoft.com/wael/2007/04/29/infopath-how-to-modify-the-xsn-file-and-the-inside-xml/

https://www.c5insight.com/Resources/Blog/tabid/148/entryid/613/how-to-migrate-a-sharepoint-2010-infopath-list-form-to-sharepoint-2013-or-sharepoint-online.aspx

 

Call Webservice from Sharepoint Page

Scenario : Get Site owner details using Webservice.

Used : .Net Webservice,Sharepoint CSOM to call get the details.

Input : Site URL

Output : Owner details

Hosted the Code in IIS website and in application pool configured service account user which is having permisiosn to Sharepoint sites.Enable Windows authentication inside website.Click on the website->IIS(Authentication)->Enable Windows and anonymous if required.

Create Webservice using visual studio

Ref : https://www.c-sharpcorner.com/blogs/how-to-call-asp-net-web-service-using-jquery-ajax and http://programmerguru.com/webservice-tutorial/how-to-deploy-asp-dot-net-webservice-in-iis/

Webservice : C# Code (Add Microsoft.client and client.runtime dll reference .

[WebMethod]
public string GetSIteOwners(string url)
{
var siteowners = “”;
ctx = new ClientContext(url);
web = ctx.Web;
var groups = web.AssociatedOwnerGroup.Users;

ctx.Load(groups);
ctx.ExecuteQuery();
foreach (User g in groups)
{

siteowners += g.Title + ” ; “;
}

return siteowners;

// throw new NotImplementedException();
}

 

Call the Service from Sharepoint :

http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js

function CallMyService() {
var siteurl = { url: $(“#txtInputURL”).val() };
$.ajax({
type: “POST”,
url: “http://localhost:4444/ChatBotService.asmx/GetSIteOwners&#8221;,
data: JSON.stringify(siteurl),
crossDomain: true,
contentType: “application/json”, // content type sent to server
success: ServiceSucceeded,
error: ServiceFailed
});
}
function ServiceFailed(result) {
debugger;
Log(‘Service call failed: ‘ + result.status + ‘ ‘ + result.statusText);
}

function ServiceSucceeded(result) {
debugger;
resultObject = result.d;
alert(resultObject);
}

Site URL : <input id=”txtInputURL” type=”text” />
<input id=”btnget” type=”button” value=”Getowners” onclick=”CallMyService();” />

 

Some of the issues faced while calling the webservice from Sharepoint Ajax call ;

  • XMLHttpRequest: Network Error 0x80070005, Access is denied sharepoint ajax webservice call
  • You do not have permission to view this directory or page using the credentials you supplied
  • Control-Allow-Origin’ header in the response must not be the wildcard ‘*’ when the request’s credentials mode is ‘include’. Origin ‘http://XXXXXXXX&#8217; is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
  • Request header field Content-Type is not allowed by Access-Control-Allow-Headers in prefligh
  • Request header content-type was not present in the Access-Control-Allow-Headers list.

For resolving this need to add below code inside webservice webconfig file.

 <system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name=”Access-Control-Allow-Origin” value=”*” />
      <add name=”Access-Control-Allow-Headers” value=”Content-Type, Authorization” />
      <add name=”Access-Control-Allow-Methods” value=”GET, POST, PUT, DELETE, OPTIONS” />
    </customHeaders>
  </httpProtocol>

  </system.webServer>

also if any other acces issue is there then add “Everyone” group to the webservice website virual directory folder.

 

SharePoint shortcuts and useful Javascript variables/functions

Copied from : https://praneethmoka.wordpress.com/2012/01/12/some-useful-javascript-variablesfunctions-in-sharepoint/

1. _spUserId (Variable)

This variable gives the ID of the logged in user. For an anonymous user, this variable will be empty.

var uid = _spUserId;
You can test this variable in the address bar of your browser. Try

javascript:alert(_spUserId);
You will see an alert message with the ID of the logged in user.

2. JSRequest (Object)

Using this JSRequest object, we can get the querystring, pathname and filename. Before using any of these properties, you should call JSRequest.EnsureSetup();

Ex: page url is http://www.xyz.com?qid=15

To get a querystring value

JSRequest.EnsureSetup();
var q = JSRequest.QueryString[“qid”]; // q = 15
Similarly, you can use

JSRequest.EnsureSetup();
var f = JSRequest.FileName; // current page name
var p = JSRequest.PathName; // server relative url
3. GetUrlKeyValue(parameter, noDecode, url) (Method)

GetUrlKeyValue() is a javascript function using which we can get the Query string parameter either from url in the browser or a url that we specify.

parameter(string): query string parameter from the url.

noDecode(bool): specifies whether the value has to be encoded or not. If false value is decoded, else returned as it is.(Optional)

url(string): the url from which Query string values are to be retrieved.(Optional)

Ex:

alert(GetUrlKeyValue(‘a’, false, ‘www.xyz.com?a=te%20st’));
The above statement will return the value ‘te st’. Here we are specifying our own url.

alert(GetUrlKeyValue(‘a’, false));
The above statement will look for a query string variable ‘a’ in the browser url, and returns the decoded value.

alert(GetUrlKeyValue(‘a’));
The above statement will look for a query string variable ‘a’ in the browser url.

4. _spPageContextInfo (Object)

_spPageContextInfo object has several useful properties, some are

a. webServerRelativeUrl (for current web)
b. siteServerRelativeUrl (current site collection url)
c. webLanguage (for localization)
d. currentLanguage (for localization again)
e. webUIVersion
f. userId (current user id just like _spUserId)
g. alertsEnabled (more for current page if it has any alerts on it)
h. allowSilverlightPrompt (to have that prompt or not on the page)
i. pageItemId
j. pageListId (Guid)

We can get the webServerRelativeUrl simply by saying

var url = _spPageContextInfo.webServerRelativeUrl;
All the remaining object properties can be used in the same way.

5. escapeProperly(str) (Method)

This function returns the URL encoded value of a given string.

var s = escapeProperly(“hello world!!”); //s = “hello%20world%21%21”
6. unescapeProperly(str) (Method)

This function decodes a URL encoded string.

var s = unescapeProperly(“hello%20world%21%21”); //s = “hello world!!”
7. STSHtmlEncode(htmlString) (Method)

This function encodes an html string

var s = STSHtmlEncode(”

sample text

“);
//s = ”

sample text


8. TrimSpaces(str) (Method)

This method trims out the leading and trailing white spaces of a string. It doesn’t remove spaces created by special characters such as ‘\n’, \t’

var s = TrimSpaces(” Hello World!! “); //s = “Hello World!!”
I intentionally put more spaces between ‘Hello’ and ‘World!!’ just to show that this method doesn’t remove any spaces between words.

9. TrimWhiteSpaces(str) (Method)

This method trims out the leading and trailing white spaces of a string. It also removes spaces created by special characters such as ‘\n’, \t’

var s = TrimWhiteSpaces(“\n\nHello World!!\t\t”); //s = “Hello World!!”
10. LoginAsAnother(url, bUseSource)

This method is used to login as different user.(as the name says)

url(string): the url of the page to which the new user has to be sent after login.

bUseSource(boolean): A boolean that indicates that the source will be added to the url, otherwise the source will be the window.location.href. This parameter is optional, default is false.

<a href="#" onclick="javascript:LoginAsAnother('\u002f_layouts\u002fAccessDenied.aspx?loginasanotheruser=true', 0)">Log on as a different user</a>
11. STSPageUrlValidation(url)

This function validates a url if it starts with “http” or “/” or “:” ONLY. It returns the url value back if it is a valid url and an empty value if it is an invalid url. If the url is not valid, an alert message is displayed that says “Invalid page URL:”.

var s = STSPageUrlValidation("praneethmoka.wordpress.com"); //s = praneethmoka.wordpress.com

var s = STSPageUrlValidation(“:praneethmoka.wordpress.com”); //s = “”;

var s = STSPageUrlValidation(“w.wordpress.com”); //s = “w.wordpress.com”;
Now please don’t ask me what kind of a validation this is.

STSPageUrlValidation(url) in turn calls a method PageUrlValidation(url) and here’s the code for PageUrlValidation method

function PageUrlValidation(url)
{ULSA13:;
if((url.substr(0, 4) == "http") || (url.substr(0, 1) == "/") || (url.indexOf(":") == -1))
{
return url;
}
else
{
var L_InvalidPageUrl_Text="Invalid page URL: ";
alert(L_InvalidPageUrl_Text);
return "";
}
}