0

I'm building a web based tool for our IT team to use to handle our IT checks and record the results.

I'm using entity framework.

Here is my object for each check to be carried out.

public class Check
{
    [Key]
    public int CheckID { get; set; }
    //public ICollection<ITDept> ItDepts { get; set; }
    //[UIHint("TeamEditor")]
    public int ITDeptID { get; set; }
    public string CheckName { get; set; }
    public string LinkToCheck { get; set; }
    public string Description { get; set; }
}

I want to create a form that will load all the checks for a given "ITDeptID".

public ActionResult LoadView(int TeamID)
{
    ViewData["NeededChecks"] = _db.Checks.Where(p => p.ITDeptID == TeamID).ToList();

    return View();
}

Then take that data and save it with the results of each check.

public class HistoricChecks
{        
    [Key]
    public int Id { get; set; }
    public string SentBy { get; set; }
    public DateTime SentTime { get; set; }
    public List<CheckLink> Checks { get; set; }
}

public class CheckLink
{

    [Key]
    [Column(Order = 0)]
    public int CheckEntryId { get; set; }

    [Key]
    [Column(Order = 1)]
    public int LinkedCheckID { get; set; }
    public int CheckIDFromList { get; set; }
    public bool PassFail { get; set; }
    public string Comments { get; set; }
}

What is the best way to create a form in which there is an entry for Check assigned to the ITDeptID passed to it.

This is what I have so far.

@using AppSupportCommunicationTool.Models
@model  HistoricChecks
<body>
    @using (Html.BeginForm("Post", "Form", FormMethod.Post, new { @name = "MainForm" }))
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <fieldset>
            <table width="1000" align="center">

                @foreach (var check in ViewData["NeededChecks"] as List<Check>)
                {
                    <tr>
                        <td>
                            Check Name: @{ @check.CheckName }
                            <br />Check documentation: @{ @check.LinkToCheck }
                            <br />Check Description: @{ @check.Description }
                        </td>
                        <td>
                            @Html.EditorFor(m => m.Checks)
                        </td>
                    </tr>
                }
            </table>
        </fieldset>
        <input type="submit" />
    }
</body>

I did try creating a EditorTempalte but it didn't get loaded.

Many thanks.

ataravati
  • 8,891
  • 9
  • 57
  • 89
Tom Kelly
  • 509
  • 2
  • 4
  • 16
  • 4
    You don't pass your data to your view using `ViewData`. You should use a model. That's why it's called MVC (Model-View-Controller). Please read more about asp.net MVC before starting to code. – ataravati Dec 10 '15 at 15:45
  • I understand that but i'm passing the data of a different model to the one my form will be using. – Tom Kelly Dec 10 '15 at 15:50
  • You told "it didn't get loaded". So what is not loaded? If you mean though view rendered as expected but with No data, then did you try putting a break point in controller to check if your Entity Framework query return any results or not? – Siva Gopal Dec 10 '15 at 15:50
  • The editorTemplate for the CheckLink model did not render in the view – Tom Kelly Dec 10 '15 at 15:52
  • 3
    @TomKelly, then you should create a view model, and combined the data from the two models. – ataravati Dec 10 '15 at 15:52
  • @TomKelly Where is the [UIHint](http://stackoverflow.com/questions/8196372/what-is-use-of-uihint-attribute-in-mvc) you specified? Then check similar posts if you did something wrong to create Editor Template. – Siva Gopal Dec 10 '15 at 15:55
  • 1
    @ataravati is right, this is what I would suggest too – Rob C Dec 10 '15 at 15:57
  • Why is you view `@model HistoricChecks`? You don't even generate any html associated with that class. The only html your generating is for `Check` so it should be `@model IEnumerable`. And to display the html for each `Check` its just `@Html.EditorFor(m => m)` (no `foreach` loop). –  Dec 11 '15 at 01:47
  • But your current code shows `@Html.EditorFor(m => m.Checks)` which of course wont do anything since the value of `Checks` is null (you do not pass a model to the view so there is nothing to render) and in any case property `Checks` is typeof `List` which is not the same as `List` so nothing will ever bind when you submit the form anyway. Impossible to understand what your really trying to do with this code –  Dec 11 '15 at 01:48

1 Answers1

0

You could benefit from the Model-View-View Model approach, what you would do in essence:

public class ProductViewModel
{
     private Product product;
     private List<Account> account;

     public ProductViewModel(Product product, List<Account> account)
     {
          this.product = product;
          this.account = account;
     }

     public bool ValidAccountForProduct
     {
          get
          {
               var result = account.Where(i => i.Role == 3 || i.Role == 1);
               if(result.Any())
                   return true;

               return false;
          }
     }
}

This is a very, very primitive example. In essence, what this code reflects is what I believe your intent is. So you would pass your two domain entities into this new class, the class will than perform the required check and output directly onto your page in a manner that accurately reflects the content of that page. So in this simple example, it will add a Property for me, ValidAccountForProduct, so if a user is in said role, they should see this product. So on the front-end with Razor as I itterate:

@Model List<ProductViewModel>
@foreach(var model in Model)
{
     if(model.ValidAccountForProduct)
     {
          // Output those Products.
     }
}

Obviously you would need to populate your Product and Account with any other information for the view, but it will be a clear concise approach rather than manipulating the ViewData to represent.

Greg
  • 11,302
  • 2
  • 48
  • 79