1

I have a basic Model as:

public class Events
{
    public int Id { get; set; }
    public string title { get; set; }
    public string amount { get; set; }
    public string Finance_Approval { get; set; }
}

I want to connect two different controllers to this single view, one for the requesters who can fill only the title and amount fields. And the second controller for Finance Manger to approve the request by filling the Finance_Approval field in the table.

I have created two controllers and their razor views as follows:

Requester Controller:

   public ActionResult Index()
    {
        return View();
    }

    public ActionResult Request(Events e)
    {
        _context.evt.Add(e);
        _context.SaveChanges();

        return Content("Added");
    }

It's Razor View:

@using (Html.BeginForm("Request", "Requester"))
{
<div class="form-group">
    @Html.LabelFor(a => a.title)
    @Html.TextBoxFor(a => a.title, new { @class = "form-control" })
</div>
<div class="form-group">
    @Html.LabelFor(a => a.amount)
    @Html.TextBoxFor(a => a.amount, new { @class = "form-control" })
</div>

<button class="btn btn-primary">Request</button>
}

And this is the Finance Controller:

  public ActionResult Index()
    {

        return View();
    }

    public ActionResult Approve(Events e)
    {

        _context.evt.Add(e);
        _context.SaveChanges();
        return Content("Approved!");
    }

And This is its Razor View:

@using (Html.BeginForm("Approve", "Finance"))
{

<div class="form-group">
    @Html.LabelFor(a => a.Finance_Approval)
    @Html.TextBoxFor(a => a.Finance_Approval, new { @class = "form-control" })
</div>

<button class="btn btn-primary">Approve</button>
 }

Now based on the razor view designs for both controller, the Requester can insert into two predefined fields which are title and amount and so is the finance manager which is Finance_Approval field only.

But the problem is that whenever the finance manager approves the request from his portal lets say with some value as "Yes", Then this value gets inserted into an entirely new row which does not have any connection with the rows filled by the requesters.

I want that finance manager should be able to approve the rows which has some value (which are filled by requesters), but i can not figure out the logic.


