2

OK、ここ、Google、その他のプログラミング サイトを検索して検索した後、最初の質問をする時が来ました。

2 つのモデルが必要なビュー Index.cshtml があるので、ViewModel の ImageViewModel.cs、2 つの子モデルの ImageModel.cs と ProductModel.cs、およびコントローラーの ImageController.cs を作成しました。

私の人生では、IEnumerable を機能させることができません。データのセットを取得する必要があります。一方には 1 つのアイテム (製品) があり、もう一方には多くの (画像) があります。画像は productID に関連付けられています。

遊んだ後、ビューで @Html.DisplayFor(modelItem => item.imageTitle) が imageTitle が存在しないというエラーをスローするようになりました。

全体に散らばっている多数の IEnumerable アイテムのいずれかを元に戻すと、渡された ImageViewModel が IEnumerable ではなく、ビューがそれを期待していることがわかります。

それが何であるかについては、ここに完全なコードリストがあります:

インデックス.cshtml

@model IEnumerable<JustAdminIt.Areas.JBI.ViewModels.ImageViewModel>

@{
ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
    <th>
        Image Title
    </th>
    <th>
        Image Excerpt
    </th>
    <th>
        Image Description
    </th>
    <th>
        Image 
    </th>
    <th>
       Product ID
    </th>
    <th></th>
</tr>
@foreach (var item in Model) {

<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Image.imageTitle)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Image.imageExcerpt)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Image.imageDescription)
    </td>
    <td>
        <img src="@Url.Content("~/Content/images/product/")@Html.DisplayFor(modelItem => item.Image.imageURL)" alt="Product Image" width="150" />
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Product.productID)
    </td>

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

</table>

ProductModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Web.Mvc;

namespace JustAdminIt.Areas.JBI.Models
{
public class Product
{
    [Key]
    public int productID { get; set; }

    [Required]
    [DisplayName("Product Name")]
    public string productName { get; set; }

    [Required]
    [AllowHtml]
    [DisplayName("Product Excerpt")]
    public string productExcerpt { get; set; }

    [Required]
    [AllowHtml]
    [DisplayName("Product Description")]
    public string productDescription { get; set; }

    [DisplayName("Mark As Active")]
    public bool productActive { get; set; }

    [DisplayName("Product Add Date")]
    public DateTime? productAddDate { get; set; }

    [DisplayName("Product Inactive Date")]
    public DateTime? productInactiveDate { get; set; }

}
}

ImageModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Web.Mvc;

namespace JustAdminIt.Areas.JBI.Models
{
public class Image
{
    [Key]
    public int imageID { get; set; }

    [Required]
    public string imageTitle { get; set; }

    [AllowHtml]
    public string imageExcerpt { get; set; }

    [AllowHtml]
    public string imageDescription { get; set; }

    [AllowHtml]
    public string imageURL { get; set; }

    [Required]
    public int productID { get; set; }
}
}

ImageController.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using JustAdminIt.Areas.JBI.Models;
using JustAdminIt.Areas.JBI.ViewModels;
using JustAdminIt.Areas.JBI.DAL;
using System.IO;

namespace JustAdminIt.Areas.JBI.Controllers
{ 
public class ImageController : Controller
{
    private ImageContext db = new ImageContext();
    private ProductContext pb = new ProductContext();

    //
    // GET: /JBI/Image/

    public ViewResult Index()
    {
        //attempt new things
        int id = 1;
        IEnumerable<Image> image = db.Image.TakeWhile(x => x.productID == id);
        IEnumerable<Product> product = pb.Product.TakeWhile(x => x.productID == id);

        ImageViewModel piViewModel = new ImageViewModel(image, product);
        return View(piViewModel);
        //return View(db.Image.ToList());
    }

    //
    // GET: /JBI/Image/Details/5

    public ViewResult Details(int id)
    {
        Image image = db.Image.Find(id);
        return View(image);
    }

    //
    // GET: /JBI/Image/Create

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

    //
    // POST: /JBI/Image/Create
    //this simply populates the DB values, but does not handle the file upload

    [HttpPost]
    public ActionResult Create(Image image)
    {
        if (ModelState.IsValid)
        {
            db.Image.Add(image);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }

        return View(image);
    }

