简体   繁体   中英

How to keep track of a certain ID while switching through different views in ASP.NET Core?

I have a table called "Releases" with the following fields:

在此处输入图片说明

And also a table called "Phases":

在此处输入图片说明

As you can see, I have a foreign key called ReleaseId in the second table. What I am trying to do is create multiple Phases within a Release.

In order to do that, in the creation of a Phase, I must also include the ReleaseId , and that should be known by the system beforehand.

I will now make a short walk-through and include some code snippets.

在此处输入图片说明

The above screenshot shows the Index method of the ReleaseController. Upon clicking on a Release Name , it will switch the view to show the phases included in that certain release.

PhaseController.cs

public ActionResult Index(int id)
    {
        List<Phase> phaseList = new List<Phase>();

        string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();

            string sql = "ReadPhases";
            SqlCommand command = new SqlCommand(sql, connection);
            command.CommandType = CommandType.StoredProcedure;

            SqlParameter parameter = new SqlParameter
            {
                ParameterName = "@ReleaseId",
                Value = id,
                SqlDbType = SqlDbType.VarChar,
                Size = 50
            };

            command.Parameters.Add(parameter);
            using (SqlDataReader dataReader = command.ExecuteReader())
            {
                while (dataReader.Read())
                {
                    Phase phase = new Phase();
                    phase.Id = Convert.ToInt32(dataReader["Id"]);
                    phase.Name = Convert.ToString(dataReader["Name"]);
                    phase.ReleaseId = Convert.ToInt32(dataReader["ReleaseId"]);
                    phaseList.Add(phase);
                }
            }

            connection.Close();
        }
        return View(phaseList);
    }

When you click a Release Name , the method above gets called properly with the help of <a class="btn btn-secondary" asp-area="" asp-controller="Phase" asp-action="Index" asp-route-id="@p.Id"> as in this way I am able to pass the ReleaseId to the Index method. Everything is alright so far as I was able to pass the ReleaseId that I needed.

The problem now is when I want to create a new Phase. I don't know how to get the ReleaseId anymore at this point because I lost the Release model and I can't import multiple models in a view.

   public IActionResult Create()
{
    return View();
}

[HttpPost]
public IActionResult Create(Phase phase)
{
    string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        string sql = "CreatePhase";

        using (SqlCommand command = new SqlCommand(sql, connection))
        {
            command.CommandType = CommandType.StoredProcedure;

            // adding parameters
            SqlParameter parameter = new SqlParameter
            {
                ParameterName = "@Name",
                Value = phase.Name,
                SqlDbType = SqlDbType.VarChar,
                Size = 50
            };
            command.Parameters.Add(parameter);

            parameter = new SqlParameter
            {
                ParameterName = "@ReleaseId",
                Value = phase.ReleaseId,
                SqlDbType = SqlDbType.Int
            };
            command.Parameters.Add(parameter);

            connection.Open();
            command.ExecuteNonQuery();
            connection.Close();
        }
    }

    return RedirectToAction("Index");
}

Above is the Create() method. Of course, at this point, it does not work because ReleaseId is an empty field, as I couldn't figure out how to pass it all the way to this view.

Therefore , how can I pass the initial ReleaseId that I first passed when I redirected to the Index method in PhaseController all the way to the Create method?

Hopefully, this is enough information to understand my problem. I opted to exclude the .cshtml code snippets as there was not much going on there. Please let me know if I have to put some more code in the original post.

EDIT:

Index.cshtml (Phase)

@model IEnumerable<Phase>

<h1 class="bg-info text-white">All Phases
    <input type="button"
       onclick="location.href='@Url.Action("Create", "Phase", phase.ReleaseId)'"
       value="Create Phase" /></h1>

<table class="table table-sm table-bordered">
    <tr><th>Name</th><th>Change Name</th><th>Delete</th></tr>
    @foreach (var phase in Model)
    {
        <tr>
            <td>@phase.Name</td>
            <td><a class="btn btn-sm btn-primary" asp-action="Update" asp-route-id="@phase.Id">Change Name</a></td>
            <td>
                <form asp-action="Delete" asp-route-id="@phase.Id" method="post">
                    <button type="submit" class="btn btn-sm btn-danger">
                        Delete
                    </button>
                </form>
            </td>
        </tr>
    }
</table>

You should pass your ReleaseId as a parameter in Create Action. There are a lot of ways to pass a parameter, in the simplest method you can use query string like below:

public IActionResult Create(int releaseId)
{
    ViewDat["ReleaseId"] = releaseId;
    return View();
}

you will need to supply releaseId to your PhaseController's Create Action from the view whereever you are displaying Create button:

<input type="button" 
       onclick="location.href='@Url.Action("Create", "Home", new {Model.FirstOrDefault()?.ReleaseId} )'" 
       value="Create Phase"/>

if you don't button, then you can use it with anchor tag as well as shown below:

<a href='@Url.Action("Create", "Home", new {Model.FirstOrDefault()?.ReleaseId}  )'>Create Phase</a>

Since, we are using FirstOrDefault and when there are no phases then releaseId could be null. So, modify your action to take in nullable int as shown below:

public IActionResult Create(int? releaseId)
{
      if (releaseId.HasValue)
      {
          // Logic when releaseId available
      }
      else
      {
          // Logic when releaseId not available
      } 
}

You can use Query String for carrying the indexes. If this index should be secured you can create a hash key and use that key in the Query String instead of the actual index to prevent manual modifications from the url.

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