首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MVC3会话状态

MVC3会话状态
EN

Stack Overflow用户
提问于 2014-04-16 05:02:14
回答 2查看 82关注 0票数 0

我最近一直在重构我的代码,以便从inproc转移到会话状态。我已经创建了一个新类,它是我从一开始就构建的可序列化的类。我目前收到“Unable to serialize the session state.‘”。错误。但是,我可以使用JsonConvert (newtonsoft)来序列化这个类。

方法是不被允许的吗?

它看起来是这样的:

代码语言:javascript
复制
[Serializable()]
public class SessionStateObject
{


    public int CurrentSessionId { get; set; }
    public int CurrentAssessmentId { get; set; }
    public int CurrentAssessmentElementId { get; set; }
    public int CurrentUserId { get; set; }

    public Dictionary<string, int> AssessmentItemsIds { get; set; }
    public Dictionary<string, int> SessionResponseIds { get; set; }


    public List<string> AdministeredItemOrderByName;
    public string LastVisitedItem;
    public int? TotalAssessmentCurrentItemOrder;

    public RenderablePersistanceObject RenderablePersistance;



    #region formula engine section variables

    public string BranchingResult { get; set; }
    public string ContentOutput { get; set; }

    public int CurrentItemId { get; set; }
    public int VirtualWorkingItemId { get; set; }


    public bool isCloneItem { get; set; }
    public bool wasPreFormulaRun;
    public bool wasContentOutput;
    public bool wasPrefillReached;
    public bool isVirtual;


    public List<string> FormulaStack { get; set; }
    public List<string> ItemNameTokens { get; set; }
    public string serializedJSContext { get; set; }
    public string CloneSourceItem { get; set; }

    public int itemsAbletoFastForwardThrough { get; set; }

    #endregion

    private Dictionary<int, int> itemIdByMultiGroupId;  //key is itemId, val is groupId
    private Dictionary<int, List<int>> MultiGroupIdByItemIds; //key is groupId, val is itemId



    public SessionStateObject()
    {
        RenderablePersistance = new RenderablePersistanceObject();
        AssessmentItemsIds = new Dictionary<string, int>();
        SessionResponseIds = new Dictionary<string, int>();
        AdministeredItemOrderByName = new List<string>();
        FormulaStack = new List<string>();
        ItemNameTokens = new List<string>();

        itemIdByMultiGroupId = new Dictionary<int, int>();
        MultiGroupIdByItemIds = new Dictionary<int, List<int>>();
    }


    public void initMultiItemGroups(Assessment assessment, NetScidDbContainer dbContext)
    {

        List<MultiItem> assessmentMultiItems = (from multi in dbContext.MultiItems
                                                where multi.AssessmentId == assessment.Id
                                                select multi).ToList();
        List<int> uniqueGroupIds = new List<int>();

        foreach (MultiItem mItem in assessmentMultiItems)
        {
            itemIdByMultiGroupId.Add(mItem.ItemId, mItem.GroupId);
            if (!uniqueGroupIds.Contains(mItem.GroupId))
            {
                uniqueGroupIds.Add(mItem.GroupId);
            }
        }

        foreach (int groupId in uniqueGroupIds)
        {
            List<int> ItemIds = (from itemGroup in assessmentMultiItems
                                 where itemGroup.GroupId == groupId
                                 orderby itemGroup.Id ascending
                                 select itemGroup.ItemId).ToList();
            MultiGroupIdByItemIds.Add(groupId, ItemIds);
        }

    }

    public List<int> GetItemIdsFromSingleItemId(int itemId)
    {
        List<int> foundItemIDs = new List<int>();
        int foundGroupId = -1;
        if (this.itemIdByMultiGroupId.ContainsKey(itemId))
        {
            foundGroupId = this.itemIdByMultiGroupId[itemId];
        }

        if (this.MultiGroupIdByItemIds.ContainsKey(foundGroupId))
        {
            foundItemIDs = this.MultiGroupIdByItemIds[foundGroupId];
        }

        return foundItemIDs;

    }

    public void nullifyRenderable()
    {
        this.RenderablePersistance = null;
    }




    public void PersistRenderable(IRenderable renderable)
    {
        this.RenderablePersistance = new RenderablePersistanceObject();
        if (renderable is MultiItemRenderable)
        {
            //get list of item IDs from the multi-item lookup
            this.RenderablePersistance.isMultiItem = true;
            this.RenderablePersistance.primaryItemId = ((Item)((MultiItemRenderable)renderable).IndexedItems.Last()).Id;
        }
        else  //regular renderable
        {
            this.RenderablePersistance.isMultiItem = false;
            this.RenderablePersistance.primaryItemId = ((Item)renderable).Id;
        }

    }

