Цатегори Арцхивес: Развој система СхареПоинт

Једноставно Објашњење: “Вредност не спада у очекиваном опсегу.”

УПДАТЕ: An anonymous poster left a great comment about internal names. Be sure to read it.

Када радите са догађаја пријемника и други код који је повезан СхареПоинт листе ставке путем објектног модела, Ја често правимо грешке које стварају ову грешку у рунтиме:

Грешка при учитавању и трчање догађај пријемник Цонцханго.киззиЕвентРецеивер у киззи, Версион = 1.0.0.0, Култура = неутрална, ПублицКеиТокен = 0дц50а750396ц3ац. Additional information is below. : Value does not fall within the expected range.

I think this is a fairly generic error that is potentially caused many different ways. Међутим, one simple explanation is that I’m referencing a field incorrectly. If the name of the field is "Due Date", Морам да га референцу овако догађаја у пријемнику:

пропертиес.ЛистИтем["Due Date"]

Када сам погрешно напишете или користите погрешан случај када се упућује на терен, SharePoint generates the above mentioned runtime error. На пример, ово није у реду:

пропертиес.ЛистИтем["due Date"]

</крај>

Претплатите се на мој блог.

Брз & Лако: Направите фолдер и доделити тип садржаја (Или, Имате свој КПИ и једу превише)

In order to work around a KPI problem I wrote about here, I did some testing and discovered that KPI’s work against folders with meta data in the same way that they work against documents or list items. I proved it out by creating a new content type based on the folder content type and then added a few fields. I created some indicators and proved to myself that KPIs work as expected. This was welcome news. It’s not perfect, because the drill-down you get from the KPI against the folders is not exactly what you want. This isn’t too much a drawback in my case because 1) the end users don’t know any better and 2) the drill-down goes to a folder. They click the folder name and they are at the item. It’s two clicks instead of one, which isn’t the end of the world.

This flowed nicely with the work I was doing. I am creating a folder for every document that gets uploaded. This is done via an event receiver. Као резултат тога, it’s a piece of cake to keep the parent folder’s meta data in sync with the KPI-driven meta data from the file itself since the plumbing is already in place. This allows me to have my KPI’s and eat them too 🙂

I modified the event receiver to add the folder and then set this new folder’s content type to my custom KPI-friendly content type. This bit of code did the trick:

 SPFolderCollection srcFolders = targetWeb.GetFolder("Documents").SubFolders;
  СПФолдер addedFolder = srcFolders.Add(properties.ListItem.ID.ToString());
  SPContentTypeId kpiCT = нови SPContentTypeId("0x0120002A666CAA9176DC4AA8CBAA9DC6B4039F");
  addedFolder.Item["Content Type ID"] = kpiCT;
  addedFolder.Item.Update();

To locate the actual Content Type ID, I accessed that content type via site settings and copy/pasted it from the URL as shown:

слика

</крај>

Претплатите се на мој блог!

Брзо и лако: Набавите СПФолдер једне СПЛистИтем у догађају Рецеивер

Мрзим да признам, but I struggled with this one all day. My event receiver needs to update a field of its parent folder. This little bit shows how to do it:

приватан воид УпдатеПарентФолдер(СПИтемЕвентПропертиес Некретнине)
{

СПФолдер тхисИтемФолдер = пропертиес.ЛистИтем.Филе.ПарентФолдер;
thisItemFolder.Item["ZZ Approval Status"] = "Good news, свако!";
thisItemFolder.Item.Update();


} // УпдатеПарентФолдер

У овом случају, Радим у библиотеци докумената и својства долазе из ИтемАддед догађаја.

Трик је у томе да не можете добити СПФолдер на ставке директно из саме ставке (и.е. пропертиес.ЛистИтем.Фолдер је нулл). Уместо тога, идите на вези Филе ставке листе и добити именик фајла.

</крај>

Претплатите се на мој блог!

Још један догађај пријемник Дебуг трик

I’m sure I’m not the first person to come up with this. Међутим, I haven’t noticed anyone publish a trick like this since I started paying close attention to the community last July. Тако, Мислио сам да је објавите ово брзо и једноставно дојаве дебуг.

Радим на састанак пријемнику који су почели да стварају ову грешку у 12 кошница:

Грешка при учитавању и трчање догађај пријемник Цонцханго.киззиЕвентРецеивер у киззи, Версион = 1.0.0.0, Култура = неутрална, ПублицКеиТокен = блахбалхбалх. Additional information is below. : Објекат референца није постављен на пример од објекта.

I didn’t know where I had introduced this bug because I had done too many things in one of my code/deploy/test cycles.

