Web.config issue - The given key was not present in the dictionary - c#

I have ran into a really annoying issue which gives me this error: "The given key was not present in the dictionary."
What I don't get is that it worked perfectly as intedded last friday and the days before that. I have debugged, checked if the webservice files were intact etc. It all fits.
All I did last friday was running a script which ran trough all of the items in my list which contains the article pages and edited their creation date. I don't know if that could have changed something, but that's the only thing I can recall.
ASPX.CS
protected void Page_Load(object sender, EventArgs e)
{
var listId = Request.QueryString["ListID"];
var itemId = Request.QueryString["ItemID"];
try
{
var spList = SPContext.Current.Web.Lists[new Guid(listId)];
var item = spList.GetItemById(int.Parse(itemId));
var image = (ImageFieldValue)item["PublishingPageImage"];
var contentType = (string)item["ContentType"];
var pageLayout = (string) item["PublishingPageLayout"];
var news = new News
{
Title = (string)item["Title"],
NewsId = item.UniqueId,
Content = (string)item["PublishingPageContent"],
ArticleDate = item["ArticleStartDate"] == null ? DateTime.Now : (DateTime)item["ArticleStartDate"],
PageName = item.File.Name,
Author = new SPFieldUserValue(SPContext.Current.Web, (string)item["Author"]).User.LoginName,
IsArticle = contentType.Contains("Article"),
PageLayout = GetLayout(pageLayout),
Image = GetImage(image)
};
// Jumps to the WSInstance class.
WSInstance.InternetInstance().PublishNews(news); // This line throws the exception.
lblMessage.Text = "News '<i>" + news.Title + "</i>' have been published succesfully to the Internet site.";
}
catch (Exception ex)
{
EventLogger.LogError("Error occured while publishing news: " + ex.Message + "\n" + ex.StackTrace, this);
}
}
WSINSTANCE
public static WSIntegration InternetInstance(SPSite spSite)
{
// Jumps to the Configuration class.
var url = Configuration.GetConfigurationValue("Progressive.WS.Internet", spSite);
...
return new WSIntegration
{
Credentials = new NetworkCredential(username, password, domain),
Url = url
};
}
public static WSIntegration InternetInstance()
{
return InternetInstance(SPContext.Current.Site);
}
CONFIGURATION
public static class Configuration
{
public static string GetConfigurationValue(string key, SPSite site)
{
var name = site.WebApplication.IisSettings[site.Zone].ServerComment; // This is where it fails and throws the error: "The given key was not present in the dictionary."
var value = "";
SPSecurity.RunWithElevatedPrivileges(() => { value = WebConfigurationManager.OpenWebConfiguration("/", name).AppSettings.Settings[key].Value; });
return value;
}
}
The section which it gets hold of the data from the web.config file.
<appSettings><add key="Progressive.WS.Internet" value="http://shpt02/_layouts/DR/WSIntegration.asmx" /> // This is the key value it cannot find.
<add key="Progressive.WS.Internet.Username" value="user" />
<add key="Progressive.WS.Internet.Password" value="password" />
<add key="Progressive.WS.Internet.Domain" value="domain" /></appSettings>

The error says that it can't find the site's Zone in the IisSettings dictionary. You should check both the value of the Zone property and the contents of the IisSettings dictionary. They may not contain the values you expect, since you access the IisSettings outside RunWithElevatedPrivileges, ie. with the end user's access rights.
In any case storing application settings in web.config is not the best option in SharePoint, as a web application hosts many site collections and sites. Modifying it causes all the sites to restart and recompile - not a good end user experience!
Check the Application Settings Manager section in the Sharepoint 2010 Guidance for an alternative way that stores settings in the appropriate site's property bag.

Saw Steve's comment and agree that any pointers to where the error is occuring would be good. Is this Silverlight (or WPF)? If so, it can be a styling name you used in your XAML is not present in the dictionary. Check names carefully and determine if there is an issue here.
Both are possible locations for the issue. Naming issues are often missed as you run through code.

Related

IsolatedStorage and navigation

