2

I'm trying to update a SPView query, it doesn't give any error but it also doesn't update the property (SPView.Query). In SPManager 2007 it works with the resulting query of that code.

Can you spot something wrong with the following code:

int tempYear = 2010;
Int32.TryParse(ddlAnos.SelectedValue, out tempYear);
DateTime dtInicio = new DateTime(tempYear, 1, 1);
DateTime dtFim = new DateTime(tempYear, 12, 31);

string tempQuery = "<Where><And><Geq><FieldRef Name=\"Created\" /><Value IncludeTimeValue=\"TRUE\" Type=\"DateTime\">" +
    SPUtility.CreateISO8601DateTimeFromSystemDateTime(dtInicio)
    + "</Value></Geq><Leq><FieldRef Name=\"Created\" /><Value IncludeTimeValue=\"TRUE\" Type=\"DateTime\">" +
    SPUtility.CreateISO8601DateTimeFromSystemDateTime(dtFim)
    + "</Value></Leq></And></Where><OrderBy><FieldRef Name=\"Created\" Ascending=\"False\" /></OrderBy>";

foreach (SPListItem tempView in webListaVistas.Lists[ListaViews].Items)
{
    SPSite siteColl = SPContext.Current.Site;
    SPUser user = SPContext.Current.Site.Owner;

    SPWeb site = SPContext.Current.Site.OpenWeb(tempView[ListaViewsSPWeb].ToString());
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
        using (SPSite ElevatedsiteColl = new SPSite(siteColl.ID, user.UserToken))
        {
            using (SPWeb ElevatedSite = ElevatedsiteColl.OpenWeb(site.ID))
            {
                SPList listViewActual = ElevatedSite.Lists[tempView[ListaViewsNomeLista].ToString()];

                for (int i = 0; i < listViewActual.Views.Count; i++)
                {
                    if (listViewActual.Views[i].DefaultView == true)
                    {
                        listViewActual.Views[i].Query = tempQuery;
                        ElevatedSite.AllowUnsafeUpdates = true;
                        listViewActual.Views[i].Update();
                        listViewActual.Update();
                        ElevatedSite.Update();
                        ElevatedSite.AllowUnsafeUpdates = false;

                        lblInfo.Text = user.Name + "\n\n" +  tempQuery + "\n\n" + listViewActual.Views[i].Query.ToString() + "\n\n" + listViewActual.Views[i].Title + "\n\nAno alterado com sucesso: " + tempYear.ToString();
                    }
                }
            }
        }
    });
}
  • Do you say it updates the query in SPManager? If so, then what exactly are you expecting your lblInfo to display? It'll be re-written on every row in your foreach, so it'll only end up displaying the last iteration. – James Love Apr 18 '11 at 14:40
  • It doesn't update the query in SPManager, what i can do is manually update the query in SPManager with the query used in my code (So i think my problem isn't in the query). lblInfo is just for "visual debug", i only expect it to be affected when it's the default view. What i'm trying to achieve is a webpart where the user can select a year and update the filter of the default view. – David Esteves Apr 18 '11 at 14:50
  • Gotcha. Have you tried this with just the Views[i].Update() and not the two following? – James Love Apr 18 '11 at 15:32
  • Just had another look, if you call SPList.Views[i] twice, you get two separate instances of that View (SPList.Views[int i] will return new SPView), which are unrelated in terms of memory usage, so when you update the Query property of the first call, and the Update() method of the second call, the change from the first call (updating the Query property) is still persisted in memory from the first call, and the second call won't catch it. See my answer of a more efficient way to use the SPView class. – James Love Apr 18 '11 at 15:53
  • Thanks for the feedback, however i can't use the foreach, it retrieves an exception since it changes the original collection (Exception: Collection was modified; enumeration operation may not execute.) But you have a good point there, i'm gonna try to get the view by name. – David Esteves Apr 18 '11 at 16:00
4

Try this code in your Elevated block instead (inside the using SPWeb bit)..

SPList listViewActual = ElevatedSite.Lists[tempView[ListaViewsNomeLista].ToString()];

for(int i = 0; i < listViewActual.Views.Count; i++)
{
    SPView view = listViewActual.Views[i];

    if(view.DefaultView)
    {
        ElevatedSite.AllowUnsafeUpdates = true;
        view.Query = tempQuery;
        view.Update();
        ElevatedSite.AllowUnsafeUpdates = false;
        break;
    }
}
  • One last thing, calling Update on the view "Dirties" the List, so you might wanna do listViewActual.Update() just outside the for loop. – James Love Apr 18 '11 at 16:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.