how to pass one-to-many from controller to view in

2019-03-01 17:56发布

Ok so this would be after changes that you guys helped me with , im assuming im getting a syntax error somewhere

View

@model OilNGasWeb.ModelData.Clients

@{
ViewBag.Title = "Index";
}


<h2>County's for </h2> 

<p>
@Html.ActionLink("Create New", "Create",new { id = Model.ClientID },null) 
</p>


<table>
<tr>

    <th>
        @Html.DisplayNameFor(model => model.County) 
    </th>

    <th>
        @Html.DisplayNameFor(model => model.Note) 
    </th>

    <th>
        @Html.DisplayNameFor(model => model.Comment) 
    </th>

</tr>

@foreach (var item in Model.Countys) {
<tr>

    <td>
        @Html.DisplayFor(modelItem => item.County)
    </td>

    <td>
        @Html.DisplayFor(modelItem => item.Note)
    </td>

    <td>
        @Html.DisplayFor(modelItem => item.Comment)
    </td>

    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.CountyID }) 
        @Html.ActionLink("Details", "Details", new { id=item.CountyID }) 
        @Html.ActionLink("Delete", "Delete", new { id=item.CountyID })
    </td>

</tr>
}

</table>

Model Clients

 [Table("Clients")]
public class Clients
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]

    public int ClientID { get; set; }

    public string Client { get; set; }
    public string Address { get; set; }
    public string State { get; set; }
    public string City { get; set; }
    public string County { get; set; }
    public int Zip { get; set; }
    public string Phone { get; set; }
    public string LogoLocation { get; set; }
    public string ContactName { get; set; }
    public string ContactPhone { get; set; }
    public string ContactEmail { get; set; }
    public int Authorized { get; set; }

    public string Note { get; set; }
    public string Comment { get; set; }

    public virtual ICollection<Countys> Countys { get; set; }

}

Model Countys

 [Table("Countys")]
public class Countys
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]

    public int CountyID { get; set; }
    public int ClientID { get; set; }

    public string County { get; set; }
    public string Note { get; set; }
    public string Comment { get; set; }

    public virtual ICollection<TownShips> Townships { get; set; }

}

Countys controller

public ActionResult Index(int id)
{
var cnty = from r in db.Clients
where r.ClientID == id
select r;
if (cnty != null)
{
return View(cnty); // View returns an error here
}
return HttpNotFound();

View is returning an error but i cannot step into it ... to find out what it is ... ideas?

2条回答
放我归山
2楼-- · 2019-03-01 18:16

You should be, for extensibility reasons, creating ViewModels that are not part of your domain model and passing those into just about all your view.

View Model:

public class IndexViewModel
{
  public int ClientID { get; set; }
  public IEnumerable<Clients> Clients { get; set; }
}

View(.cshtml):

@model OilNGasWeb.Models.Home.IndexViewModel

@{
  ViewBag.Title = "Index";
}


<h2>County's for </h2> 

<p>
  // send a ClientID with this action link
  @Html.ActionLink("Create New", "Create", new { clientid = Model.ClientID } ) 
</p>

//... etc

I'd also recommend to actually spell out your variables. It all gets compiled down, so it's typically better to write maintainable code over short handing variables.

Controller

public ActionResult Index(int id)
{
  //Lambda (just for an example, there is nothing wrong with LINQ expressions)
  var client = db.Clients
    .FirstOrDefault(c => c.ClientID == id);

  if (client != null)
  {
    var model = new IndexViewModel();
    model.ClientID = id;
    model.Clients = // some value I don't understand

    // My preference/opinion (programming religion) is to prefix with this
    // so others know if the method is *this* class, *base* class etc
    return this.View(model); 
  }

  return HttpNotFound();
}
查看更多
乱世女痞
3楼-- · 2019-03-01 18:21

From the looks of it, the data needed by the view is on a different level than what's being passed. You're currently sending an IEnumerable<Countys> to the view. But, as you ask, what happens when the enumeration is empty? Where can the view get the other pieces of data that it needs? (In this case the ClientID.)

What the view actually needs is a Clients. Because it's looking for a piece of Clients-level data, namely the ClientID. Sure, that data also exists on Countys objects, but that's immaterial to the conceptual nature of the data itself. The view in this case is showing information about a Clients object. Specifically:

int ClientID
IEnumerable<Countys> Countys

If the latter of those two isn't empty then the former can be discerned directly from that data. It might also be discerned from entirely different and unrelated data as well. But the point is that the view is conceptually acting on a Clients level, not on an IEnumerable<Countys> level.

So you'd change the view accordingly, and pass it the object that it needs:

public ActionResult Index(int id)
{
    var client = (from r in db.Clients
                 where r.ClientID == id
                 select r).SingleOrDefault();

    if (client != null)
        return View(client);

    return HttpNotFound();
}
查看更多
登录 后发表回答