I can't sort this weird issue out and I have tried anything and everything I can think of.
I got 5 pages, everyone of them passing variables with navigation this way:
Pass:
NavigationSerice.Navigate(new Uri("/myPage.xaml?key=" + myVariable, UriKind.Relative));
Retrieve:
If (NavigationContext.QueryString.ContainsKey(myKey))
{
String retrievedVariable = NavigationContext.QueryString["myKey"].toString();
}
I open a list on many pages and one of the pages automatically deletes an item from the list actualProject (actualProject is a variable for a string list). Then, when I go so far back that I reach a specific page - the app throws an exception. Why? I have no idea.
The code that deletes the item:
// Remove the active subject from the availible subjects
unlinkedSubjects.Remove(actualSubject);
unlinkedsubjectsListBox.ItemsSource = null;
unlinkedsubjectsListBox.ItemsSource = unlinkedSubjects;
Then the page that throws the exception's OnNavigatedTo event:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (NavigationContext.QueryString.ContainsKey("key"))
{
actualProject = NavigationContext.QueryString["key"];
try
{
//Read subjectList from IsolatedStorage
subjectList = readSetting(actualProject) != null ? (List<String>)readSetting(actualProject) : new List<String>();
//Put the subjectList into the subjectListBox
subjectListBox.ItemsSource = subjectList;
//Set the subjectsPageTitle to the "actualProject" value, to display the name of the current open project at the top of the screen
subjectsPageTitle.Text = actualProject;
}
catch (Exception)
{
if (language.Equals("en."))
{
// Language is set to english
MessageBox.Show("Couldn't open the project, please try again or please report the error to Accelerated Code - details on the about page");
}
else if (language.Equals("no."))
{
// Language is set to norwegian
MessageBox.Show("Kunne ikke åpne prosjektet, vennligst prøv igjen eller rapporter problemet til Accelerated Code - du finner detaljer på om-siden");
}
}
}
}
Exception:
_exception {System.ArgumentException: Value does not fall within the expected range.} System.Exception {System.ArgumentException}
My theory:
The app kind of loads the currently opened and modified List. Is that possible? No idea.
So there are a number of ways to pass data between pages.
The way you have chosen is the least suggested.
You can use the PhoneApplicationService.Current dictionary but this is messy also if you have a ton of variables, doesn't persist after app shut down and could be simplified.
I wrote a free DLL that kept this exact scenario in mind called EZ_iso.
You can find it here
Basically what you would do to use it is this.
[DataContractAttribute]
public class YourPageVars{
[DataMember]
public Boolean Value1 = false;
[DataMember]
public String Value2 = "And so on";
[DataMember]
public List<String> MultipleValues;
}
Once you have your class setup you can pass it easily between pages
YourPageVars vars = new YourPageVars { /*Set all your values*/ };
//Now we save it
EZ_iso.IsolatedStorageAccess.SaveFile("PageVars",vars);
That's it! Now you can navigate and retrieve the file.
YourPageVars vars = (YourPageVars)EZ_iso.IsolatedStorageAccess.GetFile("PageVars",typeof(YorPageVars));
This is nice because you can use it for more than navigation. You can use it for anything that would require Isolated storage. This data is serialized to the device now so even if the app shuts down it will remain. You can of course always delete the file if you choose as well.
Please make sure to refer to the documentation for any exceptions you have. If you still need help feel free to hit me up on twitter #Anth0nyRussell or amr#AnthonyRussell.info

NetSuite custom record search through suiteTalk using C#

We are having an issue with searching a custom record through SuiteTalk. Below is a sample of what we are calling. The issue we are having is in trying to set up the search using the internalId of the record. The issue here lies in in our initial development account the internal id of this custom record is 482 but when we deployed it through the our bundle the record was assigned with the internal Id of 314. It would stand to reason that this internal id is not static in a site per site install so we wondered what property to set up to reference the custom record. When we made the record we assigned its “scriptId’ to be 'customrecord_myCustomRecord' but through suitetalk we do not have a “scriptId”. What is the best way for us to allow for this code to work in all environments and not a specific one? And if so, could you give an example of how it might be used.
Code (C#) that we are attempting to make the call from. We are using the 2013.2 endpoints at this time.
private SearchResult NetSuite_getPackageContentsCustomRecord(string sParentRef)
{
List<object> PackageSearchResults = new List<object>();
CustomRecord custRec = new CustomRecord();
CustomRecordSearch customRecordSearch = new CustomRecordSearch();
SearchMultiSelectCustomField searchFilter1 = new SearchMultiSelectCustomField();
searchFilter1.internalId = "customrecord_myCustomRecord_sublist";
searchFilter1.#operator = SearchMultiSelectFieldOperator.anyOf;
searchFilter1.operatorSpecified = true;
ListOrRecordRef lRecordRef = new ListOrRecordRef();
lRecordRef.internalId = sParentRef;
searchFilter1.searchValue = new ListOrRecordRef[] { lRecordRef };
CustomRecordSearchBasic customRecordBasic = new CustomRecordSearchBasic();
customRecordBasic.recType = new RecordRef();
customRecordBasic.recType.internalId = "314"; // "482"; //THIS LINE IS GIVING US THE TROUBLE
//customRecordBasic.recType.name = "customrecord_myCustomRecord";
customRecordBasic.customFieldList = new SearchCustomField[] { searchFilter1 };
customRecordSearch.basic = customRecordBasic;
// Search for the customer entity
SearchResult results = _service.search(customRecordSearch);
return results;
}
I searched all over for a solution to avoid hardcoding internalId's. Even NetSuite support failed to give me a solution. Finally I stumbled upon a solution in NetSuite's knowledgebase, getCustomizationId.
This returns the internalId, scriptId and name for all customRecord's (or customRecordType's in NetSuite terms! Which is what made it hard to find.)
public string GetCustomizationId(string scriptId)
{
// Perform getCustomizationId on custom record type
CustomizationType ct = new CustomizationType();
ct.getCustomizationTypeSpecified = true;
ct.getCustomizationType = GetCustomizationType.customRecordType;
// Retrieve active custom record type IDs. The includeInactives param is set to false.
GetCustomizationIdResult getCustIdResult = _service.getCustomizationId(ct, false);
foreach (var customizationRef in getCustIdResult.customizationRefList)
{
if (customizationRef.scriptId == scriptId) return customizationRef.internalId;
}
return null;
}
you can make the internalid as an external property so that you can change it according to environment.
The internalId will be changed only when you install first time into an environment. when you deploy it into that environment, the internalid will not change with the future deployments unless you choose Add/Rename option during deployment.

Why do I get "Object reference not set to an instance of an object." when changing pages in asp.net

I have a master page that set ups some variables that I want to use across the site..
protected void Page_Load(object sender, EventArgs e)
{
//Get users name from AD
str_DomainName = HttpContext.Current.User.Identity.Name;
str_CurrentLogin = str_DomainName.Substring(5);
//Display current user information
DirectorySearcher search = new DirectorySearcher("LDAP://DCHS");
search.Filter = String.Format("(SAMAccountName={0})", str_CurrentLogin);
SearchResult result = search.FindOne();
DirectoryEntry entry = result.GetDirectoryEntry();
lbl_CurrentUser.Text = result.Properties["givenName"][0].ToString() + ' ' + result.Properties["sn"][0].ToString();
// Get SID
IntPtr logonToken = WindowsIdentity.GetCurrent().Token;
WindowsIdentity windowsId = new WindowsIdentity(logonToken);
//Set session variabls
this.CurrentFirstName = result.Properties["givenName"][0].ToString();
//this.CurrentEmail = result.Properties["mail"][0].ToString();
//this.CurrentSID = windowsId.User.ToString();
//this.CurrentUserName = str_CurrentLogin;
//this.CurrentFullName = lbl_CurrentUser.Text;
//this.CurrentDomain = str_DomainName;
this.Session.Add("currentEmail", result.Properties["mail"][0].ToString());
}
public String CurrentFirstName
{
get { return (String)ViewState["currentFirstName"]; }
set { ViewState["currentFirstName"] = value; }
}
I then call them in my defalut.aspx page as follows:
protected void Page_PreRender(object sender, EventArgs e)
{
//try
//{
lbl_FullName.Text = Master.CurrentFullName;
lbl_SID.Text = Master.CurrentSID;
testLabel.Text = Master.CurrentEmail;
//}
//catch (Exception ex)
//{ }
}
This works fine.. If I however navigate away from the default page, then I get the following error..
Object reference not set to an instance of an object.
One the lbl_FullName.Text = Master.CurrentFullName; line
If I uncomment the try catch then it works fine, but I don't believe that this is the correct method of avoiding the fault..
I'm only new to ASP, so be nice..
EDIT:
The variabes are being set in Master.cs as follows.
public String CurrentUserName
{
get { return (String)ViewState["currentUserName"]; }
set { ViewState["currentUserName"] = value; }
}
A few questions:
Which side of the expression is generating the error: this.lbl_FullName or this.Master?
If it's the former, then there's something funky going on in your page.aspx.designer.cs file. Make sure the label control has been declared in there (this file is automatically generated by visual studio, but can sometimes not update properly). You should see a single line like this:
protected
global::System.Web.UI.WebControls.Label
lbl_FullName;
If it's the this.Master property then your page is obviously not referencing your masterpage. Check the page directive (the top line of your .aspx file) and make sure that the DynamicMasterPage value is set and that the path is correct.
On a design note, the masterpage isn't the best place to "store variables". The masterpage should literally just be used to initialise the common parts of the page across your site.
If you need to gather information from a user and use it across several pages, use session variables. This is a method of storing objects "in memory" for as long as the user's browser is open.
Items can be added to the session as follows:
this.Session.Add("fullName", fullName);
Items can then be retrieved later from any other page / usercontrol in your site as follows:
string fullName = (string)this.Session["fullName"];
ViewState is per-page. When you navigate to the new page, it isn't set.
Your master page should put these into Session instead.

How can I get the LastRunTime for a report using the Business Objects Web Services SDK?