Покушао сам Ово решење да би мој ПДБ тамо са надом да је СхареПоинт 12 кошница ће показати траг стека, but no luck. I don’t know if it’s possible and if someone does, молим вас јавите ми 🙂

Знам да је могуће да се напишете своје поруке да 12 кошница. Frankly, Хтео сам нешто мало мање страшно и брже да спроводи.

Помислила сам да сам барем добити неке основне информације трага за хватање и поново бацају опште изузетке као што је овај:

  покушати {
    УпдатеЕдитионДате(Некретнине);
  }
  улов (Изузетак Е)
  {
    бацити нови Изузетак("Dispatcher, УпдатеЕдитионДате(): Изузетак: [" + е.ТоСтринг() + "].");
  }

Овај се појавио у 12 кошница тхусли:

Грешка при учитавању и трчање догађај пријемник Цонцханго.киззиЕвентРецеивер у киззи, Версион = 1.0.0.0, Култура = неутрална, ПублицКеиТокен = блахблахблах. Additional information is below. : Диспечер, УпдатеЕдитионДате(): Изузетак: [Систем.НуллРеференцеЕкцептион: Објекат референца није постављен на пример од објекта. at Conchango.xyzzyManagementEventReceiver.UpdateEditionDate(СПИтемЕвентПропертиес својства) at Conchango.xyzzyManagementEventReceiver.Dispatcher(СПИтемЕвентПропертиес својства, Стринг евентДесцриптион)].

То ми је све детаље ми је потребно да се прати тај одређени проблем и ја очекујем да га користите много иде напред.

</крај>

Претплатите се на мој блог!

Решење: СПКуери не тражи фасцикле

This past week I was implementing an "evolving" solution for a client that uses BDC and SPQuery and ran into some difficulty using SPQuery against a document library containing folders. Боттом лине: assign "recursive" на вид атрибутом упита.

Мој сценарио:

  • У понедељак, Ја отпремите документ и понуде неке мета податке.
  • The following week, I upload a new document. Much of this new document’s meta data is based on the document I uploaded on Monday (which we call the "master document").
  • We’ve created a web service façade that provides a BDC-friendly interface to the list so that users can easily locate that Monday document via a title search.
  • A BDC data column provides a friendly user interface. (This is part of my attempt at using BDC for a more friendly Lookup column).

The final BDC façade service uses a query like this to do the lookup:

 // Used U2U tool to assist in generating this CAML query.
      oQuery.Query =
        "<Где>";

      ако (titleFilter.Length > 0)
        oQuery.Query  =
          "  <И>";

      oQuery.Query  =
        "    <И>" +
        "      <Geq>" +
        "        <FieldRef Name=\"DocumentId\" />" +
        "        <Value Type=\"Text\">" + minId + "</Вредност>" +
        "      </Geq>" +
        "      <Leq>" +
        "        <FieldRef Name=\"DocumentId\" />" +
        "        <Value Type=\"Text\">" + maxId + "</Вредност>" +
        "      </Leq>" +
        "    </И>";

      ако (titleFilter.Length > 0)
        oQuery.Query  =
          "    <Садржи>" +
          "      <FieldRef Name=\"Title\" />" +
          "      <Value Type=\"Text\">" + titleFilter + "</Вредност>" +
          "    </Садржи>" +
          "  </И>";
      oQuery.Query  =
        "</Где>";

During the initial stage of development, this worked great. Међутим, we introduced folders into the directory to solve some problems and suddenly, my BDC picker wouldn’t return any results. I tracked this down to the fact that the SPQuery would never return any results. We used folders primarily to allow multiple files with the same name to be uploaded but with different meta data. When the file is uploaded, we create a folder based on the list item’s ID and then move the file there (I wrote about that овде; we’ve had mixed results with this approach but on the whole, it’s working well). The user don’t care about folders and in fact, don’t really understand that there are any folders. We have configured all the views on the library to show items without regard to folders.

I hit this problem twice as the technical implementation evolved and solved it differently each time. The first time, I wasn’t using the CONTAINS operator in the query. Without a CONTAINS operator, I was able to solve the problem by specifying the view on the SPQuery’s contructor. Instead of using the default constructor:

СПЛист oList = web.Lists["Documents"];

SPQuery oQuery = нови SPQuery();

I instead used a constructor that specified a view:

СПЛист oList = web.Lists["Documents"];

SPQuery oQuery = нови SPQuery(oList.Views["All Documents"]);

That solved the problem and I started to get my results.