    public AssessmentRuntime StartAdministrativeSession(NetScidDbContainer dataContext, Assessment assessment, User currentUser, string pid = "1")
    {

        AssessmentRuntime newRuntime = new AssessmentRuntime(this, dataContext);

        Session newSession = new Session();


        assessment.PrepElements();

        PermissionEntity rootPE = new PermissionEntity();

        if (currentUser != null)
        {
            rootPE = PermissionEntityHelper.GetRootPermissionEnity(dataContext, currentUser);
        }
        else
        {
            rootPE = (from adminpe in dataContext.PermissionEntities
                      where adminpe.Name == "TelesageAdmin"
                      select adminpe
                ).FirstOrDefault();
        }
        newSession.Participant = (from pids in dataContext.ParticipantIdAliasLookups
                                  where pid == pids.AliasId && pids.RootPermissionEntity.Id == rootPE.Id
                                  select pids.Participant).FirstOrDefault();


        if (newSession.Participant == null)
        {
            Participant newParticipant = new Participant();
            ParticipantIdAliasLookup newPidAlias = new ParticipantIdAliasLookup();
            newParticipant.ParticipantDataJSON = "";

            newPidAlias.AliasId = pid;
            newPidAlias.RootPermissionEntity = rootPE;

            newParticipant.AliasLookup = newPidAlias;
            newParticipant.PermissionEntities.Add(currentUser.PermissionEntity);
            newParticipant.PermissionEntities.Add(rootPE);

            newSession.Participant = newParticipant;

            dataContext.Participants.AddObject(newParticipant);
            dataContext.ParticipantIdAliasLookups.AddObject(newPidAlias);

        }

        newSession.Assessment = assessment;
        newSession.User = currentUser;
        newSession.StartTime = DateTime.Now;

        newSession.PermissionEntity = currentUser.PermissionEntity;

        newSession.SetSessionData("engineversion", typeof(SmartQWeb.MvcApplication).Assembly.GetName().Version.ToString());
        newSession.SetSessionData("assessmentname", newSession.Assessment.Name);
        newSession.SetSessionData("assessmentversion", newSession.Assessment.Version);
        newSession.SetSessionData("computername", Environment.MachineName);
        newSession.SetSessionData("username", currentUser.Name);



        dataContext.Sessions.AddObject(newSession);

        newSession.SetSessionData("dxdata", JsonConvert.SerializeObject(newRuntime.RenderedDiagnoses));

        newRuntime.formulaEngine = new FixedLengthFormulaEngine(newRuntime);
        SessionLog newSessionLog = new SessionLog();

        dataContext.SessionLogs.AddObject(newSessionLog);
        newSession.SessionLog = newSessionLog;




        dataContext.SaveChanges();

        initMultiItemGroups(assessment, dataContext);

        this.CurrentSessionId = newSession.Id;
        this.CurrentUserId = currentUser.Id;
        this.CurrentAssessmentId = assessment.Id;
        newRuntime.Context = new RuntimeContext(this, dataContext);


        this.GetAssessmentItems(assessment);  //to populate the items dict
        newRuntime.formulaEngine.InitializeContext(this.AssessmentItemsIds.Keys.ToList());
        newRuntime.RenderedDiagnoses = new RenderedDiagnosisModel(newRuntime.Context.AdministeredItemOrderByName);

        newRuntime.Context.Logger.WriteLog("Session started with assessment: " + newRuntime.Context.Assessment.Name + " with version: " + newRuntime.Context.Assessment.Version);
        newRuntime.Context.Logger.WriteLog("Session started by user: " + newRuntime.Context.CurrentUser.Name + "for participant ID: " + newSession.ParticipantId);




        return newRuntime;
    }

