简体   繁体   中英

Storing session inside partial view

I am trying to write an ASP.NET MVC application which links a person's relation to other members of the family.

I am trying to implement the following screen:

在此输入图像描述

Where each member is implemented via a bootstrap tab, so far I am able to navigate between tabs based on dynamically generated id(s).

View markup:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

@using HouseHolderInfoSystem.Entity.Models

<script type="text/javascript">
  $(function() {

    // Navigation click handler
    $(".relation_link").click(function(event) {

      //Get the ID
      const memberId = $(this).attr("data-memberId");

      // AJAX call to get the partial view content
      $.ajax({
        url: '@Url.RouteUrl(routeName: "DisplayRelationTagger")',
        type: 'POST',
        dataType: 'HTML',
        contentType: 'application/json; charset=utf-8',
        data: JSON.stringify({
          MemberId: memberId,
          ApplicationId: '@ViewBag.ApplicationId'
        }),
        success: function(data) {
          //populate the tab content.
          $(`#${memberId}`).html(data);
        },
        error: function(jqXHR, textStatus, errorThrown) {
          console.error('Could not update the div because of some error!');
        }
      });
    });
  });
</script>

<br />

<div class="container">
  <div class="container">
    <div class="row">
        <div class="col-lg-12">
            <h2>Household Relationships</h2>
            <br>
            <h4>
                Please tell us how the members of your household are related to each other
            </h4>

            <hr>
            <br>

            @if (ViewBag.FamilyMembers != null)
            {
                <ul class="nav nav-tabs">
                    @for (int i = 0, familyMembersCount = (ViewBag.FamilyMembers as List<FamilyMember>).Count; i < familyMembersCount; i++)
                    {
                        if (i == 0)
                        {
                            <li class="active">
                                <a data-toggle="tab" class="relation_link" data-memberId="@Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).FamilyMemberId))" href="#@Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).FamilyMemberId))"> @Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).FirstName)) @Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).LastName)) </a>
                            </li>
                        }
                        else
                        {
                            <li>
                                <a data-toggle="tab" class="relation_link" data-memberId="@Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).FamilyMemberId))" href="#@Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).FamilyMemberId))"> @Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).FirstName)) @Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).LastName)) </a>
                            </li>
                        }
                    }
                </ul>

                <div class="tab-content">
                    @for (int i = 0, familyMembersCount = (ViewBag.FamilyMembers as List<FamilyMember>).Count; i < familyMembersCount; i++)
                    {
                        if (i == 0)
                        {
                            <div id="@Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).FamilyMemberId))" class="tab-pane fade in active">
                                @(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).FirstName)) @Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).LastName))
                            </div>
                        }
                        else
                        {
                            <div id="@Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).FamilyMemberId))" class="tab-pane fade">
                                @(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).FirstName)) @Html.Raw(Html.AttributeEncode((ViewBag.FamilyMembers[i] as FamilyMember).LastName))
                            </div>
                        }
                    }
                </div>
            }
            <br>
        </div>
    </div>

<div class="row">
  <div class="col-lg-4">
    @Html.RouteLink("Back", "", null, new { @class = "btn btn-lg btn-danger" })
  </div>
  <div class="col-lg-4">
  </div>
  <div class="col-lg-4">
    @Html.RouteLink("Save and submit", "", null, new { @class = "btn btn-lg btn-primary" })
  </div>
</div>
</div>

Partial view code:

@using HouseHolderInfoSystem.Entity.Models

<script>
        function ChangeRelationSelection(CurrentMemberId, RelatedFamilyMemberId, Relation ) {
            if ( !CurrentMemberId || !RelatedFamilyMemberId || !Relation )
            {
                alert( `Current member ID or Related member ID or Relation cannot be empty!` );
                return;
            }


            const url = `@Url.RouteUrl(routeName: "UpdateRelationTagging")`;
            const options = {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json; charset=utf-8',
                    'Access-Control-Allow-Origin': '*'
                },
                body: JSON.stringify( { FamilyMemberId: CurrentMemberId, RelatedFamilyMemberId: RelatedFamilyMemberId, Relation: Relation } ),
            };

            fetch( url, options )
                .then(res => res.json())
                .then( data => console.log(data.message))
                .catch(error => console.error( error.message ));
        }



</script>

@if (ViewBag.CurrentMember != null && ViewBag.RemainingMembers != null)
{
    <br>
    <fieldset>
        <legend>Relationships of @Html.Raw(Html.AttributeEncode((ViewBag.CurrentMember as FamilyMember).FirstName)) @Html.Raw(Html.AttributeEncode((ViewBag.CurrentMember as FamilyMember).LastName))</legend>


        @foreach (FamilyMember familyMember in (List<FamilyMember>)ViewBag.RemainingMembers)
        {
            <div style="display:block" class="form-group">
                <span style="color:red; font-size:16px;">* </span>
                <span>
                    Relationship to @(Html.AttributeEncode((familyMember as FamilyMember).FirstName)) @Html.Raw(Html.AttributeEncode((familyMember as FamilyMember).LastName))
                </span>
                <select id='@(Html.AttributeEncode(familyMember.FamilyMemberId))' class="form-control relationSelect" onchange="ChangeRelationSelection('@(Html.AttributeEncode(ViewBag.CurrentMemberId))', '@(Html.AttributeEncode(familyMember.FamilyMemberId))', event.currentTarget.value)">
                    <option selected disabled>----Please select a relation----</option>
                    <option value="Father">Father</option>
                    <option value="Mother">Mother</option>
                    <option value="Son">Son</option>
                    <option value="Daughter">Daughter</option>
                    <option value="Husband">Husband</option>
                    <option value="Wife">Wife</option>
                </select>
            </div>
            <br>
        }
    </fieldset>

}

