2011-01-11 7 views
5

Utworzono typ zawartości TypeA, który ma pole odnośnika do podstawowej listyB. Następnie tworzę Listę, która wykorzystuje TypeA. Wszystko jest tworzone programowo.Programowo wygenerowane pole wyszukiwania powoduje "Wyjątek System.ArgumentException: wartość nie mieści się w oczekiwanym zakresie" podczas tworzenia nowego elementu

Wyjątek jest zgłaszany, gdy ma zostać załadowany modalny moduł "dodaj nowy element" ListA. Dzieje się tak tylko wtedy, gdy ListB zawiera elementy. Jeśli ListB jest pusta, lista jest „dodać nowy element” modalnych obciążeń i pola odnośnika do ListB poprawnie wyświetla ślad (None)

stosu:

System.ArgumentException: Value does not fall within the expected range. 

at Microsoft.SharePoint.SPFieldMap.GetColumnNumber(String strFieldName, Boolean bThrow) 
at Microsoft.SharePoint.SPListItemCollection.GetColumnNumber(String groupName, Boolean bThrowException) 
at Microsoft.SharePoint.SPListItemCollection.GetRawValue(String fieldname, Int32 iIndex, Boolean bThrow) 
at Microsoft.SharePoint.SPListItem.GetValue(SPField fld, Int32 columnNumber, Boolean bRaw, Boolean bThrowException) 
at Microsoft.SharePoint.SPListItem.GetValue(String strName, Boolean bThrowException) 
at Microsoft.SharePoint.SPListItem.get_Item(String fieldName) 
at Microsoft.SharePoint.WebControls.LookupField.get_DataSource() 
at Microsoft.SharePoint.WebControls.LookupField.CreateChildControls() 
at System.Web.UI.Control.EnsureChildControls() 
at Microsoft.SharePoint.WebControls.BaseFieldControl.OnLoad(EventArgs e) 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 

Metody używam do tworzenia typ treści, listy, i pole odnośników:

private SPContentType createContentType(SPSite site, string typeName, string groupName, string parentTypeName, string[] fields) { 
     try { 
      SPContentType testExist = site.RootWeb.ContentTypes[typeName]; 
      if (testExist != null) 
       return testExist; 
     } 
     catch { } 

     SPContentType parentType = site.RootWeb.ContentTypes[parentTypeName]; 

     SPContentType contentType = new SPContentType(parentType, site.RootWeb.ContentTypes, typeName); 
     contentType.Group = groupName; 

     foreach (string field in fields) { 
      contentType.FieldLinks.Add(new SPFieldLink(site.RootWeb.GetField(field))); 
     } 
     contentType.FieldLinks["Title"].Required = false; 
     contentType.FieldLinks["Title"].Hidden = true; 

     site.RootWeb.ContentTypes.Add(contentType); 
     contentType.Update(); 
     return contentType; 
    } 

    public SPFieldLookup createLookupField(string fieldName, string groupName, Guid listGuid, string lookupField, bool allowMultipleValues, bool isRequired) { 
     if (site.RootWeb.Fields.ContainsField(fieldName)) 
      return null; 
     string internalName = site.RootWeb.Fields.AddLookup(fieldName, listGuid, isRequired); 
     SPFieldLookup lookup = site.RootWeb.Fields.GetFieldByInternalName(internalName) as SPFieldLookup; 
     lookup.AllowMultipleValues = allowMultipleValues; 
     lookup.LookupField = lookupField; 
     lookup.Group = groupName; 
     lookup.Update(); 
     return lookup; 
    } 

    public SPList createList(string listName, string description, SPContentType contentType) { 

     if (web.Lists.TryGetList(listName) != null) 
      web.Lists[listName].Delete(); 
     Guid newListGuid = web.Lists.Add(listName, description, SPListTemplateType.GenericList); 
     SPList newList = web.Lists[newListGuid]; 
     newList.OnQuickLaunch = true; 
     newList.Update(); 

     newList.ContentTypesEnabled = true; 
     SPContentType newType = newList.ContentTypes.Add(contentType); 
     newList.Update(); 
     newList.ContentTypes["Item"].Delete(); 
     newList.Update(); 
     newList.Fields["Title"].Required = false; 
     newList.Fields["Title"].Hidden = true; 
     newList.Fields["Title"].Update(); 

     SPView view = newList.DefaultView; 
     foreach (SPField field in newType.Fields) { 
      view.ViewFields.Add(field); 
     } 
     view.ViewFields.Delete("Title"); 
     view.ViewFields.Delete("LinkTitle"); 
     view.ViewFields.Delete("ContentType"); 
     view.Update(); 

     return newList; 
    } 

Przykład

SPContentType typeB = createContentType(site, "Type B", "My Group", "Item", new string[] {"Salary"}); 
SPList listB = createList("List B", "my list b", typeB); 
SPFieldLookup lookupB = createLookupField("B", "My Group", listB.ID, "Salary", false, false); 
SPContentType typeA = createContentType(site, "Type A", "My Group", "Item", new string[] {"Name", "B"}); 
SPList listA = createList("List A", "my list a", typeA); 

Odpowiedz

4

Właściwość SPFieldLookup.LookupField wymaga nazwy wewnętrznej pola.

Rozwiązanie to zrobić następującą zmianę (na przykład):

SPFieldLookup lookupB = createLookupField("B", "My Group", listB.ID, listB.Fields["Salary"].InternalName, false, false);