    [HttpPost]
    public ActionResult UploadFile(HttpPostedFileBase Filedata)
    {
        // Verify that the user selected a file
        if (Filedata != null && Filedata.ContentLength > 0)
        {
            // extract only the fielname
            var fileName = Path.GetFileName(Filedata.FileName);
            // store the file inside ~/App_Data/uploads folder
            var path = Path.Combine(Server.MapPath("~/Content/images/product/"), fileName);
            Filedata.SaveAs(path);
        }
        // redirect back to the index action to show the form once again
        return RedirectToAction("Index");
    }

    //
    // GET: /JBI/Image/Edit/5

    public ActionResult Edit(int id)
    {
        Image image = db.Image.Find(id);
        return View(image);
    }

    //
    // POST: /JBI/Image/Edit/5

    [HttpPost]
    public ActionResult Edit(Image image)
    {
        if (ModelState.IsValid)
        {
            db.Entry(image).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(image);
    }

    //
    // GET: /JBI/Image/Delete/5

    public ActionResult Delete(int id)
    {
        Image image = db.Image.Find(id);
        return View(image);
    }

    //
    // POST: /JBI/Image/Delete/5

    [HttpPost, ActionName("Delete")]
    public ActionResult DeleteConfirmed(int id)
    {            
        Image image = db.Image.Find(id);
        db.Image.Remove(image);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        db.Dispose();
        base.Dispose(disposing);
    }
}
}

ImageViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Web.Mvc;
using JustAdminIt.Areas.JBI.Models;

namespace JustAdminIt.Areas.JBI.ViewModels
{
public class ImageViewModel
{
    public IEnumerable<ImageViewModel> Image { get; set; }
    public IEnumerable<ImageViewModel> Product { get; set; }

    public ImageViewModel(IEnumerable<Image> image, IEnumerable<Product> product)
    {
        IEnumerable<Image> Image = image;
        IEnumerable<Product> Product = product;
    }
}
}
4

3 に答える 3

1

Index アクション メソッドでは、単一の new を作成ImageViewModel()してビューに渡しますが、ビューはIEnumerable<ImageViewModel>.

あなたがやっていることは、単一の ImageViewModel を作成し、2 つのコレクションをそれに渡すことです。これは、2 つの異なるアイテムの 1 つをそれぞれ保持する複数のボックスを使用するのではなく、1 つのボックスを使用して 2 つのグループのアイテムを保持するようなものです。

適切な方法でアイテムを生成するには、アプリを再設計する必要があります。ここに 2 つの異なるデータ コンテキストがある理由はわかりませんが、それによって事態は非常に複雑になります。

于 2012-07-30T00:33:37.500 に答える
1

したがって、@Mystere Manと@Travis JIの助けを借りて、文脈から外れたコード「スニペット」を含む多数のリソースを読んだ後、解決策があります。

まず、すべてのモデルに対して新しい DbContext を作成していました。私は知っている、ばか。したがって、これらはすべて独自のコンテキスト ファイルにラップされており、私の web.config は非常に満足しています。

1 つのコンテキストで複数のソースを示すサンプル DbContext:

public class MyDataContext : DbContext
{
    public DbSet<Bundle> Bundle { get; set; }
    public DbSet<Image> Image { get; set; }
    public DbSet<Product> Product { get; set; }
    public DbSet<Siteconfig> Siteconfig { get; set; }
}

更新されたファイル(変更されたファイルのみを投稿します。ここにリストされていない場合は、元の質問と同じです):

ImageViewModel.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Web.Mvc;
using JustAdminIt.Areas.JBI.Models;

namespace JustAdminIt.Areas.JBI.ViewModels
{
    public class ImageViewModel
    {
        public Image Image { get; set; }
        public Product Product { get; set; }
    }
}

ImageController.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using JustAdminIt.Areas.JBI.Models;
using JustAdminIt.Areas.JBI.ViewModels;
using JustAdminIt.Areas.JBI.DAL;
using System.IO;

namespace JustAdminIt.Areas.JBI.Controllers
{ 
public class ImageController : Controller
{
    //private ImageContext db = new ImageContext();
    //private ProductContext pb = new ProductContext();

    private JustBundleItContext db = new JustBundleItContext();

    //
    // GET: /JBI/Image/

    public ViewResult Index()
    {
        var model = from a in db.Product
                    join b in db.Image
                    on a.productID equals b.productID
                    select new ImageViewModel
                    {
                        Product = a,
                        Image = b
                    };
        return View(model.ToList());

    }

