Answered Redirect in Event Receiver

  • Tuesday, May 01, 2012 7:59 AM
     
     

    Hello All,

    How to redirect to another page in "ItemAdded" event receiver without canceling event?

    In my case I have created one custom list and attached a workflow to it which automatically starts when new item is created. So now when new item is added in my list I want to automatically redirect to it's task form. How can I achieve this?

    Thanks & Regards,

    Sanket Pandya

All Replies

  • Tuesday, May 01, 2012 9:01 AM
     
      Has Code

    Hello!

    Try following:

    public override void ItemAdding(SPItemEventProperties properties)
    {
        base.ItemAdding(properties);
    
        if (properties.AfterProperties["Title"].ToString() == "!RedirectToAnotherPage!")
        {
            //Redirect
            properties.Cancel = true;
            properties.RedirectUrl = "/anotherPage.aspx";
            properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
        }
    }
    
    public override void ItemAdded(SPItemEventProperties properties)
    {
        EventFiringEnabled = false;
        //Your actions
        properties.ListItem.Update();
        EventFiringEnabled = true;
    
        //Start redirecting
        var redirectItem = properties.List.Items.Add();
        redirectItem["Title"] = "!RedirectToAnotherPage!";
        redirectItem.Update();
    
        base.ItemAdded(properties);
    }
    
    Create another item with special properies (Title = "!RedirectToAnotherPage!") and catch this property in ItemAdding event where you can cancel item creating with redirect.


    Don't happy, be worry...

  • Thursday, May 03, 2012 7:03 AM
     
     

    Hello Aviw,

    Thanks for your reply.

    But it don't work for me.

    By the way, I did it in a different way. I set my "ItemAdded" Event Receiver as Synchronous and then redirect to the url using  SPUtility.Redirect from ItemAdded.

    Regards,

    Sanket Pandya

  • Thursday, May 03, 2012 8:40 AM
     
      Has Code

    Hi Sanket, 

    You cannot use the SPUtility.Redirect in the ItemAdded event receiver , as it this event happens when the user return to the Library , thus by design you cannot do it . 

    But what you can do is use the ItemAdding event to redirect , but first you need to add the item inside this event ( By writing code to do it as after rediection , Item will not be added to the list) , as the HttpContext.Current will be null in ItemAdded . This is the code for List ( it may not work for Document Library as you need to check for File CheckOut and check it in using the code ) Here is the code .

    DisableEventFiring(); 
    SPSite spsite = new SPSite(properties.WebUrl );
               SPWeb spweb = spsite.OpenWeb();
               spweb.AllowUnsafeUpdates = true;
    string customurl = //put your URL here
               SPItemEventDataCollection spitemcollection = properties.AfterProperties;
    
               System.Collections.Hashtable hashtable = properties.AfterProperties.ChangedProperties;
               foreach (DictionaryEntry dic in spitemcollection)
               {
                   
                       curlisitem[dic.Key.ToString()] = dic.Value;
                   }
    
    curlisitem.Update();
    spweb.Dispose();
               spsite.Dispose();
               curSpweb.Dispose();
    
     EnableEventFiring();
               SPUtility.Redirect(customurl, SPRedirectFlags.Trusted, HttpContext.Current);

    Hope it helps. Thanks,

    Saed

  • Thursday, May 03, 2012 10:11 AM
     
     

    SPUtility.Redirect(customurl, SPRedirectFlags.Trusted, HttpContext.Current);

    But HttpContext.Current is null in event receivers...

    My contributions: SharePoint 2010 Solution Installer

  • Thursday, May 03, 2012 11:13 AM
     
      Has Code

    Hello Aviw,

    I am able to get the HttpContext.Current.

    For that First I create a feature and on "FeatureActivated" I have added Event Receiver and set ti as synchronous using following code.

    SalesList.EventReceivers.Add(SPEventReceiverType.ItemAdded, assemblyName, strClassName);
    SPEventReceiverDefinition ev = SalesList.EventReceivers[0];
    ev.Synchronization = SPEventReceiverSynchronization.Synchronous;
    ev.Update();

    And then I created constructor for my Event Receiver like following.

    HttpContext context;
    public SalesListEventReceiver() : base()
    {
        if (null != HttpContext.Current)
        {
            context = HttpContext.Current; 
        }
    }

    And then in "ItemAdded" event receiver I am able to get context and also I am able to redirect using SPUtility.Redirect like following.

    public override void ItemAdded(SPItemEventProperties properties)
    {
        base.ItemAdded(properties);
        try
        {                
           string url = properties.WebUrl + "/Lists/Tasks/EditForm.aspx?ID=" + "101";//Instead of 101 I am using my function to get ID
    
           SPUtility.Redirect(url, SPRedirectFlags.Trusted, context);
        }
        catch (Exception ex)
        {
           Logger.Log(ex);
        }
    }

    Regards,

    Sanket Pandya

  • Monday, May 07, 2012 12:46 PM
     
     

    Hi Sanket,

    Is it working with List Item added Pop -up window, gone through the same code and getting the object value of context also in ItemAdded Event , still its not re-directing to defined url, url is also from same site,

    Please suggest , what's a issue here.

    Thanks

    Manoj Mittal


    Manoj Mittal

  • Monday, May 07, 2012 1:17 PM
     
     

    hi manoj

    you most set your "ItemAdded" Event Receiver as Synchronous in Receiver Element

  • Monday, May 07, 2012 5:47 PM
     
     

    @Aviw_

    But HttpContext.Current is null in event receivers...

    No, it's only null in asynchronous event receivers.  It's non-null in synchronous event receivers.

     

    @Sanket

    As has already been mentioned, you cannot redirect the user from the ItemAdded event as it is asynchronous, you need to redirect the user from the itemAdding event receiver.

  • Tuesday, May 08, 2012 5:47 AM
     
     

    Hi,

    'ed methods are Asynchronous by default
    'ing methods are Synchronous by default

    If we change "Event Receiver as Synchronous in Receiver Element" then also we didn't get the HttpContext.Current value which is coming as null.

    If we set option "no" for Dialog in List Advance Settings (New Form, Edit Form ) then Item Added event is redirecting to defined url.

    @sanket approach , using the static object in ItemAdding event , we are getting the value of HttpContext.current.

    My Issue  is still same: Can we redirect using the Pop-Up (List New Item Add) window also , If we are using non-dialog form , then its working fine


    Manoj Mittal

  • Tuesday, May 08, 2012 6:49 AM
     
     Answered Has Code

    Hi

    I did a small POC , which is working now , Create an empty sharepoint project - add one event receiver on custom list - i.e. Element.xml

      <Receivers ListUrl ="/Lists/PollList">
          <Receiver>
            <Name>ItemAddItemAdding</Name>
            <Type>ItemAdding</Type>
            <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
            <Class>EventApp.ItemAdd.ItemAdd</Class>
            <SequenceNumber>10000</SequenceNumber>
            <Synchronization>Synchronous</Synchronization>
          </Receiver>
          <Receiver>
            
            <Name>ItemAddItemAdded</Name>
            <Type>ItemAdded</Type>
            <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
            <Class>EventApp.ItemAdd.ItemAdd</Class>
            <SequenceNumber>10000</SequenceNumber>
            <Synchronization>Asynchronous</Synchronization>
          </Receiver>
      </Receivers>

    And C# code for Event.

        /// <summary>
        /// List Item Events
        /// </summary>
        public class ItemAdd : SPItemEventReceiver
        {
            HttpContext current;
            static object obj;
            public ItemAdd()
            {
                if (current == null)
                {
                    current = HttpContext.Current;
                }
            }
            /// <summary>
            /// An item is being added.
            /// </summary>
            public override void ItemAdding(SPItemEventProperties properties)
            {
                base.ItemAdding(properties);
                obj = current;
            }
            /// <summary>
            /// An item was added.
            /// </summary>
            public override void ItemAdded(SPItemEventProperties properties)
            {
                base.ItemAdded(properties);
                current = (HttpContext)obj;
                SPUtility.Redirect("Redirecting URL", SPRedirectFlags.Trusted, current);
            }
        }

    Its working for both Pop-Up option and without it also,

    Thanks for your suggestion dear.

    Regards


    Manoj Mittal

    • Marked As Answer by Shimin Huang Friday, May 11, 2012 8:25 AM
    •  
  • Tuesday, May 08, 2012 2:39 PM
     
     

    I would highly, highly discourage you from using that code.

    There's a reason that the current context is null in the asynchronous event, and that's because you can't be sure that the response to the user hasn't been sent by the time it starts, or finishes.

    Sometimes that code will work, and sometimes it won't.  There are a lot of different things that you can do to very easily break that code because it's reliant on a very unstable race condition.  I have seen several threads of people who were using this and then had it start consistently breaking after they made changes that they thought won't have affected it at all.

    The fact that it works for a few trivial test cases at first doesn't make it a viable solution.

  • Wednesday, May 09, 2012 4:59 AM
     
     

    If i need to redirect at ItemAdded Event ,then what approach you suggest.


    Manoj Mittal

  • Wednesday, May 09, 2012 8:19 AM
     
     Proposed Answer

    best approach may be changing Save Button in ribbon such that when clicked, a ECMA script first save your Item, then redirect to other page, or open other page in dialog.


  • Wednesday, May 09, 2012 1:24 PM
     
     

    If i need to redirect at ItemAdded Event ,then what approach you suggest.


    Manoj Mittal

    I suggest you not redirect in the item added event in the first place, as I said before.  You haven't actually told us what your problem is, you've only given us a technical problem that you want to solve (redirect in item added) without the context behind it.  Since all you've said is that you want to redirect when an item is added, why not just do that in the itemAdding event?  There isn't any real problems from redirecting the user in the item adding event.
  • Wednesday, May 09, 2012 4:28 PM
     
     

    @Aviw_

    But HttpContext.Current is null in event receivers...

    No, it's only null in asynchronous event receivers.  It's non-null in synchronous event receivers.

    It's null when item created, for example, by workflow or in datasheet list view.

    My contributions: SharePoint 2010 Solution Installer

  • Monday, May 28, 2012 3:05 PM
     
     

      There isn't any real problems from redirecting the user in the item adding event.
    if you redirect in ItemAdding, Item Addition Will be canceled.
  • Monday, May 28, 2012 7:26 PM
     
     

    if you redirect in ItemAdding, Item Addition Will be canceled.

    But you are cancelling only fake adding, with our key-word in title.

    My contributions: SharePoint 2010 Solution Installer

  • Tuesday, May 29, 2012 2:14 PM
     
     

    if you redirect in ItemAdding, Item Addition Will be canceled.
    You can disable event firing, add an item to the list with all of the fields of the item that the event receiver is trying to add, and then redirect (canceling adding of the original item).
  • Wednesday, May 30, 2012 7:11 AM
     
     

    You can disable event firing, add an item to the list with all of the fields of the item that the event receiver is trying to add, and then redirect (canceling adding of the original item).

    but It may cause save conflict.



    yaşamak bir eylemdir