@erShoaib Here is the final updates:

  public ActionResult Index()
    {

        var all = _context.evt.ToList();
        return View(all);

    }

    public ActionResult Details(int? Id)
    {
        if (Id == 0)
        {
            return HttpNotFound();
        }

        var evtt = _context.evt.Find(Id);

        return View(evtt);
    }

    public ActionResult Approve(Events e)
    {
        if (e==null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Events evt = _context.evt.Find(e.Id);
        evt.Finance_Approval = e.Finance_Approval;

        //_context.evt.Add(e);
        _context.SaveChanges();
        return Content("Approved!");
    }

This is the full index:

   @model IEnumerable<InsertFromdifferentControllers.Models.Events>

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<table class="table table-bordered table-hover">
@foreach (var item in Model)
{

  <tbody>
      <tr>
          <td>@item.Id</td>
          <td>@item.title</td>
          <td>@item.amount</td>
          <td>@Html.ActionLink("Expand","Details","Finance", new { Id = 
  @item.Id},null)</td>
      </tr>
  </tbody>

  }

 </table>

And this is the view for Details:

@model InsertFromdifferentControllers.Models.Events

<table class="table table-bordered table-hover table-responsive">


<tbody>
    <tr>
        <td>@Model.Id</td>
        <td>@Model.title</td>
        <td>@Model.amount</td>
        @using (Html.BeginForm("Approve","Finance"))
        {
            <div class="form-group">
                @Html.LabelFor(a=> a.Finance_Approval);
                @Html.TextBoxFor(a=> a.Finance_Approval, new { @class="form-control"})
            </div>
            <button class="btn btn-primary">Save</button>
        }
    </tr>
</tbody>

halfer
  • 19,824
  • 17
  • 99
  • 186
John Kamaal
  • 129
  • 8
  • you need to get that record which is added by Requester in Finance controller index method and pass it to finance controller index view and when finance manager click approve button then same record is come back to Approve action method with Finance_Approval value and then in Approve action method you have to update that record – er-sho Oct 31 '18 at 14:05
  • Could you edit your question to add the way you display the `Events` to validate in the Finance view? Apart from that, use PascalCase for your properties and a boolean for finance approval – Manta Oct 31 '18 at 22:10
  • @ershoaib thank you, I got what you are trying to say, but still struggling in writing the correct logic. can you help a little more? Can u write or hint with a little coding? – John Kamaal Nov 01 '18 at 04:45
  • @JohnKamaal, I added my answer below, if you found well then mark the tick on left side of answer to make it green :) – er-sho Nov 01 '18 at 06:00
  • @ershoaib thank you for your contribution, i tried your approach but it gives an error as: object reference not set to an instance of an object. And it gives reference to this file: Projects\InsertFromdifferentControllers\InsertFromdifferentControllers\Views\Finance\Index.cshtml. (It also marks the foreach line as red) – John Kamaal Nov 03 '18 at 05:09
  • @JohnKamaal, did u assign strongly type model for this view means `Events` class as model? – er-sho Nov 03 '18 at 05:29
  • @JohnKamaal, add your finance controller index method and its full view in your question – er-sho Nov 03 '18 at 05:46
  • @ershoaib I have added the updated Finance controller and the complete index view in question. Please check it at above. – John Kamaal Nov 03 '18 at 07:08
  • @JohnKamaal, whats this line mean in your finance index view => `@Html.ActionLink("Expand","Details","Finance", new { Id = @item.Id},null)` bcoz i didnt see any `Details` action method in your controller? – er-sho Nov 03 '18 at 07:13
  • @ershoaib ok ignore that line, i was trying to access each item individually. Now i removed that line, still it gives the error – John Kamaal Nov 03 '18 at 07:18
  • @JohnKamaal, your index view is of model type `IEnumerable` and it action method returns single `Events` so thats why this error comes but where is your form => `@using (Html.BeginForm("Approve", "Finance"))` on view? – er-sho Nov 03 '18 at 07:21
  • @JohnKamaal, yes sure, if you provide me enough and relevant details then I'll provide you solution asap – er-sho Nov 03 '18 at 07:29
  • @ershoaib thank you for your support, I edited the question as FInal Updates, Kindly check it at above. It still gives the same error but this time marks the following line in RED in finance controller. evt.Finance_Approval = e.Finance_Approval; – John Kamaal Nov 03 '18 at 07:51
  • @JohnKamaal, does your details view properly render all the details of specific event after clicking on `Expand` action link? – er-sho Nov 03 '18 at 08:47
  • @JohnKamaal, copy that RED line error here – er-sho Nov 03 '18 at 08:47
  • @ershoaib yeah it renders all the details along with a text box to enter some value for example "Yes" and a submit button to save. but when i click on save it says, object reference not set to an instance of an object. and it highlights this line in red: evt.Finance_Approval = e.Finance_Approval; – John Kamaal Nov 03 '18 at 09:44
  • add this line => `@Html.HiddenFor(a => a.Id);` inside `@using (Html.BeginForm("Approve","Finance"))` just above to `
    ` and try again and let me know. i think we are closed to solve your problem
    – er-sho Nov 03 '18 at 09:53
  • wow now it works very fine, thank you so much @ershoaib – John Kamaal Nov 03 '18 at 10:00
  • @ershoaib you helped alot, thank you very much, it means a lot – John Kamaal Nov 03 '18 at 10:01
  • @JohnKamaal, glat to hear that you have get rid from your problem, and welcome :) – er-sho Nov 03 '18 at 10:06
  • @ershoaib could you please help me with this question https://stackoverflow.com/questions/53258489/issues-with-uploading-file-in-asp-net-c-sharp-application-object-reference-not?noredirect=1#comment93401506_53258489 – John Kamaal Nov 12 '18 at 08:49

1 Answers1

0

Your Requester Controller and its View was perfect means requester successfully added new record to db.

For example: title = "Abc", amount="123" and after added this record suppose id was 10

Now in Finance Controller you need to get above record in Index method like

public ActionResult Index(int id=0)                 <=  Pass "id=10"
{
   if(id == 0)
   {
     return HttpNotFound();
     //or code to handle request when id = 0
   }

   Events events = _context.evt.Find(id);           <= The "Find" function can get record with id=10
   return View(events);                             <= Pass found record to view.
}

After change made by finance manager to Finance_Approval field of above record with id is 10

For example: Finance_Approval = "Approved". Then all the fields of record with this new field can be posted to Approve action method in Finance Controller.

And then you need to update above record like

public ActionResult Approve(Events e)               <= Now "e" contains id=10, title="Abc", amount="123" and Finance_Approval="Approved"
{
    if(e == null)
    {
         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    Events events = _context.evt.Find(e.id);        <= Fetch record of id=10 from database.
    events.Finance_Approval = e.Finance_Approval;   <= Assign changes to found record with posted data from view.
    _context.SaveChanges();
    return Content("Approved!");
}
er-sho
  • 9,581
  • 2
  • 13
  • 26