Hello I have function which creates/updates fields in app.exe.config file
public static void UpdateConfig(string FieldName, string FieldValue, ConfigSelector SectionName = ConfigSelector.AppSettings)
{
switch (SectionName)
{
case ConfigSelector.Execption:
{
// MessageBox.Show("gg");
var xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
if (xmlDoc.SelectSingleNode("configuration/Execption") != null)
{
if (xmlDoc.SelectSingleNode("configuration/Execption/List") != null)
{
// create new node <add key="Region" value="Canterbury" />
var nodeRegion = xmlDoc.CreateElement("add");
nodeRegion.SetAttribute("key", FieldName);
nodeRegion.SetAttribute("value", FieldValue);
xmlDoc.SelectSingleNode("configuration/Execption/List").AppendChild(nodeRegion);
}
else
{
var List = xmlDoc.CreateElement("List");
xmlDoc.SelectSingleNode("configuration/Execption").AppendChild(List);
UpdateConfig(FieldName, FieldValue, SectionName);
}
}
else
{
var List = xmlDoc.CreateElement("Execption");
xmlDoc.SelectSingleNode("configuration").AppendChild(List);
UpdateConfig(FieldName, FieldValue, SectionName);
}
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
ConfigurationManager.RefreshSection("Execption/List");
break;
}
}
}
Function works first Check if xpath configuration/Execption exist, if not exist it creates this path and recalls function again, second time check if configuration/Execption/List path exist if not creates path and recalls function again, and third time adds required fields which is fieldname and fieldvalue,
but I getting System.StackOverflowException in line:
if (xmlDoc.SelectSingleNode("configuration/Execption") != null)
Did I miss something?
You are calling UpdateConfig recursively, with the exact same arguments already passed to it
UpdateConfig(FieldName, FieldValue, SectionName);
Since the recursive call happens before the xmlDoc.Save(), it always works on the same content.
Saving before doing the recursive call should fix the issue.
You don't save the document after adding the new element, so when you are loading the file in the next iteration the new element isn't there, and xmlDoc.SelectSingleNode("configuration/Execption") != null is still false, so the code creates the element again in infinite recursion and you get StackOverflowException.
Just save the document after you change it
else
{
var List = xmlDoc.CreateElement("Execption");
xmlDoc.SelectSingleNode("configuration").AppendChild(List);
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
UpdateConfig(FieldName, FieldValue, SectionName);
}
Related
I add dicom files using the AddFile(dicomFile,name) method but the number of frames tag does not appear.
var sourcePath = Path.Combine(tempDirectory, "DICOM", $"PATIENT{i + 1}", $"STUDY{j + 1}", $"SERIES{k + 1}", $"SUBSERIES{l + 1}");
var dicomDir = new DicomDirectory { AutoValidate = false };
foreach (var file in new DirectoryInfo(tempDirectory).GetFiles("*.*", SearchOption.AllDirectories))
{
try
{
var dicomFile = DicomFile.Open(file.FullName);
if (dicomFile != null)
{
var referenceField = file.FullName.Replace(tempDirectory, string.Empty).Trim('\\');
dicomDir.AddFile(dicomFile, referenceField);
}
}
catch (Exception ex)
{
Log.Error(ex, ex.Message);
}
}
var dicomDirPath = Path.Combine(tempDirectory, "DICOMDIR");
dicomDir.Save(dicomDirPath);
resultDirectories.Add(dicomDirPath);
I also tried the addorupdate method but it doesn't work.
I use the fo-dicom library 4.0.7
When building a DICOMDIR with fo-dicom by iterative calling AddFile for each file, then you will get a DICOMDIR with all the required DicomTags. But of course there are a lot of tags that are optional and you can add them yourself.
The method AddFile returns an instance of type DicomDirectoryEntry, which gives you a reference to the patient record entry, the study record entry, the series record entry and the instance record entry. There you can add as many additional optional data that you wish. In your case it would look like
[...]
if (dicomFile != null)
{
var referenceField = file.FullName.Replace(tempDirectory, string.Empty).Trim('\\');
var entries = dicomDir.AddFile(dicomFile, referenceField);
// now you can add some additional data.
// but before adding values, make sure that those values are available
// in your original DicomFile to avoid NullReferenceExceptions.
if (dicomFile.Dataset.Contains(DicomTag.NumberOfFrames))
{
entries.InstanceRecord.AddOrUpdate(DicomTag.NumberOfFrames, dicomFile.Dataset.GetSingleValue<int>(DicomTag.NumberOfFrames));
}
}
I am using XPathSelectElement to get some elements from an XML file. It works when those elements are present in the XML file. If the selected element is NOT in the XML it naturally throws a "Null Reference" exception. Which is fine. I would expect it to do that. However, I want to be able to catch that exception and do nothing if the XPathSelectElement is null.
Code that works as expected:
public void LoadBonusDescription()
{
string Race = CharRaceSelector.Text;
string bonus = RequirementsBox.Text;
XDocument doc = XDocument.Load($"{Gamepath}");
string description = (string)doc.XPathSelectElement($"//RaceID[#id='{Race}']/Bonus[#id='{bonus}']/Description").Value;
//DescriptionBox is a listBox
DescriptionBox.Text = description;
}
I tried throwing in an if statement like:
if (description == null)
{
return;
}
else
{
DescriptionBox.Text = description;
}
But it doesn't hit that part, and throws the exception at the string variable assignment here:
string description = (string)doc.XPathSelectElement($"//RaceID[#id='{Race}']/Bonus[#id='{bonus}']/Description").Value;
How do I catch the exception BEFORE (or during) the variable assignment in order to run the if statement?
If I can't catch it, is there a way to disable the DescriptionBox listBox AND NOT turn the text in the box to gray (as it does with DescriptionBox.Enabled = false;)?
Basically I want to prevent users from selecting items that aren't available in the XML file.
Added:
var description = (string)doc.XPathSelectElement($"//RaceID[#id='{Race}']/Bonus[#id='{bonus}']/Description");
if (description == null)
{
return;
}
else
{
DescriptionBox.Text = description;
}
as #dbc suggested and it works perfectly!
I would like to change the state of a bool to true while the current action is taking place. The action result gets the id from the razor page and then creates a link in my sitemap. While it is doing that i would like it to change the state of the bool in the record and save it. I have tried implementing this code in the controller but with no success.
var isadded = db.Sitemaps.Where(m => m.IsAdded == false).FirstOrDefault();
isadded.IsAdded = true;
This does not work because it has no idea what record it is supposed to change and does not have a save.
I have this in my code already.
public ActionResult AddNewSitemapElement(int? id)
and then i make sure it isn't null and return a badRequest if it is. Then i have the code below to use throughout the Action.
MySitemap mySitemap = db.Sitemaps.Find(id);
Is there a way to incorporate using the id in a string to change this? Also should i put it at the bottom of the Action so it does it after adding the data to the XML or does it not matter?
Thanks for your help!
Update:
I added this block of code to the action and it seems to work. From the advice of comment below. I already know the state of the bool before this happens. This bool only controls the show of a button to add the link to the XML in the view. So once it is created in the database the button is there to add it to the xml. So i know it is false already. However this seems to work. Would be glad to know if this is the best approach or not.
if (mySitemap.IsAdded == false) {
mySitemap.IsAdded = true;
db.SaveChanges();
}
Update:
Below is my full Controller Action. It does work as is. If there is a more proper way to implement this then feel free to comment.
public ActionResult AddNewSitemapElement(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
MySitemap mySitemap = db.Sitemaps.Find(id);
if (mySitemap.IsAdded == false) {
mySitemap.IsAdded = true;
db.SaveChanges();
}
SitemapGenerator sg = new SitemapGenerator();
//create a sitemap item
//var siteMapItem = new SitemapItem(Url.Action("NewAdded", "NewController"), changeFrequency: SitemapChangeFrequency.Always, priority: 1.0);
var siteMapItem = new SitemapItem(PathUtils.CombinePaths(Request.Url.GetLeftPart(UriPartial.Authority), "/" + mySitemap.Category + "/" + mySitemap.Location),
changeFrequency: SitemapChangeFrequency.Daily, priority: (mySitemap.Priority), lastModified: (mySitemap.LastModified));
//Get the XElement from SitemapGenerator.CreateItemElement
var NewItem = sg.CreateItemElement(siteMapItem);
//create XMLdocument element to add the new node in the file
XmlDocument document = new XmlDocument();
//load the already created XML file
document.Load(Server.MapPath("~/Sitemap.xml"));
//convert XElement into XmlElement
XmlElement childElement = document.ReadNode(NewItem.CreateReader()) as XmlElement;
XmlNode parentNode = document.SelectSingleNode("urlset");
//This line of code get's urlset with it's last child and append the new Child just before the last child
document.GetElementsByTagName("urlset")[0].InsertBefore(childElement, document.GetElementsByTagName("urlset")[0].LastChild);
//save the updated file
document.Save(Server.MapPath("~/Sitemap.xml"));
return RedirectToAction("Index", "Sitemap");
}
This is a general pattern to ensure you are only updating the individual entity and return it where applicable.
public ActionResult AddNewSitemapElement(int? id)
{
if (id != null)
{
var mysitemap = db.Sitemaps.where(x => x.id == id.Value && !x.IsAdded).FirstOrDefault();
if(mysitemap != null)
{
mysitemap.IsAdded = true;
DB.SaveChanges();
}
return mysitemap;
}
return null;
}
Here What I am trying to do, my employer want to be able to be able do 301 redirect with regex expression with the alias in Sitecore so the way I am trying to implement this is like this!
a singleline text field
with a checkbox to tell sitecore it will be a regex expression I am a noob in .NET and Sitecore how can I implement this ? here a exemple http://postimg.org/image/lwr524hkn/
I need help the exemple of redirect I want handle is like this, this is a exemple of the redirect I want to do it could be product at the place of solution.
exemple.com/en/solution/platform-features to
exemple.com/en/platform-features
I base the code from http://www.cmssource.co.uk/blog/2011/December/modifying-sitecore-alias-to-append-custom-query-strings-via-301-redirect this is for query string I want to use regex expression.
namespace helloworld.Website.SC.Common
{
public class AliasResolver : Sitecore.Pipelines.HttpRequest.AliasResolver
{
// Beginning of the Methods
public new void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (!Settings.AliasesActive)
{
Tracer.Warning("Aliases in AliasResolver are not active.");
}
else
{
Sitecore.Data.Database database = Context.Database;
if (database == null)
{
Tracer.Warning("There is no context in the AliasResolver.");
}
else
{
{
Profiler.StartOperation("Resolve virgin alias pipeline.");
Item item = ItemManager.GetItem(FileUtil.MakePath("/sitecore/system/aliases", args.LocalPath, '/'), Language.Current, Sitecore.Data.Version.First, database, SecurityCheck.Disable);
if (item != null)
{
//Alias existis (now we have the alias item)
if (item.Fields["Regular Expressions"] != null)
{
if (!String.IsNullOrEmpty(item.Fields["Regular Expressions"].Value) && !args.Url.QueryString.Contains("aproc"))
{
var reg = new Regex(#"(?<Begin>([^/]*/){2})[^/]*/(?<End>.*)");
var match = reg.Match(#"exemple.com/en/solution/platform-features");
var result = match.Groups["Begin"].Value + match.Groups["End"].Value;
}
}
}
Profiler.EndOperation();
}
catch (Exception ex)
{
Log.Error("Had a problem in the VirginAliasResolver. Error: " + ex.Message, this);
}
}
}
}
///<summary>
/// Once a match is found and we have a Sitecore Item, we can send the 301 response.
///</summary>
private static void SendResponse(string redirectToUrl, HttpRequestArgs args)
{
args.Context.Response.Status = "301 Moved Permanently";
args.Context.Response.StatusCode = 301;
args.Context.Response.AddHeader("Location", redirectToUrl);
args.Context.Response.End();
}
}
}
PS: I know they have module for this but my employer want it done that way and I am reaching for help since it's been a week I'm trying to add this feature
So if I understand correctly, you do not want to select an Alias by path:
Item item = ItemManager.GetItem(FileUtil.MakePath("/sitecore/system/aliases", args.LocalPath, '/'), Language.Current, Sitecore.Data.Version.First, database, SecurityCheck.Disable);
But rather find an Alias comparing a Regex field to the Url. I have not tested this, but it could be someting like:
var originalUrl = HttpContext.Current.Request.Url;
var allAliases = Sitecore.Context.Database.SelectItems("/sitecore/system/aliases//*");
var foundAlias = allAliases.FirstOrDefault( alias =>
!string.IsNullOrEmpty(alias["Regular Expressions"]) &&
Regex.IsMatch(HttpContext.Current.Request.Url.ToString(), alias["Regular Expressions"]));
Then, if foundAlias != null, you can retrieve the url and redirect like you do in your private SendResponse function.
var linkField = (LinkField)foundAlias.Fields["linked item"];
var targetUrl = linkField.Url;
using (new SecurityDisabler())
{
if (string.IsNullOrEmpty(targetUrl) && linkField.TargetItem != null)
targetUrl = LinkManager.GetItemUrl(linkField.TargetItem);
}
SendResponse(targetUrl, args);
Again, I have not tested this so don't shoot me if it needs some corrections, but this should help you get on your way.
I just started using ReSharper and I'm trying to identify why it thinks this code is wrong.
var file = new FileInfo("foobar");
return file.Directory.FullName;
It highlights file.Directory as a "Possible System.NullReferenceException". I'm not sure how this is possible because the file object can never be null and I can't figure out how the DirectoryInfo object returned from the FileInfo object could ever be null.
The Directory property can indeed be null. The implementation of the property is roughly
public DirectoryInfo Directory {
get {
string directoryName = this.DirectoryName;
if (directoryName == null) {
return null;
}
return new DirectoryInfo(directoryName);
}
}
It can definitely return null. Here is a concrete example
var x = new FileInfo(#"c:\");
if (x.Directory == null) {
Console.WriteLine("Directory is null"); // Will print
}