Laden...

MVC4: Fehler "Zirkelverweis erkannt"

Erstellt von b0b0nr1 vor 10 Jahren Letzter Beitrag vor 10 Jahren 6.910 Views
B
b0b0nr1 Themenstarter:in
92 Beiträge seit 2011
vor 10 Jahren
MVC4: Fehler "Zirkelverweis erkannt"

Hallo!

Ich bekomme merkwürdiger Weise einen Fehler in meinem OpenSource CMS.
Undzwar möchte ich einen AjaxRequest machen und per JSON dann ganz normal success=true oder false und eine message zurückgeben.

Vorher habe ich immer in Plaintext "Inhalt erfolgreich erstellt" ausgegeben und es war ein normales ActionResult.

Merkwürdigweise ist das das einzige Form, welches mir diesen Fehler zurückgibt. Und dies auch nicht mal im debugger selber. Sondern es scheint direkt vom DevServer zu kommen.

Breakpoints sagen mir dass die Action korrekt durchgelaufen wird.

Ich dachte eventuell liegt es an meinem PC...daher habe ich das Repository auf meinem Notebook erneut gecloned und ach da der gleiche Fehler:

Fehlermeldung:
Beim Serialisieren eines Objekts vom Typ "System.Globalization.CultureInfo" wurde ein Zirkelverweis erkannt.

Hier ist der Code der Action:


    [HttpPost]
        [nPermissionVal(NeededPermissionKeys="USR_CAN_CREATE_CONTENT")]
        public JsonResult AddContent(Models.Core.nContentPostModel MDL, nContentTextBinder Binder)
        {
            MDL.Texts = Binder.Bind();

            Ren.CMS.Content.ContentValidator Cval = new Content.ContentValidator();

            if (!Cval.isValidPostModelForInsert(MDL))

                return Json(new
                {
                    success = false,
                    message = LanguageDefaultsMessages.LANG_SHARED_MESSAGE_FORM_NOT_VALID,
                    modelStateKeys = ModelState.ToDictionary(e => e.Key),
                    modelStateValues = ModelState.ToDictionary(e => e.Value)
                });

            MDL.Texts.ToList().ForEach(e => e.LongText = HttpUtility.UrlDecode(e.LongText));
            var Props = MDL.GetType().GetProperties().Where(e => e.PropertyType == typeof(string));
            foreach (var prop in Props)
                prop.SetValue(MDL, HttpUtility.UrlDecode((prop.GetValue(MDL) ?? String.Empty).ToString()));

            Ren.CMS.Content.ContentManagement CtM = new Content.ContentManagement();
            Ren.CMS.Content.nContent ContentModel = new Content.nContent(MDL);
            CtM.InsertContent(ContentModel);
            if (MDL.Tags != null)
                CtM.bindTagsToContent(MDL.ID, MDL.Tags);

            return Json(new { success = true, message = LanguageDefaultsMessages.LANG_SHARED_MESSAGE_FORM_CONTENT_SAVED.ReturnLangLine() });
        }


nContentPostModel:



 public class nContentPostModel
    {
        #region Properties

        /// <summary>
        /// Returns the Category object
        /// </summary>
        /// 
        [Required]
        public string CategoryID
        {
            get;
            set;
        }

        /// <summary>
        /// Returns the Content Type of the Content
        /// </summary>
        /// 
        [Required]
        public string ContentType
        {
            get;
            set;
        }

        public DateTime CreationDate
        {
            get;
            set;
        }

        /// <summary>
        /// Returns the Username of the Creator
        /// </summary>
        public string CreatorName
        {
            get;
            set;
        }

        /// <summary>
        /// Returns the Creators PK ID
        /// </summary>
        ///
        [Required]
        public string CreatorPKID
        {
            get;
            set;
        }

        public string CreatorSpecialName
        {
            get; set;
        }

        //Eigenschaften
        /// <summary>
        /// Returns the ID of the Content
        /// </summary>
        /// 
        public int ID
        {
            get;
            set;
        }

        /// <summary>
        /// Returns Boolean of the Locked Status of the Content
        /// </summary>
        ///  
        public bool Locked
        {
            get;
            set;
        }

        public int ReferenceID
        {
            get;
            set;
        }

        public int[] Tags
        {
            get; set;
        }

        public IEnumerable<nContentPostModelText> Texts
        {
            get; set;
        }

        #endregion Properties
    }