I then added the CONTAINS operator into the mix and it broke again. It turns out that the CONTAINS operator, so far as I can tell, does not work with the view the same way as the a simpler GEQ / LEQ operators. I did some searching and learned that the query’s ViewAttributes should be set to "Recursive", као у:

oQuery.ViewAttributes = "Scope=\"Recursive\"";

That solved the problem for CONTAINS. Заправо, this also solved my original search problem and if I had specified the recursive attribute the first time, I would not have run into the issue again.

The fact that a view-based SPQuery works for some operators (GEQ/LEQ) and not others (CONTAINS), coupled with the fact that KPIs don’t seem to work at all with folder-containing document libraries leads me to believe that SPQuery has some orthogonality issues.

Special Thanks:

  • The good folks at U2U and their query tool.
  • Michael Hoffer’s great "learning by doing" блогу, comments and responses.

</крај>

Претплатите се на мој блог!

МОСС КПИ буба? Листа индикатора Везано за библиотеку докумената са фасциклама

УПДАТЕ 02/29/08: I solved this problem by creating a folder and then assigning a content type to the folder which has the meta data I need for the KPIs. Описао сам то у мало детаљније овде.

We have implemented a technical solution where users upload documents to a document library. An event receiver creates a directory and moves the file to that directory (техником слично ономе што сам написао о овде). We’ve successfully navigated around the potential issues caused by event receivers that rename uploaded files (mainly because users never start their document by clicking on "New" већ стварају документе локално и затим их отпремите).

The meta data for these documents includes a Yes/No site column called "Urgent" and another site column called "Status". We need to meet a business requirement that shows the percentage of "Urgent" documents whose status is "Pending".

Ово је обично једноставно урадити и описао сам нешто веома овако на СхареПоинт Бигл са много сцреен схот ако сте заинтересовани.

Укратко, Сам урадио следеће:

  • Create a view on the doc library called "Pending".
  • Подешавање приказа да игнорише структуру фолдера.
  • Креирање КПИ листе.
  • Create an indicator in the list that points to the doc lib and that "Pending" прегледати.

This simply does not work. The KPI shows my target (e.g. пет хитне докумената) but always shows the actual number of urgent documents as zero. Paradoxically, ако уђите у детаље, it shows the five urgent documents in the list. I created a very simple scenario with two documents, one in a folder and one not. Here is the screen shot:

слика

The above screen shot clearly shows there are two documents in the view but the "value" is one. The "CamlSchema" with blank document Id is in the root folder and the other is in a folder named "84".

Чини ми се да, иако сте навели поглед, the KPI doesn’t honor the "show all items without folders" подешавање и уместо тога, стога, само у основну фасциклу.

Ако сам у праву, молим вас пустите ми линију, или оставите коментар.

</крај>

Претплатите се на мој блог!

Тецхнорати Тагс:

Решење за проблем: “ФилеНотФоундЕкцептион” Витх Ми Феатуре Рецеивер.

I was working on a feature last week that would add some event receivers to a specific list instance. (Ја блог мало о том списку пријемник овде).

Коришћење командне линије, Могу да инсталирате функцију без грешке (али види доле за скривене грешке). When I tried to deploy the feature on the site, MOSS complained of a "FileNotFoundException" грешка. This blog entry describes how I solved it.

То је грешка која Мос ми је показао у веб претраживачу:

Feature ‘b2cb42e3-4f0a-4380-aaba-1ef9cd526f20’ could not be installed because the loading of event receiver assembly "xyzzyFeatureReceiver_0" није успело: Систем.ИО.ФилеНотФоундЕкцептион: Could not load file or assembly ‘xyzzyFeatureReceiver_0’ или један од његових зависности. Систем не може да пронађе наведену датотеку.
Филе наме: ‘xyzzyFeatureReceiver_0’
at System.Reflection.Assembly.nLoad(АссемблиНаме филеНаме, Стринг цодебасе, Докази ассемблиСецурити, Скупштина лоцатионХинт, СтацкЦравлМарк& стек земљишта, Булова тхровОнФилеНотФоунд, Булова форИнтроспецтион)
at System.Reflection.Assembly.InternalLoad(АссемблиНаме ассемблиРеф, Докази ассемблиСецурити, СтацкЦравлМарк& стек земљишта, Булова форИнтроспецтион)
at System.Reflection.Assembly.InternalLoad(Стринг ассемблиСтринг, Докази ассемблиСецурити, СтацкЦравлМарк& стек земљишта, Булова форИнтроспецтион)
at System.Reflection.Assembly.Load(Стринг ассемблиСтринг)
at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_ReceiverObject()
ВРН: Скупштина обавезујућа је евидентирање искључен.
Да би омогућили склапање бинд евидентирање неуспех, подесите вредност регистратора [ХКЦУ Софтваре Мицрософт Фусион!ЕнаблеЛог] (ДВОРД) на 1.
Приметити: Постоје неки перформанс казна повезана са скупштине везују сече отказа.
Да бисте искључили ову функцију, уклоните вредност регистратора [ХКЦУ Софтваре Мицрософт Фусион!ЕнаблеЛог].