    //
    // GET: /JBI/Image/Details/5

    public ViewResult Details(int id)
    {
        Image image = db.Image.Find(id);
        return View(image);
    }

    //
    // GET: /JBI/Image/Create

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

    //
    // POST: /JBI/Image/Create
    //this simply populates the DB values, but does not handle the file upload

    [HttpPost]
    public ActionResult Create(Image image)
    {
        if (ModelState.IsValid)
        {
            db.Image.Add(image);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }

        return View(image);
    }

    [HttpPost]
    public ActionResult UploadFile(HttpPostedFileBase Filedata)
    {
        // Verify that the user selected a file
        if (Filedata != null && Filedata.ContentLength > 0)
        {
            // extract only the fielname
            var fileName = Path.GetFileName(Filedata.FileName);
            // store the file inside ~/App_Data/uploads folder
            var path = Path.Combine(Server.MapPath("~/Content/images/product/"), fileName);
            Filedata.SaveAs(path);
        }
        // redirect back to the index action to show the form once again
        return RedirectToAction("Index");
    }

    //
    // GET: /JBI/Image/Edit/5

    public ActionResult Edit(int id)
    {
        Image image = db.Image.Find(id);
        return View(image);
    }

    //
    // POST: /JBI/Image/Edit/5

    [HttpPost]
    public ActionResult Edit(Image image)
    {
        if (ModelState.IsValid)
        {
            db.Entry(image).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(image);
    }

    //
    // GET: /JBI/Image/Delete/5

    public ActionResult Delete(int id)
    {
        Image image = db.Image.Find(id);
        return View(image);
    }

    //
    // POST: /JBI/Image/Delete/5

    [HttpPost, ActionName("Delete")]
    public ActionResult DeleteConfirmed(int id)
    {            
        Image image = db.Image.Find(id);
        db.Image.Remove(image);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        db.Dispose();
        base.Dispose(disposing);
    }
}
}

インデックス.cshtml

@model List<JustAdminIt.Areas.JBI.ViewModels.ImageViewModel>

@{
ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
    <th>
        Image Title
    </th>
    <th>
        Image Excerpt
    </th>
    <th>
        Image Description
    </th>
    <th>
        Image 
    </th>
    <th>
       Product ID
    </th>
    <th></th>
</tr>

@foreach (var item in Model) {

<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Image.imageTitle)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Image.imageExcerpt)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Image.imageDescription)
    </td>
    <td>
        <img src="@Url.Content("~/Content/images/product/")@Html.DisplayFor(modelItem => item.Image.imageURL)" alt="Product Image" width="150" />
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Product.productName)
    </td>

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

</table>

コントローラーで LINQ クエリを使用すると、ViewModel を大幅に簡素化しながら、画像が関連付けられている製品を見つけるために必要な結合を行うことができました。ビューで item.Image グループまたは item.Products グループから選択できるようになり、それらが適切に結合されていることがわかりました。

于 2012-07-30T03:13:04.843 に答える
0

この問題は、 の使用が原因である可能性がありますTakeWhile

「指定された条件が真である限り、シーケンスから要素を返し、残りの要素をスキップします。」- http://msdn.microsoft.com/en-us/library/system.linq.enumerable.takewhile.aspx

そこで使用することもできますWhere( https://stackoverflow.com/a/5031771/1026459 )

db.Image.Where(x => x.productID == id).ToList();
pb.Product.Where(x => x.productID == id).ToList();

それはほんの一部です。これら 2 つの IEnumerable セットを含むクラスを渡しています。ただし、ビューはそのクラスの IEnumerable を受け入れています。あなたは適切に受け渡していますが、適切に受け取っていません。

@model JustAdminIt.Areas.JBI.ViewModels.ImageViewModel

ただし、ここで別の問題があります。渡されたときに製品と画像は関連していないため、両方で同時に foreach を使用することはできません

@foreach (var item in Model) {

になり得る

@foreach (var item in Model.Product) {

しかし、ここに挙げた理由により、これは多くの画像があることを意味するわけではありません。この関係を作成するには、少しリファクタリングする必要があります。それを達成する方法はあなた次第です。基本的に、モデルに仮想関係を作成するか、両方をラップするクラスを使用する必要があります。

于 2012-07-30T00:39:59.173 に答える