nContentTextBinder:



 public class nContentTextBinder
    {
        #region Properties

        public List<bool> Active
        {
            get; set;
        }

        public List<string> LangCode
        {
            get; set;
        }

        public List<string> LongText
        {
            get; set;
        }

        public List<string> MetaDescription
        {
            get; set;
        }

        public List<string> MetaKeyWords
        {
            get; set;
        }

        public List<string> PreviewText
        {
            get; set;
        }

        public List<string> SEOName
        {
            get; set;
        }

        public List<int> TextID
        {
            get; set;
        }

        public List<string> Title
        {
            get; set;
        }

        #endregion Properties

        #region Methods

        public List<nContentPostModelText> Bind()
        {
            List<nContentPostModelText> B = new List<nContentPostModelText>();
            if (IsN()) return B;
            for (int x = 0; x < Active.Count; x++)
            {
                nContentPostModelText Bb = new nContentPostModelText();
                Bb.Active = Active[x];

                if (Title.Count > x)
                {
                    Bb.Title = Title[x];

                }
                if (PreviewText.Count > x)
                {
                    Bb.PreviewText = PreviewText[x];

                }
                if (LongText.Count > x)
                {
                    Bb.LongText = LongText[x];

                }
                if (SEOName.Count > x)
                {
                    Bb.SEOName = SEOName[x];

                }
                if (MetaDescription.Count > x)
                {
                    Bb.MetaDescription = MetaDescription[x];

                }
                if (MetaKeyWords.Count > x)
                {
                    Bb.MetaKeyWords = MetaKeyWords[x];

                }
                if (TextID.Count > x)
                {
                    Bb.TextID = TextID[x];

                }
                if (LangCode.Count > x)
                {
                    Bb.LangCode = LangCode[x];

                }

                B.Add(Bb);

            }

            return B;
        }

        private bool IsN()
        {
            if (Title == null) return true;
            if (PreviewText == null) return true;
            if (LongText == null) return true;
            if (SEOName == null) return true;
            if (MetaDescription == null) return true;
            if (MetaKeyWords == null) return true;
            if (TextID == null) return true;
            if (Active == null) return true;
            if (LangCode == null) return true;

            return false;
        }

        #endregion Methods
    }


Die View würde den Thread sprengen daher hier nur der Link zur Datei im Repository:
<Link entfernt>

Ich bin echt ratlos. Wär echt nett wenn jemand eine Idee hätte wo der Fehler herkommen könnte.

Ich habe schon alle Dateien durchsucht, ob ich irgendwo was mit der CultureInfo mache aber auch da leider Fehlanzeige.

mfg

b0b0

Hinweis von herbivore vor 10 Jahren

Wenn der Code den Rahmen sprengt, dann ist er auch nicht per Link zulässig, siehe [Hinweis] Wie poste ich richtig? Punkt 4 und 4.1.

2.207 Beiträge seit 2011
vor 10 Jahren

Guten morgen b0b0nr1,

Ich kenn mich auf dem Gebiet nicht ganz so gut aus, aber hilft dir das hier weiter?

Trying to pass a custom type in MVC action

Gruss

Coffeebean

B
b0b0nr1 Themenstarter:in
92 Beiträge seit 2011
vor 10 Jahren

Darauf bin ich auch schon gestoßen,

Jedoch gehen alle anderen Forms, an die ich Models übergebe.

Ich hatte gehofft die Logik beibehalten zu können und das Problem anders zu lösen.

16.834 Beiträge seit 2008
vor 10 Jahren