I'm using the Business Objects Web Services SDK to access our Business Objects data. I've successfully got a list of reports, and from that found the LastSuccessfulInstance of a report that has been previously run. However, I can't seem to get the LastRunTime to be populated. When I do a query with no attributes specified it comes back as not set, and I get the same result when I ask for that attribute in particular. I've looked at the report itself and the instance and they both don't have this information. Does anyone know where I can get it from?
Here's my code (hacked from one of SAP's demos):
var sessConnUrl = serviceUrl + "/session";
var boConnection = new BusinessObjects.DSWS.Connection(sessConnUrl);
var boSession = new Session(boConnection);
// Setup the Enterprise Credentials used to login to the Enterprise System
var boEnterpriseCredential = new EnterpriseCredential
{
Domain = cmsname,
Login = username,
Password = password,
AuthType = authType
};
// Login to the Enterprise System and retrieve the SessionInfo
boSession.Login(boEnterpriseCredential);
/************************** DISPLAY INBOX OBJECTS *************************/
// Retrieve the BIPlatform Service so it can be used to add the USER
var biPlatformUrl = boSession.GetAssociatedServicesURL("BIPlatform");
var boBiPlatform = BIPlatform.GetInstance(boSession, biPlatformUrl[0]);
// Specify the query used to retrieve the inbox objects
// NOTE: Adding a "/" at the end of the query indicates that we want to
// retrieve the all the objects located directly under the inbox.
// Without the "/" Path operator, the inbox itself would be returned.
const string query = "path://InfoObjects/Root Folder/Reports/";
// Execute the query and retrieve the reports objects
var boResponseHolder = boBiPlatform.Get(query, null);
var boInfoObjects = boResponseHolder.InfoObjects.InfoObject;
// If the reports contains a list of objects, loop through and display them
if (boInfoObjects != null)
{
// Go through and display the list of documents
foreach (var boInfoObject in boInfoObjects)
{
var report = boInfoObject as Webi;
if (report == null)
continue;
if (!string.IsNullOrEmpty(report.LastSuccessfulInstanceCUID))
{
var instanceQuery = "cuid://<" + report.LastSuccessfulInstanceCUID + ">";
var instanceResponseHolder = boBiPlatform.Get(instanceQuery, null);
var instance = instanceResponseHolder.InfoObjects.InfoObject[0];
}
}
}
Both report.LastRunTimeSpecified and instance.LastRunTimeSpecified are false and both LastRunTime are 01\01\0001, but I can see a last run time in the Web Intelligence UI.
With a little help from Ted Ueda at SAP support I figured it out. Not all the properties are populated by default you need to append #* to the query string to get everything, i.e. change the line:
const string query = "path://InfoObjects/Root Folder/Reports/";
to:
const string query = "path://InfoObjects/Root Folder/Reports/#*";

Why can't I insert record with foreign key in a single server request?

I'm tryring to do a simple insert with foreign key, but it seems that I need to use db.SaveChanges() for every record insert. How can I manage to use only one db.SaveChanges() at the end of this program?
public static void Test()
{
using (var entities = new DBEntities())
{
var sale =
new SalesFeed
{
SaleName = "Stuff...",
};
entities.AddToSalesFeedSet(sale);
var phone =
new CustomerPhone
{
CreationDate = DateTime.UtcNow,
sales_feeds = sale
};
entities.AddToCustomerPhoneSet(phone);
entities.SaveChanges();
}
}
After running the above code I get this exception:
System.Data.UpdateException: An error occurred while updating the entries. See the InnerException for details. The specified value is not an instance of a valid constant type
Parameter name: value.
EDIT: Changed example code and added returned exception.
Apperantly using UNSIGNED BIGINT causes this problem. When I switched to SIGNED BIGINT everything worked as it supposed to.
I tried to do this "the right way":
And then I wrote this little test app to scan a directory, store the directory and all its files in two tables:
static void Main(string[] args)
{
string directoryName = args[0];
if(!Directory.Exists(directoryName))
{
Console.WriteLine("ERROR: Directory '{0}' does not exist!", directoryName);
return;
}
using (testEntities entities = new testEntities())
{
StoredDir dir = new StoredDir{ DirName = directoryName };
entities.AddToStoredDirSet(dir);
foreach (string filename in Directory.GetFiles(directoryName))
{
StoredFile stFile = new StoredFile { FileName = Path.GetFileName(filename), Directory = dir };
entities.AddToStoredFileSet(stFile);
}
try
{
entities.SaveChanges();
}
catch(Exception exc)
{
string message = exc.GetType().FullName + ": " + exc.Message;
}
}
}
As you can see, I only have a single call to .SaveChanges() at the very end - this works like a charm, everything's as expected.
Something about your approach must be screwing up the EF system.....
it might be related with the implementation of AddToSalesFeedSet etc..
there is chance that you are doing commit inside ?
any way, my point is that i encountered very close problem, was tring to add relation to new entity with existed entity that been queried earlier - that has unsigned key
and got the same exception;
the solution was to call Db.collection.Attach(previouslyQueriedEntityInstance);

Categories

Resources