0

How do I move data from an Iactionresult to another action result? I have been trying to display the data from the form and view it another Iactionresult? I attempt to use Tempdata but it seems like there is an error. Could anyone help me with it?

This action displays an individual product details when I click on an particular Id.

  [HttpGet]
  public IActionResult Details(int id)
  {
     string sql = String.Format(@"SELECT * FROM WBProduct 
                                   WHERE Id = {0}", id);
     List<Product> lstProduct = DBUtl.GetList<Product>(sql);
     if (lstProduct.Count == 0)
     {
        TempData["Message"] = $"Product #{id} not found";
        TempData["MsgType"] = "warning";
        return RedirectToAction("Index");
     }
     else
     {
        
        Product cdd = lstProduct[0];

        return View(cdd);
     }

        

  }

I would like to display the the details of the product in this IActionResult

[HttpPost]
public IActionResult Create()
{
     return View("Create");
}

View for Details:

@model Product

<div>

    <div class="form-group row">
        <div class="offset-sm-2"><h2>@Model.ProductName</h2></div>
    </div>

    <div class="form-group row">
        <div class="offset-sm-2 col-sm-5">
            <img id="ImgPhoto" src="~/images/product/@Model.ProductImage" style="width:400px;" />
        </div>
    </div>

    <div class="form-group row">
        <label class="control-label col-sm-2" for="City">Weight: </label>
        <div class="col-sm-5">
            <input type="text" asp-for="ProductWeight" class="form-control" readonly />
        </div>
    </div>

    <div class="form-group row">
        <label class="control-label col-sm-2" for="Date">Stock :</label>
        <div class="col-sm-5">
            <input type="text" asp-for="ProductStock" class="form-control" readonly />
        </div>
    </div>



    <div class="form-group row">
        <label class="control-label col-sm-2" for="Cost">Price: </label>
        <div class="col-sm-5">
            <input type="text" asp-for="ProductPrice" asp-format="{0:C}" class="form-control" readonly />
        </div>
    </div>

    <div class="form-group row">
        <label class="control-label col-sm-2" for="Story">Description: </label>
        <div class="col-sm-5">
            <textarea asp-for="ProductDescription" rows="8" cols="20" class="form-control" readonly></textarea>
        </div>
    </div>

   
    

    <div class="form-group row">
        <a href="http://localhost:50528/Product/Create" class="btn btn-info" role="button" > Add to Cart </a>
    </div>

    </div>

Create View:

@model Product
<div class="form-group row">
    <div class="offset-sm-2"><h2>@Model.ProductName</h2></div>
</div>



<div class="form-group row">
    <label class="control-label col-sm-2" for="City">Weight: </label>
    <div class="col-sm-5">
        <input type="text" asp-for="ProductWeight" class="form-control" readonly />
    </div>
</div>

<div class="form-group row">
    <label class="control-label col-sm-2" for="Date">Stock :</label>
    <div class="col-sm-5">
        <input type="text" asp-for="ProductStock" class="form-control" readonly />
    </div>
</div>



<div class="form-group row">
    <label class="control-label col-sm-2" for="Cost">Price: </label>
    <div class="col-sm-5">
        <input type="text" asp-for="ProductPrice" asp-format="{0:C}" class="form-control" readonly />
    </div>
</div>

<div class="form-group row">
    <label class="control-label col-sm-2" for="Story">Description: </label>
    <div class="col-sm-5">
        <textarea asp-for="ProductDescription" rows="8" cols="20" class="form-control" readonly></textarea>
    </div>
</div>

The error message that I got was: enter image description here

2 Answers2

1

This should be a GET action, not a POST one, then you should extract the info from the TempData and pass it as parameter to the view cshtml.

 TempData["Product"] = JsonConvert.SerializeObject(lstProduct[0]);
 return RedirectToAction("Create");

Now you can deserialize in the Create action and retrieve your Product

[HttpGet]
public IActionResult Create()
{
     // If the caller has prepared a product we can show it.
     if(TempData.ContainsKey("Product"))
     {
         Product p = JsonConvert.DeserializeObject<Product>(TempData["Product"]);
         return View(p);
     }
     else
         return View();
}
Steve
  • 213,761
  • 22
  • 232
  • 286
  • I have edited the codes as it can only display the products when I include '{ Product cdd = lstProduct[0]; return View(cdd); }' How do I include the TempData? – iwanttopassmyfyp Jan 09 '21 at 17:42
  • Also a better example with reusable code can be find here https://stackoverflow.com/questions/34638823/store-complex-object-in-tempdata – Steve Jan 09 '21 at 18:15
0

If you want to move data from one action to another action in the same controller just call one action from another and put data as an input parameter of another action.

To send message to Index action, at first create a class for the message:

public class ErrorMsg
{
 public string Message {get; set;}
 public string MessageType {get; set;}
}

Change your action Index to this:

public IActionResult Index(ErrorMsg errorMsg)
  {
// if action called from another controller action, details for exapmple,
//errorMsg will contain data from that action
// otherwise errMsg will be an empty default object with empty strings

 //Check if error
if(!string.IsNullOrEmpty(errorMsg.Message) ...your error code
  else       ....your index code here
}

Change your action details code:

  public IActionResult Details(int id)
  {
     string sql = String.Format(@"SELECT * FROM WBProduct 
                                   WHERE Id = {0}", id);
     List<Product> lstProduct = DBUtl.GetList<Product>(sql);

     if (lstProduct.Count == 0)
     {
        var errMsg = new ErrMessage { 
        Message = $"Product #{id} not found",
        MessageType = "warning"
         }

        return Index(errMsg);
     }
     else
     {
       
       Product cdd= lstProduct.FirstOrDefault();
       //Or you can try again  var  cdd = lstProduct[0]; if you like it more

        return View("Details", cdd);
     }
  }

Change your create action to this:


public IActionResult Create(Product product)
{

// if action called from another controller action, "product" will contain data //from that action
// otherwise "product" will be posted from the view or it will be an empty model with the default value fields

 if(product.Id ==0)  ... call add ef code 
    else ... call update ef code
}

And you have to add <form tag to all your views, othewise if will not post back any data, and add Product.Id hidden field inside of form:

@model Product

@using (Html.BeginForm("Create", "Product", FormMethod.Post)
{
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>

<div>

<input type="hidden" asp-for="@Model.Id" />

    <div class="form-group row">
        <div class="offset-sm-2"><h2>@Model.ProductName</h2></div>
    </div>

    <div class="form-group row">
        <div class="offset-sm-2 col-sm-5">
            <img id="ImgPhoto" src="~/images/product/@Model.ProductImage" style="width:400px;" />
        </div>
    </div>

    <div class="form-group row">
        <label class="control-label col-sm-2" for="City">Weight: </label>
        <div class="col-sm-5">
            <input type="text" asp-for="ProductWeight" class="form-control" readonly />
        </div>
    </div>

    <div class="form-group row">
        <label class="control-label col-sm-2" for="ProductStock">Stock :</label>
        <div class="col-sm-5">
            <input type="text" asp-for="ProductStock" class="form-control" readonly />
        </div>
    </div>



    <div class="form-group row">
        <label class="control-label col-sm-2" for="ProductPrice">Price: </label>
        <div class="col-sm-5">
            <input type="text" asp-for="ProductPrice" asp-format="{0:C}" class="form-control" readonly />
        </div>
    </div>

    <div class="form-group row">
        <label class="control-label col-sm-2" for="ProductDescription">Description: </label>
        <div class="col-sm-5">
            <textarea asp-for="ProductDescription" rows="8" cols="20" class="form-control" readonly></textarea>
        </div>
    </div>

    <div class="form-group row">
        <button class="btn btn-info btn-link" type="submit"> Add to Cart </button>
    </div>

    </div>  
}
Serge
  • 40,935
  • 4
  • 18
  • 45
  • I am sorry but I don't understand what are trying to reach. – Serge Jan 09 '21 at 17:53
  • I have edited my codes above in the question. The codes you suggested returns an error message as it could find the specific product details. With the newly edited codes, how do I call move the data? @Sergey – iwanttopassmyfyp Jan 09 '21 at 18:07
  • I see your details view but I don't see any form there. So I am wondering where are data going when you click link ? Acording href it should be going to create. Are you trying to move model detail back to details or to create? And when do you need to move data from one action to another? – Serge Jan 09 '21 at 18:20
  • I am trying to move the data from Details action to Create action. – iwanttopassmyfyp Jan 10 '21 at 02:17
  • @iwanttopassmyfyp I don' t see why do you need it. If product is not found you just return view details with the empty product as a model, otherwis view details fields will be init with product values. Could you show your create view pls – Serge Jan 10 '21 at 08:59