Also so ein komplizierten und Schichten-technisch chaotischen Controller hab ich lange nicht mehr gesehen 😉

Wenn Du den lokalen DevServer wirklich verwendest: hör auf damit.
Verwende lieber den IIS Server, da der DevServer nicht alles unterstützt und manchmal ein sehr komisches Verhalten hat.
Wenns auf dem IIS wirklich auch noch auftaucht, sind die Debugging-Möglichkeiten auch besser.

Aber prinzipiell ist ein Zirkelverweis in Deinem Json möglich. Sprich, wenn sich die Modelle gegenseitig referenzieren etc.

5.658 Beiträge seit 2006
vor 10 Jahren

Hallo allerseits,

die Fehlermeldung ist meines Erachtens ziemlich eindeutig:

Fehlermeldung:
Beim Serialisieren eines Objekts vom Typ "System.Globalization.CultureInfo" wurde ein Zirkelverweis erkannt.

Hier ist die einzige Codezeile, wo etwas serialisiert wird:

return Json(new { success = true, message = LanguageDefaultsMessages.LANG_SHARED_MESSAGE_FORM_CONTENT_SAVED.ReturnLangLine() });

Was gibt denn die ReturnLangLine-Methode zurück?

Christian

Weeks of programming can save you hours of planning

B
b0b0nr1 Themenstarter:in
92 Beiträge seit 2011
vor 10 Jahren

@Abt.

Dis nContentPostModel beinghaltet ein IENumerable von typ nContentPostModelTexts.

@Mr. Sparkle:

