I am trying to change a field value dynamically from back-end, but looks like the changes are not being saved.
Code
item is fetched from the master database.
using (new EditContext(item))
{
item.Editing.BeginEdit();
try
{
//Value is updated here from "" to Test
item.Fields["Content"].Value = "Test";
}
finally
{
//item.Fields["Content"].Value is "" again.
item.Editing.AcceptChanges();
item.Editing.EndEdit();
}
}
UPDATE
As #sitecore climber said, I did change my code back to use -
new Sitecore.SecurityModel.SecurityDisabler()
However, the issue was caching. The updated value was displayed in the content editor, only after I had cleared the cache and restarted the browser.
To get around that, I disabled caching before making the edit and turned it back on once the editing was done.
CacheManager.Enabled = false;
using (new Sitecore.SecurityModel.SecurityDisabler())
{
item.Editing.BeginEdit();
try
{
item.Fields["Content"].Value = "Test";
}
finally
{
item.Editing.EndEdit();
}
}
CacheManager.Enabled = true;
Please add : (new Sitecore.SecurityModel.SecurityDisabler())
EditContext containts next lines of code :
public EditContext(Item item)
{
Assert.ArgumentNotNull((object) item, "item");
this._item = item;
this._item.Editing.BeginEdit();
}
so you don't need here if you have in your code
item.Editing.BeginEdit();
your code must be :
using (new Sitecore.SecurityModel.SecurityDisabler())
{
item.Editing.BeginEdit();
try
{
//Value is updated here from "" to Test
item.Fields["Content"].Value = "Test";
}
finally
{
//item.Fields["Content"].Value is "" again.
// Remove AcceptChanges I never use it , for editing .
// item.Editing.AcceptChanges();
item.Editing.EndEdit();
}
}
I updated my answer, did you check on content editor if are any changes ?
Can you clear cache, and check again. It's really strange why is not working I guess can be a caching problem .
Try using SecurityDisabler if it helps..
using (new Sitecore.SecurityModel.SecurityDisabler())
{
item.Editing.BeginEdit();
try
{
//Value is updated here from "" to Test
item.Fields["Content"].Value = "Test";
}
finally
{
//item.Fields["Content"].Value is "" again.
item.Editing.AcceptChanges();
item.Editing.EndEdit();
}
}
Related
I added an entry in the Properties.Settings named strCol that is of type NameValueCollection. I am using this to save items from a listview to the settings so that when the application reboots, the ListView gets re-populated again with the items that were saved previously. I'm only storing the item name and the tag from the ListViewItems.
But something strange is happening I cant explain.
I am using this code to save the items to the settings:
NameValueCollection nvCol = new NameValueCollection();
foreach (ListViewItem lviP in lvParmNames.Items)
{
nvCol.Add(lviP.Text, lviP.Tag.ToString());
}
Properties.Settings.Default.strCol = nvCol;
Properties.Settings.Default.Save();
For some reason the Save and load in and from settings works fine, as long as the application is still active. But when the application has been closed and rebooted, the load doesn't work as if the NameValueCollection was not saved.
What am I missing here ?
How I'm currently loading the setting:
The call for loading, but it already seem to fail at the check if its null
if (Properties.Settings.Default.strCol != null)
{
NameValueCollection nv = Properties.Settings.Default.strCol;
foreach (string key in nv)
{
try
{
var value = nv[key];
ListViewItem lvi = new ListViewItem(key);
lvi.Tag = value;
lvFamNames.Items.Add(lvi);
}
catch (Exception ex)
{
TaskDialog.Show("Error", "Error while parsing Family Names from saved settings. \n" + ex.Message);
}
}
}
Just noticed something:
Though i added the NameValueCollection in the sections it is actually not added when building the application. When i open the config file, the setting is not there.
So i guess the issue is here, though now i need to figure out how to add it now.
Looking into the Settings.Designer.cs file, i guess this part looks wrong for the type of 'NameValueCollection`:
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.Collections.Specialized.NameValueCollection strColExcelFamNames {
get {
return ((global::System.Collections.Specialized.NameValueCollection)(this["strCol"]));
}
set {
this["strCol"] = value;
}
}
So I am wanting to load an image with the use of a function that receives as a string the name of the image it needs to load and then have it load it however I cannot get this to work as I think the program is simply trying to load the variable name rather that the the string it stores(which is the actual name of the image). Sorry if that's badly worded hopefully my code clears up what I mean.
bool FlagDisplay(PictureBox team, string teamName)//Displays the flag of the team that was selected
{
if (teamName == "Canada")
{
team.Image = Properties.Resources.Canada;
}
else if (teamName == "New Zealand")
{
team.Image = Properties.Resources.NZ;
}
else if (teamName == "South Africa")
{
team.Image = Properties.Resources.RSA;
}
return (true);
}
I want my code to work more like
bool FlagDisplay(PictureBox team, string teamName)//Displays the flag of the team that was selected
{
team.Image = Properties.Resources.teamName;
}
var imageToShow = Properties.Resources.ResourceManager.GetObject(teamName);
imageToShow will be a System.Drawing.Bitmap.
See https://msdn.microsoft.com/en-us/library/963f81yd(v=vs.110).aspx
A PictureBox only contains one Picture. If you want to change the image that it is displaying , then you need to pass an actual Image to it, not just a string.
so , try this:
public void FlagDisplay(PictureBox team, string teamName)//Displays the flag of the team that was selected
{
// note here you probably need to add .jpg or .png to the teamName
var imageToShow = new Bitmap(teamName); // this takes filename
team.Image = (Image) imageToShow;
}
I would be inclined to code your FlagDisplay method like this:
bool FlagDisplay(PictureBox team, string teamName)
{
var images = new Dictionary<string, string>()
{
{ "Canada", Properties.Resources.Canada },
{ "New Zealand", Properties.Resources.NZ },
{ "South Africa", Properties.Resources.RSA },
};
if (images.ContainsKey(teamName))
{
team.Image = new Bitmap(images[teamName]);
return true;
}
return false;
}
The advantage with this approach is that you can pull the dictionary out of the method and build it dynamically to handle different countries or image locations without necessarily needing to recompile your FlagDisplay source.
If that causes an error then you don't have full image paths in your resources.
I have a block of code where I'm trying to disable event firing when editing a file, once the debugger hits the item.SystemUpdate(false) line it throws an exception that states "The file xxxx has been modified by xxxxx"
HandleEventsFiring handle = new HandleEventsFiring();
handle.DisableHandleEventFiring();
try
{
web.AllowUnsafeUpdates = true;
SPFile rptFile = web.GetFile(item.Url); //item is an SPListItem
if (rptFile.Exists)
{
WordDocUtility word = new WordDocUtility();
using (System.IO.Stream stream = rptFile.OpenBinaryStream())
{
word.ReplaceKeys(stream, keys);
rptFile.SaveBinary(stream);
}
}
item.SystemUpdate(false); // the line throwing the exception
}
finally
{
handle.EnableHandleEventFiring();
web.AllowUnsafeUpdates = allowUnsafeUpdates;
}
public class HandleEventsFiring: SPItemEventReceiver
{
public void DisableHandleEventFiring()
{
this.EventFiringEnabled = false;
}
public void EnableHandleEventFiring()
{
this.EventFiringEnabled = true;
}
}
Does anyone know of a way around this or am I doing something wrong?
Any help would be greatly appreciated.
You haven't really shown enough of the code for us to point you to the exact problem. The error that you're getting means that after you pulled the list item that is in item from the content database it was later updated. Chances are, if you get the error every single time, that you're pulling down the same item more than once and your changes are conflicting with yourself. My guess is that item represents a file in a document library, and that you're modifying the file in addition to the splist item. These changes are what are conflicting. You need to fetch the item, update the item, then fetch the file and update the file. If you need to fetch the item and then update the file you will need to fetch the item again so that you don't end up updating an item when another update occurred between the fetch and update.
I am tryong to do the following in a Row_Command event of a gridview. But the the pop up box never comes up, I have tried it in so many different ways.. but yet no luck. Please if someone can see the issue i would really appreciate a pointer.
protected void Gridview_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName == "Merchant")
{
if (ItemsAvailable)
{
StringBuilder sb = new StringBuilder();
MyClass class = new MyClass();
TList<LineItems> otherItems = MyClass.GetItems(id);
bool IsNotAvailable = false;
foreach (LineItems item in otherItems)
{
Merchandise skuMerchandise = skuMerchandise.GetMerchandise(otherItems.mid);
if (skuMerchandise != null)
{
if (skuMerchandise.AvailableItems <= 0)
{
sb.Append(OtherItems.Name);
sb.Append(Environment.NewLine);
IsNotAvailable = true;
}
}
}
if (IsNotAvailable)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key",
"function Redirect() {location.href = 'homePage.aspx';}
if(confirm('The items : "+sb.ToString()+" will arrive in 1 month.
Do you wish to continue?') == true){Redirect();};", true);
}
}
}
Everytime i click the button, it just passes like nothing.. never prompts eveb though IsNotAvailable is true when I add a breakpoint.
You can go for a simpler way,
Define the javascript function in the design/separate script file so that it accepts the name of item. eg. myFunction(itemName)
And in your CS file, simply add a call to that function,
if (IsNotAvailable)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key",
"myFunction('" + itemName + "')
}
}
It will make things simpler and you would be able to confirm if this is a Javascript issue or a problem in how you are writing it through CS file.
Update:
Your first goal should be to make sure that your JS function is working for you, so before anything, add the following code in an empty html file and run it,
<script type='text/javascript'>
ItemNotInStock('item');
function ItemNotInStock(itemName)
{
var message = "The following items are no longer in stock :" + itemName + ".
Would you like to continue?";
if (confirm(message) == true)
{ location.href = "homePage.aspx"; }
}
If you redirect correctly then do what's mentioned below.
Define the following javascript in your design file(tested it locally, working for me in chrome,)
<script type='text/javascript'>
function ItemNotInStock(itemName)
{
var message = "The following items are no longer in stock :" + itemName + ".
Would you like to continue?";
if (confirm(message) == true)
{ location.href = "homePage.aspx"; }
}
In your C# code, add following line
if (IsNotAvailable)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key",
string.Format("ItemNotInStock('{0}');", itemName);
}
}
Make sure your JavaScript code is executed by using breakpoints available in the developer tools of the browser of your choice, like Chrome Developer Tools: Breakpoints
BTW: Why do you create an instance of Merchandise if you instantly discard it with the next line?
hi
this code works fine and my config file changes correctly.
//Local Variable Declaration
System.Configuration.Configuration oConfig =
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(
Request.ApplicationPath);
if (oConfig .AppSettings.Settings["CompanyName"] == null)
{
oConfig AppSettings.Settings.Add("CompanyName", "MyCompanyName");
oConfig .Save();
}
but when I want to use a property for this purpose Nothing happend in Config File.
// Property Declaration
private System.Configuration.Configuration _oRootConfig;
public System.Configuration.Configuration oRootConfig
{
get
{
return
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(
Request.ApplicationPath);
}
set { _oRootConfig = value; }
}
if (oRootConfig.AppSettings.Settings["CompanyName"] == null)
{
oRootConfig.AppSettings.Settings.Add("CompanyName", "MyCompanyName");
oRootConfig.Save(System.Configuration.ConfigurationSaveMode.Modified, true);
}
now i have two question:
1-why this code doesnot work ,and there
is no error.
2-if i want to programn in object oriented
manner ,what can i do to fix this property
if the problem is related to the property.
thanks
You're reopening the config on every get, do this instead:
get
{
if(this._oRootConfig == null)
this._oRootConfig = (System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath));
return this._oRootConfig;
}
this line of code:
get
{
return (System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath));
}
set { _oRootConfig = value; }
you are not setting _oRootConfig in your get. You need this code:
get
{
_oRootConfig = (System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath));
return _oRootConfig;
}
set
{
_oRootConfig = value;
}