Решавање проблема са Виндовс СхареПоинт Сервицес.

Знам како да намерно изазове ту грешку: don’t install the assembly in the GAC. Али, it was in the GAC. I normally install assemblies into the GAC by dragging them into the c:\windows\assembly folder using windows explorer. I’ve never felt 100% удобно да ради, јер сам увек мислила да је постојао гацутил разлогом … so I tried that. It made no difference.

Претражио сам интернетс и нашао овај пост: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2243677&SiteID=1

Постер десило да се користи исти корен део кода (Од унутра ВСС књиге са ове листе) so that was a hopeful sign. Међутим, Предлог украшавање скупштине са [монтажа: ] directive didn’t make sense to me. I tried it anyway and I was right. It made no difference.

Then I noticed that my class definition was not public. I made it public and that made no difference.

Следећи, I went to the trouble of enabling the "assembly bind failure log" (након корисне и тачне упутствима) and this is where things started to get interesting. That log shows me that the runtime is searching everywhere on that server for my assembly. It even appears to be searching for it in my medicine cabinet. Али … неће га потражите у ГАЦ.

I put on my winter jacket and go searching the Internets again and find that someone has had this problem too. The lengthy discussion in that posting peters off into nothing and I can’t find a solution.

I move my assembly into one of the places the log claims it’s searching and I make a little more progress. I’m rewarded with a new error in the browser when I try to activate the feature:

Failed to create feature receiver object from assembly "xyzzyFeatureReceiver_0", type "Conchango.xyzzyFeatureReceiver" за функцију б2цб42е3-4ф0а-4380-Ааба-1еф9цд526ф20: Систем.АргументНуллЕкцептион: Вредност не може бити нула.
Параметар име: тип
at System.Activator.CreateInstance(Тип, Булова нејавне)
at System.Activator.CreateInstance(Тип)
at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_ReceiverObject()

Решавање проблема са Виндовс СхареПоинт Сервицес.

Време је за последњи пут на интернетс!

Овај пут сам сазнао, предвидиво довољно, that MOSS issues this error because the assembly is not in GAC.

Ја желим да се нешто позитивно из ове и покушајте да осетите мало похвалити да сам направио Бегунац од МСИЛ склопова, but it’s not working. I’m just plain annoyed. I find myself muttering "chicken or the egg" под мој дах.

I finally decide to punt. I create an entirely new project and copy/paste the code from the incredible-cloaked-from-the-GAC-assembly non-working project over to this new project. (I look for a build flag called something like "hide from assembly binding if installed in the GAC" али не могу наћи).

Ја инсталирате функцију и активирати га и … ради! Тако, после свега што, I had to basically ‘reboot’ my project. То је још један разлог зашто мрзим рачунаре.

I did learn something useful from this. I had been installing features using the stsadm command line all day long and been using the "-force" option out of habit. For some reason, I did not use the -force option when I installed the new project. Овај пут, Ја сам заправо урадио, truly forget to copy this new project’s assembly into the GAC. Као резултат тога, I received that "FielNotFoundException" грешка. Овај пут, Добио сам је од стсадм, not when I tried to activate the feature via the web browser. Тако, -force actually plays two roles. It allows you to re-install an existing feature. It also allows you to install a buggy feature that cannot work at runtime by suppressing the error. It probably says as much in the help somewhere but I never noticed it.

</крај>

Брз & Лако: Преименовање отпремљене датотеке Коришћење СхареПоинт Објецт Модел преко Евент Рецеивер

УПДАТЕ: This works but there are significant limitations which are described in the comments. This may still be useful in some cirumstances.

УПДАТЕ 2: У мом тренутном пројекту, users always upload documents. Као резултат тога, I don’t run into a problem where MS Word is running and thinks that the file was renamed on it. I did run into a problem, "the file was modified by someone else" and solved this via a simple semaphore type flag. Users need to change a meta data field from its default value to something else. The itemupdated() пријемник тражи важећу вредност пре него што се заправо обавља преименовати и од тада, I have not had any problems. Your mileage may vary.