    //start from a previous existing session
    public AssessmentRuntime StartAdministrativeSession(NetScidDbContainer dataContext, Assessment assessment, Session previousSession, User currentUser, string pid = "", string resumefromlatest = "false")
    {

        AssessmentRuntime newRuntime = new AssessmentRuntime(this, dataContext);
        Session newSession = new Session();


        Assessment sessionAssessment = assessment;





        newSession.ParticipantId = previousSession.ParticipantId;
        //THE OTHER ENTITIES BESIDES THE SESSION NEED TO BE DETATCHED AND RE-ATTACHED (BY BEING ADDED TO THE NEW SESSION)  
        assessment.PrepElements();
        newRuntime.RenderedDiagnoses = new RenderedDiagnosisModel(newRuntime.Context.AdministeredItemOrderByName);

        List<Response> prevresponses = previousSession.Responses.ToList();

        if (sessionAssessment == assessment)
        {
            foreach (Response prevresponse in prevresponses)
            {
                newRuntime.Context.CachedAssessmentResponses.Add(prevresponse.Item.ItemName, prevresponse);

                dataContext.Detach(prevresponse);

                newSession.Responses.Add(prevresponse);
            }
        }
        else
        {
            //the sessionAssessment is now the more up-to-date one so the responses pulled will have to be mapped, not just detatched and copied
            foreach (Response prevresponse in prevresponses)
            {
                Dictionary<string, FixedLengthItem> newAssessmentItemNames = AssessmentHelper.GetAssessmentItems(sessionAssessment);

                if (!newAssessmentItemNames.ContainsKey(prevresponse.Item.ItemName))
                    continue;

                Response newResponse = new Response
                {
                    NumericValue = prevresponse.NumericValue,
                    Item = newAssessmentItemNames[prevresponse.Item.ItemName],
                    ItemName = prevresponse.Item.ItemName,
                    AdministeredOrder = -1,
                    Value = prevresponse.Value
                };

                newRuntime.Context.CachedAssessmentResponses.Add(newResponse.Item.ItemName, newResponse);

                newSession.Responses.Add(newResponse);
            }



        }
        newSession.SessionDataJSON = previousSession.SessionDataJSON;

        //DxData
        newRuntime.RenderedDiagnoses =
            JsonConvert.DeserializeObject<RenderedDiagnosisModel>(newSession.GetSessionData("dxdata"));



        //inc session is =2 when the the session has been resumed by
        previousSession.IncSession = 2;



        newSession.SetSessionData("previoussession", previousSession.Id.ToString());

        newSession.Participant = previousSession.Participant;

        newSession.Assessment = sessionAssessment;
        newSession.User = currentUser;
        newSession.PermissionEntity = currentUser.PermissionEntity;
        newSession.StartTime = DateTime.Now;
        dataContext.Sessions.AddObject(newSession);



        dataContext.SaveChanges();

        newRuntime.formulaEngine = new FixedLengthFormulaEngine(newRuntime);



        initMultiItemGroups(assessment, dataContext);



        newSession.SetSessionData("continuedsession", newSession.Id.ToString());


        this.CurrentSessionId = newSession.Id;
        this.CurrentUserId = currentUser.Id;
        this.CurrentAssessmentId = assessment.Id;

        this.GetAssessmentItems(assessment);  //to populate the items dict
        this.SetUpPreviousResponses(newSession); //populates SSO responses

        newRuntime.Context = new RuntimeContext(this, dataContext);
        if (newRuntime.RenderedDiagnoses != null)
            newRuntime.RenderedDiagnoses.reInitAdminOrder(newRuntime.Context.AdministeredItemOrderByName);
        newRuntime.formulaEngine.InitializeContext(this.AssessmentItemsIds.Keys.ToList());


        return newRuntime;
    }



    //start from the SSO
    public AssessmentRuntime ResumeSessionFromState(NetScidDbContainer dataContext)
    {

        AssessmentRuntime newRuntime = new AssessmentRuntime(this, dataContext);

        newRuntime.formulaEngine = new FixedLengthFormulaEngine(newRuntime);
        newRuntime.formulaEngine.InitializeSerializedContext(serializedJSContext);

        newRuntime.Context = new RuntimeContext(this, dataContext);
        if (this.CurrentAssessmentElementId != 0)
        {
            newRuntime.CurrentAssessmentElement = (from ae in dataContext.AssessmentElements
                where ae.Id == this.CurrentAssessmentElementId
                select ae).FirstOrDefault();

            newRuntime.CurrentAssessmentElement.GetNewRuntime(newRuntime.Context);
        }
        return newRuntime;
    }



    private void GetAssessmentItems(Assessment assessment)
    {
        var fixedLengthElements = (from elements in assessment.AssessmentElements
                                   where elements is FixedLengthBlock
                                   select elements);

        foreach (FixedLengthBlock elemblock in fixedLengthElements)
        {
            foreach (FixedLengthItem item in elemblock.ItemBank.Items)
            {
                item.aeRef = elemblock;
                AssessmentItemsIds.Add(item.ItemName, item.Id);
            }
        }



    }


    private void SetUpPreviousResponses(Session newSession)
    {

        //put response IDs by itemname into this dictionary

        SessionResponseIds = (from response in newSession.Responses
                              select response).ToDictionary(key => key.ItemName, value => value.Id);

    }








}

RenderablePersistanceObject看起来像这样:

代码语言:javascript
复制
   public class RenderablePersistanceObject
    {
        public int primaryItemId;
        public int MultiItemGroupId;
        public bool isMultiItem;
    }
EN

回答 2

Stack Overflow用户

发布于 2014-04-16 05:49:14

你不能像那样序列化一个普通的字典。您可以查看这篇MSDN文章,了解有关实现的建议。如果你并不真正需要一个字典,也许List>会工作得更好?

票数 0
EN

Stack Overflow用户

发布于 2014-04-16 05:58:34

正如Erik所指出的,这是另一个对象上缺乏装饰器Serializable()导致的问题。添加它解决了我的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23094464

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档