Die ReturnlangLine methode gibt aus der Datenbank zur aktuellen Sprache eine "Lang Line" aus:



    public class LanguageDefaultValues : IEnumerable
    {
        #region Fields

        public string LangCode = "__USER__";
        public string Package = "Root";

        private Type baseType = null;
        private LanguageCode[] codes = null;
        private string Langlinename = "";
        private Dictionary<string, string> myCol = new Dictionary<string, string>();
        private LanguagePackage[] packages = null;
        private PropertyInfo[] props = null;
        private object[] sobjData = null;

        #endregion Fields

        #region Constructors

        public LanguageDefaultValues(string languageLinename, string Packagename = "Root", string LangCode = "__USER__")
        {
            this.Package = Packagename;
            this.LangCode = LangCode;
            this.Langlinename = languageLinename;
        }

        #endregion Constructors

        #region Methods

        public void Add(string langCode, string Value)
        {
            myCol.Add(langCode, Value);
        }

        public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
        {
            return myCol.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public string ReturnLangLine()
        {
            Dictionary<string, string> DefaultVal = myCol;
            string LangLine = this.Langlinename;

            string package = this.Package;
            string code = this.LangCode;

            CORE.Language.Language Lang = new CORE.Language.Language(code, package);

                string langName = this.Langlinename;

                return Lang.getLine(langName, DefaultVal);

            return "";
        }

        public Dictionary<string, string> ToDictionary()
        {
            return this.myCol;
        }

        private string _getLangName(Expression<Func<string, string>> f)
        {
            string name =  ((f.Body as MemberExpression).Member.Name);
               return name;
        }

        #endregion Methods
    }


Referenz zur Language Klasse:



   public class Language
    {
        #region Fields

        ThisApplication.ThisApplication AppT = new ThisApplication.ThisApplication();
        private string lineName = "";
        private string lngcode = null;
        private string pPackage = "Root";
        private MembershipUser User = new MemberShip.nProvider.CurrentUser().nUser;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Init the Language  Class with a given Lang-Code
        /// </summary>
        /// <param name="langcode">Lang-Code for this Instance</param>
        /// <param name="package">The Package for the Language Instance (Default: Root)</param>
        public Language(string langcode, string package = "Root")
        {
            if (langcode == "__USER__")
            {
                langcode = Helper.CurrentLanguageHelper.CurrentLanguage;
            }

            this.lngcode = langcode;
            this.pPackage = package;
        }

        /// <summary>
        /// Init the Language Class and sets the Lang-Code to "deDE"
        /// </summary>
        /// <param name="package">The Package for the Language Instance (Default: Root)</param>
        public Language()
        {
        }

        /// <summary>
        /// Instant init. This Init activates the  "GetInstant()" Function and returns directly an language line.
        /// Example: Name = new Language("name","Root","deDE").GetInstant();
        /// </summary>
        /// <param name="LangLineName">Name of the language line</param>
        /// <param name="PackageName">Name of the Package</param>
        /// <param name="code">Language code (default: deDE)</param>
        public Language(string LangLineName, string PackageName, string code = "deDe")
        {
            this.lineName = LangLineName;
            this.pPackage = PackageName;
            this.lngcode = code;
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// Sets the Package for this instance. Default: Root
        /// </summary>
        public string Package
        {
            get { return this.pPackage; }
            set { this.pPackage = value; }
        }

        #endregion Properties

        #region Methods

        public string GetInstant()
        {
            return this.getLine(lineName);
        }

        /// <summary>
        /// Loads a Language Line String from the Package (Set by this.Package / Default: Root)
        /// </summary>
        /// <param name="name">Name of the Language Line</param>
        /// <returns>(String)Content</returns>
        public string getLine(string name, Dictionary<string, string> DefaultReturnValue = null)
        {
            SqlHelper Sql = new SqlHelper();
            string cmd = "SELECT TOP 1 * FROM " + AppT.getSqlPrefix + "Language WHERE Package=@Package AND Name=@Name AND Code=@Code";
            SqlParameter[] P = new SqlParameter[] {

            new SqlParameter("@Package",this.pPackage),
            new SqlParameter("@Name",name),
            new SqlParameter("@Code",this.lngcode)

            };
            string line = "";
            try
            {

                Sql.SysConnect();
                SqlDataReader Reader = Sql.SysReader(cmd, P);
                Reader.Read();
                if (Reader.HasRows)
                {
                    line = ((string)Reader["Content"]);

                }
                Sql.SysDisconnect();
            }
            catch (SqlException e) { line = e.Message; }
            finally { }

            if (!LanglineExists(name, Package, this.lngcode) && DefaultReturnValue != null)
            {

                line = this.registerDefaultValues(name, this.pPackage, DefaultReturnValue);

            }
            if (String.IsNullOrEmpty(line)) line = name;

            return line;
        }

        /// <summary>
        /// Inserts an Language Line.
        /// </summary>
        /// <param name="name">Name of the Line</param>
        /// <param name="Content">Content of the Line</param>
        public void InsertLine(string name, string Content, bool overwriteDB = false)
        {
            //Checking for langline

            SqlHelper Sql = new SqlHelper();
            Sql.SysConnect();

            if (this.LanglineExists(name, Package, this.lngcode) && !overwriteDB)
                throw new Exception("Language Line " + name + "(" + this.lngcode + ") does allready exists in Package: " + Package);

            string cmd = "INSERT INTO " + AppT.getSqlPrefix + "Language (Name, Content, Package, Code) VALUES (@Name,@Content,@Package,@Code)";
            SqlParameter[] Parameters = new SqlParameter[]{
            new SqlParameter("@Name", name),
            new SqlParameter("@Content", Content),
            new SqlParameter("@Package", this.pPackage),
            new SqlParameter("@Code", this.lngcode),

            };
            try
            {

                Sql.SysNonQuery(cmd, Parameters);
                Sql.SysDisconnect();

            }
            catch (SqlException e)
            {

                throw e;

            }
            finally
            {

            }
        }

        public bool LanglineExists(string LangName, string LangPackage, string LangCode)
        {
            if (LangCode == "__USER__" && HttpContext.Current.Request.IsAuthenticated)
            {
                if (User == null) User = new MemberShip.nProvider.CurrentUser().nUser;
                Settings.UserSettings Us = new Settings.UserSettings(User);

                object lc = Us.getSetting("langCode").Value;
                if (lc != null) LangCode = lc.ToString();
                else LangCode = "";
            }
            if (String.IsNullOrEmpty(LangCode))
            {

                SettingsHelper.GlobalSettingsHelper GS = new SettingsHelper.GlobalSettingsHelper();

                LangCode = GS.Read("GLOBAL_DEFAULT_LANGUAGE");

            }

            string check = "SELECT * FROM " + AppT.getSqlPrefix + "Language WHERE Name=@name AND Package=@package AND Code=@code";

            SqlHelper Sql = new SqlHelper();
            Sql.SysConnect();
            bool exists = false;
            SqlDataReader R = Sql.SysReader(check, new nSqlParameterCollection(){ {"@name", LangName },
                                                                                  {"@package", LangPackage},
                                                                                  {"@code", LangCode}});
            exists = R.HasRows;

            R.Close();
            Sql.SysDisconnect();
            return exists;
        }

        private string registerDefaultValues(string forLangLine, string forPackage, Dictionary<string, string> DefaultReturnValue)
        {
            string returnValue = null;

            //Database Action

            CORE.SqlHelper.SqlHelper SQL = new CORE.SqlHelper.SqlHelper();

            CORE.ThisApplication.ThisApplication TA = new CORE.ThisApplication.ThisApplication();

            string prefix = TA.getSqlPrefix;

            string query = "SELECT code FROM " + prefix + "Lang_Codes";
            CORE.SqlHelper.nSqlParameterCollection SQLCOL = new CORE.SqlHelper.nSqlParameterCollection();

            SQL.SysConnect();

            SqlDataReader Codes = SQL.SysReader(query, SQLCOL);
            Language Lang = null;
            if (Codes.HasRows)
            {

                while (Codes.Read())
                {

                    Lang = new Language((string)Codes["code"], forPackage);

                    if (DefaultReturnValue[(string)Codes["code"]] == null)
                    {

                        DefaultReturnValue.Add((string)Codes["code"], DefaultReturnValue.Where(code => code.Value != null).First().Value);

                    }
                    Lang.InsertLine(forLangLine, DefaultReturnValue[(string)Codes["code"]]);

                }

            }
            Codes.Close();

            Lang = new CORE.Language.Language(this.lngcode, forPackage);
            returnValue = Lang.getLine(forLangLine);
            if (returnValue == "")
            {
                returnValue = forLangLine;

            }
            SQL.SysDisconnect();

            return returnValue;
        }

        #endregion Methods
    }
}


EDIT: http://www.codeproject.com/Articles/605595/ASP-NET-MVC-Custom-Model-Binder Gerade gelesen. Bin gerade nicht Zuhause aber ich werde es damit zuhause einmal probieren (Custom Model Binder) Für alternative Ideen bin ich jedoch trotzdem sehr dankbar 😃

5.658 Beiträge seit 2006
vor 10 Jahren

Also ich würde dir empfehlen, deinen Code zu **testen **und zu debuggen, anstatt hier nach und nach deinen kompletten Projektcode zu posten. Erstelle dir Testfälle wie das Serialisieren zu JSON, und dann kannst du mit dem Debugger herausfinden, wo das Problem liegt.

[Artikel] Debugger: Wie verwende ich den von Visual Studio?
[Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden

Christian

Weeks of programming can save you hours of planning

B
b0b0nr1 Themenstarter:in
92 Beiträge seit 2011
vor 10 Jahren

Hi!

Ich hab den Fehler gefunden 😃

Ich weiß zwar immer noch nicht warum das dadurch so gekommen ist aber hier:



return Json(new
            {
                success = false,
                message = LanguageDefaultsMessages.LANG_SHARED_MESSAGE_FORM_NOT_VALID

//             modelStateKeys = ModelState.ToDictionary(e => e.Key),
  //              modelStateValues = ModelState.ToDictionary(e => e.Value)
            });


Die auskommentierten zwei Zeilen warn der Auslöser.