Tuesday, April 15, 2014

Disable Sharepoint item events firing during item update

In Sharepoint, the attached item events are fired whenever you perform an item.Update(),so if you to want to restrict it for event firing you can use following code,

class DisabledItemEventsScope : SPItemEventReceiver, IDisposable
{
    bool oldValue;
    public DisabledItemEventsScope()
    {
        this.oldValue = base.EventFiringEnabled;
        base.EventFiringEnabled = false;
    }
    #region IDisposable Members
    public void Dispose()
    {
        base.EventFiringEnabled = oldValue;
    }
    #endregion
}

Now we can use this class together with the using syntax to create a scope within all item event firing is disabled.

using (DisabledItemEventsScope scope = new DisabledItemEventsScope())
{
    item.SystemUpdate(); // will NOT fire events
}
item.SystemUpdate(); // will fire events again

or other way to achieve this are,



public static class SPListItemExtension
{
public static void UpdateDisableItemEvents(this SPListItem item)
{
using (DisabledItemEventsScope scope = new DisabledItemEventsScope())
{
item.Update();
}
}
}

and call it in your code as follows:
item.UpdateDisableItemEvents();

Friday, March 28, 2014

Using Membership Provider in SharePoint 2010 Event Receiver

If we have Claims-based authentication and Membership database hooked in the SharePoint, a very common scenario could be adding new user to the membership database within SPList event handler (let’s say in ItemAdding). We would like to check there if the user already exists there, if so to redirect to our custom error page, of not – just add it to the membership database.

Well, if you just try to access the membership database and fetch all the users you will end up with “NullReferenceException”.



Well, if you dig around about problems like this, you can see some helpful posts stating that HtppContext is null in the Event handlers for SharePoint list.
Could that be the reason? And that is weird, because we instantly would ask ourselves – what has SqlMembershipProvider in common with the HttpContext? And the natural answer of course is – nothing (well, GetCurrentUserName() relies, but if we take a look in its body, it should definitely not bring to null reference exception).

But, if we really take a look at the stack trace of the exception we will see that what is called is not the method of SqlMembershipProvider, but the method of SPClaimsAuthMembershipProvider.
If we open the reflector and see what’s happening in its methods, we will get answered right away!
StackTrace:
at Microsoft.SharePoint.Administration.Claims.SPClaimsAuthProviderUtility.GetPassthroughMembershipProvider()
at Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider.GetAllUsers(Int32 pageIndex, Int32 pageSize, Int32& totalRecords)
at System.Web.Security.Membership.GetAllUsers()
at MySolution.Code.EventHandlers.RegisterUsersEventHandlers.<>c__DisplayClass1.b__0()
at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.b__2()
at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)


If we use the reflector and check the body of called methods we will see next:





And the reason for calling SPClaimsAuthMembershipProvider is the fact that it is the default provider used according the web.config of our application.
Knowing what the reason is, makes fixing the problem achievable in 2 different ways. Let’s quickly review the solutions:

Solutions:
1) Continue to rely on SPClaimsAuthMembershipProvider and obtaining HttpContext.Current

Just instantiate the HttContext.Current If it is null:

if (HttpContext.Current == null)
{
HttpRequest request = new HttpRequest(String.Empty, sp_web.Url, String.Empty);
HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));
}



If you instantiated new HttpContext, it would be good to reset it at the end of your methods back to null. Just make sure this happens only if HttpContext.Current was null at the beginning.

2) Working with the SqlMembershipProvider and forgetting about HttpContext.Current issue

What we need is to get the SqlMembershipProvider from registered providers and to start using it.
SqlMembershipProvider sqlMembershipProvider = (SqlMembershipProvider)Membership.Providers["FBAMembershipProvider"];

Bear in mind that you should put the name as it is in your web.config file.

Tuesday, March 18, 2014

Update Modified By field in sharepoint 2010 list


Sometimes we need to insert/update item using
“SPSecurity.RunWithElevatedPrivileges(delegate(){});” for getting the Administrator privilege..

But as a result of that we see the “System Account” as a value of "Modified By" field of that inserted/updated item, instead of the original user who actually did the modification.

In this case, we need to update the "Modified By" field in the time of inserting/updating. It may not work if we assign a value for the "Modified By" field and call the Update method.

So we have to use the "UpdateOverwriteVersion()" method. This method allows for the setting of properties on a SPListItem object without creating a separate version of the item. This method also allows for setting of certain system properties such as Created(date), Modified(date), Author(Created By) and Editor(Modifies By).

These are the following code by which we can easily update Modified By field:-

using (SPSite oSite = new SPSite(SPContext.Current.Web.Url))


 {
   using (SPWeb oWeb = oSite.OpenWeb())
   {
      //Variable to store the user
      SPUser oUser = oWeb.CurrentUser;
      oWeb.AllowUnsafeUpdates = true;

      SPFieldUserValue userVal = new SPFieldUserValue(oWeb, oUser.ID, oUser.LoginName);

      SPList oList = oWeb.Lists["ListName"];
      SPListItem oItem = oList.GetItemById(Item Id);

      oItem["Modified By"] = userVal;
                OR
      oItem[SPBuiltInFieldId.Editor] = userVal;
                OR
      oItem[“Editor”] = userVal;

      oItem.UpdateOverwriteVersion();

      oWeb.AllowUnsafeUpdates = false;
   }
}

Wednesday, February 19, 2014

The Web application at could not be found. Verify that you have typed the URL correctly.

When we work on SharePoint console application we generally get this error "The Web application at could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application".

Solution:

1) Goto the properties of solution,change platform target x64 in build tab.

  

 2) Change the target framework to 3.5  in application tab.


Monday, February 10, 2014

Enable Anonymous Access in SharePoint 2010

There are the simple steps for configuration of enable anonymous access in Sharepoint 2010

1. Starting in Central Administration, under Application Management, click on the Manage web applications.
Anonymous Access Set Up Step 1
2. Make sure you select the site you want to enable anonymous access and click on the Authentication Providers icon.
 Anonymous Access Set Up Step 2
3. On the Authentication Providers pop-up window click on the Default zone.
 Anonymous Access Set Up Step 3
4. Under Edit Authentication, check Enable anonymous access and click Save.
Anonymous Access Set Up Step 4

5. Going back to Web Application Management click on the Anonymous Policy icon.

 Anonymous Access Set Up Step 5
6. Under Anonymous Access Restrictions select your Zone and set the Permissions to None – No policy and click Save.
Anonymous Access Set Up Step 6
7. Now, web application will allow anonymous access to be set. So, navigate to your top level site collection for the web application. Click the Site Actions > Site Settings. Under Users and Permissions click Site permissions.
Anonymous Access Set Up Step 7 Anonymous Access Set Up Step 8Anonymous Access Set Up
Now your anonymous access is enabled.

Friday, January 10, 2014

SPUtility.SendEmail Issue in CSS styles applied to an email when sending email from SharePoint

Recently I was working on a timer job that sends (html) emails via SharePoint's SPUtility.SendEmail function. The CSS styles I used in the email body were being inconsistently applied to the email when viewed in Outlook 2010. The method I was using was:

Create the email body, applying the styles at the top of the email body.
emailBody.Append(AddStyles());
emailBody.Append(body);

Send the email setting the fAppendHtmlTag parameter to true.
SPUtility.SendEmail(web, true, false, recipient, subject, emailBody)

To fix the issue, I set the fAppendHtmlTag parameter to false, instead adding the HTML tags myself, as such:
var body = String.Format("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=8\" /><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />{0}</head><body>{1}</body></html>", AddStyles(), emailBody);

Then send the email:
SPUtility.SendEmail(web, false, false, recipient, subject, body)

This worked nicely, and the CSS styles were now applied consistently throughout the body of the email.

 but if you further find some issue you can below method for sending mail

public static bool SendMailUitility(SPWeb web, string Subject, string Body, bool IsBodyHtml, string From, string To, string Cc, string Bcc)
        {
            bool mailSent = false;
            try
            {
                SmtpClient smtpClient = new SmtpClient();
               
               // smtpClient.Host = SPContext.Current.Site.WebApplication.
                smtpClient.Host = web.Site.WebApplication.
                OutboundMailServiceInstance.Server.Address;
                MailMessage mailMessage = new MailMessage(From, To, Subject, Body);
                if (!String.IsNullOrEmpty(Cc))
                {
                    MailAddress CCAddress = new MailAddress(Cc);
                    mailMessage.CC.Add(CCAddress);
                }
                if (!String.IsNullOrEmpty(Bcc))
                {
                    MailAddress BCCAddress = new MailAddress(Bcc);
                    mailMessage.Bcc.Add(BCCAddress);
                }
                mailMessage.IsBodyHtml = IsBodyHtml;
                smtpClient.Send(mailMessage);
                mailSent = true;
            }
            catch (Exception) { return mailSent; }
            return mailSent;
        }

    }
}


or using gmail smtp

   public void SendMailThroughGmail(string subject, string Body)
        {

            MailMessage mail = new MailMessage();
            SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
            mail.From = new MailAddress("abc100@gmail.com");
            mail.To.Add("newemail@7p.com");
            mail.IsBodyHtml = true;
            mail.Subject = subject;
            mail.Body = Body;
            //Attachment attachment = new Attachment(filename);
            //  mail.Attachments.Add(attachment);

            SmtpServer.Port = 25;
            SmtpServer.Credentials = new System.Net.NetworkCredential("abc100@gmail.com", "******");
            SmtpServer.EnableSsl = true;
            SmtpServer.Send(mail);

        }



Thursday, January 2, 2014

Referenced assembly does not have a strong name

when you are using third party .dll files or cause is an assembly is not signed with a strong name, the strong name could not be verified, or the strong name would not be valid without the current registry settings of the compute.

The strong name protects clients from unknowingly loading an assembly that has been tampered with. Assemblies without strong names should not be deployed outside of very limited scenarios.

An assembly without a strong name  cannot be loaded into the global assembly cache.


Step 1 : Run visual studio command prompt and go to directory where your DLL located.

  For Example my DLL located in D:/test/perceptiveMCAPI.dll


Step 2 : Now create il file using below command.

  D:/test> ildasm /all /out=perceptiveMCAPI.il  perceptiveMCAPI.dll
  (this command generate code library)


Step 3 : Generate new Key for sign your project.

  D:/test> sn -k mykey.snk


Step 4 : Now sign your library using ilasm command.

  D:/test> ilasm /dll /key=mykey.snk perceptiveMCAPI.il

so after this step your assembly contains strong name and signed.
just add reference this new assembly in your project and compile project its running now. 

If  your current assemble framework is 2.0 or lesser and your system contain higer framework 4.0 then strong name assemble generated in 4.0 framework. If you want to generate assemble in 2.0 frame work you change Step 4 as

D:/test>C:\Windows\Microsoft.NET\Framework\v2.0.50727\ ilasm /dll /key=mykey.snk perceptiveMCAPI.il

In this step you generate assemble in 2.0 framework