I have a client requirement to change the name of files uploaded to a specific document library to conform with a particular naming convention. The API does not provide a "rename()" метод. Уместо тога, користимо "MoveTo(…)". Here is a minimal bit of code to accomplish this:

 јавност заменити воид ИтемАддед(СПИтемЕвентПропертиес Некретнине)
        {
            СПФиле ф = пропертиес.ЛистИтем.Филе;

            ф.МовеТо(пропертиес.ЛистИтем.ПарентЛист.РоотФолдер.Урл + "/xyzzy.doc");
            ф.Упдате();

        }

The only tricky bit is the "properties.ListItem.ParentList.RootFolder.Url". The MoveTo() method requires a URL. That mashed up string points me to the root folder of my current document library. This allows me to avoid any hard coding in my event receiver.

То је више користан верзија која ради исту ствар, but assigns the name of the file to "Title":

 јавност заменити воид ИтемАддед(СПИтемЕвентПропертиес Некретнине)
        {
            ДисаблеЕвентФиринг();

            // Додели наслов ове ставке на име фајла самог.
 // НАПОМЕНА: Овај задатак се мора одвијати пре него што измените саму датотеку.
 // Позивање упдате() на СПФиле изгледа да поништи својства у
 // неки смисао.  Updates to "Title" није до те промене (и ажурирање() позвати)
 // су се преселили испред промена имена датотеке.
            пропертиес.ЛистИтем["Title"] = Пропертиес.ЛистИтем.Филе.Наме;

            пропертиес.ЛистИтем.Упдате();

            СПФиле ф = пропертиес.ЛистИтем.Филе;

            // Набавите продужење датотеке.  Треба да се касније.
 ниска спфилеЕкт = нови Филе Инфо(ф.Наме).Продужетак;

            // Преименујте датотеку ИД ставке листе и употребите екстензију да
 // да део нетакнут.
            ф.МовеТо(пропертиес.ЛистИтем.ПарентЛист.РоотФолдер.Урл +
                "/" + пропертиес.ЛистИтем["ID"] + спфилеЕкт);

            // Цоммит тај потез.
            ф.Упдате();

            ЕнаблеЕвентФиринг();
        }

Брзо Савет: Веб сегмент за упит садржаја, Проналажење вредности колоне и КССЛ

I have a column name in a content type named "Real Estate Location".

That column is of type "lookup".

Променили сам <ЦоммонВиевФиелдс> и ИтемСтиле.ксл да покаже колону.

Једноставан <клс:вредности од изаберите =…> враћа унутрашњу вредност која садржи податке о положају редни, као такав:

1;#Мајами

Да бисте добили људски пријатељски вредност, користите КССЛ-подстрока после, као што је приказано:

<клс:value-of select="substring-after(@ Реал_к005Ф_к0020_Естате_к005Ф_к0020_Лоцатион,'#')"></клс:вредности од>

Користите ову технику сваки пут када радите са проналажење вредности у КССЛ трансформација и треба да се људски пријатељски вредност.

<крај />

Тецхнорати Тагс: , ,

Брзо и лако: Одредите интерни назив колони колони локације

УПДАТЕ: Џереми Тхаке has blogged about this and put up some code for a console application that shows internal names.

I was trying to get a content query web part to display a due date from a task and because the screen label is "Due Date", Претпоставио сам да је колона име за коришћење у <ЦоммонВиевФиелдс> is "Due_x0020_Date".

Погрешно!

The real column name in this case was "DueDate".

How did I find it? I re-read Heather Solomon’s blog entry on modifying CQWP to show additional columns of data. She describes this process at step #13. Trust it. It’s correct. Најмање, it was correct for me. I did not trust it at first for another column with a much longer name.

I say "Trust it" because I did not trust it and probably wasted near two hours butting my head up against a wall. After I resolved the "DueDate" име, I wanted to add another field to <ЦоммонВиевФиелдс>. Using the Solomon technique, I was getting a column name like "XYZ_x0020_Project_x0020_Due_x00".

I thought to myself, that’s clearly a truncated name. I went ahead and un-truncated it with no success. I finally used the seemingly truncated name and it worked.

Bonus tip: When I was working with the CQWP, if I added a bad internal name to <ЦоммонВиевФиелдс>, the CQWP would tell me that the query had returned no results. Али, if I added a data type to the field name, it would return a result. Adding the data type actually masked a problem since I was referencing a non-existent field. I could add it, but when I tried to display its value, I would always get a blank.

This did not mask the error:

<ЦоммонВиевФиелдс>Due_x0020_Date;</CommonViewfields>

This did mask the error:

<ЦоммонВиевФиелдс>Due_x0020_Date,DateTime;</CommonViewfields>

</крај>