C# controller code:

[Route("tag-relations/{ApplicationId:guid}", Name = "TagRelationGet")]
public ActionResult TagRelations(string ApplicationId)
{
    Application currentApplication = _applicationService.GetApplicationById(ApplicationId);
    ViewBag.FamilyMembers = currentApplication.FamilyMembersApplication.ToList();
    ViewBag.ApplicationId = ApplicationId;
    return View();
}

 [HttpPost]
        [Route("~/display-relations", Name = "DisplayRelationTagger")]
        public PartialViewResult DisplayRelationTagging(RelationTaggingDTO TaggingDTO)
        {
            Application currentApplication = _applicationService.GetApplicationById(TaggingDTO.ApplicationId);

            FamilyMember currentlySelectedFamilyMember = currentApplication.FamilyMembersApplication.FirstOrDefault(x => x.FamilyMemberId == TaggingDTO.FamilyMemberId);
            List<FamilyMember> remainingFamilyMembers = currentApplication.FamilyMembersApplication.Where(x => x.FamilyMemberId != TaggingDTO.FamilyMemberId).ToList();

            // Store family member member count into session for later use
            Session["FamilyMemberCount"] = currentApplication.FamilyMembersApplication.ToList().Count;

            ViewBag.CurrentApplicationId = TaggingDTO.ApplicationId;
            ViewBag.CurrentMemberId = TaggingDTO.FamilyMemberId;
            ViewBag.CurrentMember = currentlySelectedFamilyMember;
            ViewBag.RemainingMembers = remainingFamilyMembers;

            if (Session["RelationTagging"] != null)
            {
                List<UpdateRelationTaggingDTO> allRelations = JsonConvert.DeserializeObject<List<UpdateRelationTaggingDTO>>(Session["RelationTagging"].ToString());

                List<UpdateRelationTaggingDTO> currentlySelectedRelations = new List<UpdateRelationTaggingDTO>();

                foreach (var item in allRelations)
                    foreach (var innerItem in remainingFamilyMembers)
                        if (item.RelatedFamilyMemberId == innerItem.FamilyMemberId)
                            currentlySelectedRelations.Add(item);

                if (currentlySelectedRelations.Count > 0)
                    ViewBag.TaggedRelationMembers = JsonConvert.SerializeObject(currentlySelectedRelations);
            }

            return PartialView("DisplayRelationshipTagger");
        }

I know I have to partial view inside the tab content and call it using ajax, but my question is two-fold.

  1. Let's say when I click on tab 1 which has person 1, I need to show all the members in the form except the current person which are Person 2 and Person 3.

    在此输入图像描述

  2. How to store the relationships inside the session so that it can be only submitted once to the database after finishing all the relationship tagging.

What you can do in the code is to use Jquery in your main page

IF this is your current Select Statement

<select id='@(Html.AttributeEncode(familyMember.FamilyMemberId))' class="form-control relationSelect" onchange="ChangeRelationSelection('@(Html.AttributeEncode(ViewBag.CurrentMemberId))', '@(Html.AttributeEncode(familyMember.FamilyMemberId))', event.currentTarget.value)">
                    <option selected disabled>----Please select a relation----</option>
                    <option value="Father">Father</option>
                    <option value="Mother">Mother</option>
                    <option value="Son">Son</option>
                    <option value="Daughter">Daughter</option>
                    <option value="Husband">Husband</option>
                    <option value="Wife">Wife</option>
                </select>

You can add More Attributes in a "data" attributes like

<select id='@(Html.AttributeEncode(familyMember.FamilyMemberId))' **data-familyid="@(Html.AttributeEncode(familyMember.FamilyMemberId))"
 data-memberid="@(Html.AttributeEncode(ViewBag.CurrentMember.Id))"**
  class="form-control relationSelect" onchange="ChangeRelationSelection('@(Html.AttributeEncode(ViewBag.CurrentMemberId))', '@(Html.AttributeEncode(familyMember.FamilyMemberId))', event.currentTarget.value)">
                    <option selected disabled>----Please select a relation----</option>
                    <option value="Father">Father</option>
                    <option value="Mother">Mother</option>
                    <option value="Son">Son</option>
                    <option value="Daughter">Daughter</option>
                    <option value="Husband">Husband</option>
                    <option value="Wife">Wife</option>
                </select>

Once you have both IDs available (ie the CurrentMemberID and the FamilyMemberID on the Dropdown)

Next what you can do is

$(".relationSelect").change(function(){
//Here what you can do is read the data attributes
var familyid = $(this).data("familyid");
var MemberId = $(this).data("memberid");
var relation = $(this).val();
 // Next step is to send it via tha ajax to server and store it in the session, as you require 
$.post("@Url.Action("StoreInSession", "Controller")", {MemberID: MemberId, familyID :familyid, relation : relation}, function(resp){

});

Next Part in the Controller you can have a Model that can store the data in this format

public class RelationStore 
{
    public string MemberID {get;set;}
    public Dictionary<string,string> RelationAndFamily {get;set;}
}

and In Controller

public JsonResult(string FamilyId, string memberId, string Relation )
{
    List<RelationStore> I = Session("RelationStore") as List<RelationStore>;
    //Make your Logic to Add to the List and then put the list back in session 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM