通过一个操作在两个模型上执行创建操作

时间:2011-11-29 12:33:19

标签: asp.net-mvc-3 razor upload entity-framework-4.1 scaffolding

我有两种模式:类别图片,它们分别指两个表,类别和图片。 Category模型具有Picture模型的导航属性。

现在,我使用Scaffolding功能创建了一个控制器,并为Category提供了CRUD操作。以下是代码: -

public ActionResult Create()
{
    ViewBag.ParentCategoryId = new SelectList(db.Categories, "Id", "Name");
    ViewBag.PictureId = new SelectList(db.Pictures, "Id", "PictureUrl");
    return View();
}

自动生成的控制器操作使用SelectList列出数据库中的可用图片条目,并将其传递到下拉列表以供选择。这不是理想的情况,因为我想要的是无法用户上传图片,然后将引用添加到类别模型。之后,条目将保存到“类别和图片”表中。

3 个答案:

答案 0 :(得分:5)

像这样创建模型:

public class FullCategoryModel
{
    public HttpPostedFileBase Picture { get; set; }
    public Category CategoryModel {get; set;}
}

在视图中:

@using (Html.BeginForm("Create", "Category", FormMethod.Post, 
    new { enctype = "multipart/form-data" }))
{  
  @Html.TextBoxFor(model => model.Category.Name)      // example, put there all category details 
  <input type="file" name="Picture" id="Picture" />      
  <input type="submit" value="Upload" />    

}

然后创建动作:

[ActionName("Create")]
[HttpPost]
public ActionResult Create(FullCategoryModel model)
{
// here you can get image in bytes and save it in db, 
// also all category detail are avalliable here

MemoryStream ms = new MemoryStream();
model.Picture.InputStream.CopyTo(ms);
Image picture = System.Drawing.Image.FromStream(ms);

// save in db as separate objects, than redirect
return RedirectToAction("Index", "Category");
}

答案 1 :(得分:2)

首先,我要感谢@NickLarsen让我相信我的理解是好的,我可以自己完成任务。

问题不是太难,但由于我是Asp.net MVC的新手,事情有点莫名其妙。从一开始,我就认为我需要ViewModel合并Category和Price类,然后是图片上传API。但是,不知何故,我无法将这些碎片放在正确的位置。因此,经过对互联网的各种回归和研究,我以下列方式完成了任务: -

  • 首先,我创建了一个ViewModel

    public class CatPicView
    {
        public Category Category { get; set; }
        public Picture Picture { get; set; }
    }
    
  • 其次,我添加了Uploadify javascript API

    <script type="text/javascript">
        $('#file_upload').uploadify({
            'uploader': '@Url.Content("~/uploadify/uploadify.swf")',
            'script': '@Url.Action("Upload", "Category")',
            'cancelImg': '@Url.Content("~/uploadify/cancel.png")',
            'buttonText': 'Upload',
            'folder': '@Url.Content("~/content/images")',
            'fileDesc': 'Image Files',
            'fileExt': '*.jpg;*.jpeg;*.gif;*.png',
            'auto': true,
            'onComplete': function (event, ID, fileObj, response, data) {
                    var json = jQuery.parseJSON(response);
                    $("#pictureImage").html("<img src='"+json+"' alt='"+json+"' height='100px' width='100px'/>");
                    $("#Picture_PictureUrl").val(json);
                    $("#pictureRemove").show();
                }
            });
    </script>
    
  • 将API挂钩到以下服务器功能以重命名并保存到文件夹

    [HttpPost]
    public ActionResult Upload(HttpPostedFileBase fileData)
    {
        if (fileData != null && fileData.ContentLength > 0)
        {
            //var fileName = Server.MapPath("~/Content/Images/" + Path.GetFileName(fileData.FileName));
            int pictureCount = 800000;
            pictureCount += db.Pictures.Count();
            string extension = Path.GetExtension(fileData.FileName);
            string renamedImage = Server.MapPath("~/Content/Images/Categories/cat" + pictureCount + extension);
            fileData.SaveAs(renamedImage);
            return Json("/Content/Images/Categories/" + Path.GetFileName(renamedImage));
        }
        return Json(false);
    }
    
  • 最后,为了保存对DB的更改

    [HttpPost] public ActionResult Create(CatPicView catPic) { if (ModelState.IsValid) { if (!String.IsNullOrEmpty(catPic.Picture.PictureUrl)) { Picture picture = new Picture(); picture.PictureUrl = catPic.Picture.PictureUrl; db.Pictures.Add(picture); catPic.Category.PictureId = picture.Id; } db.Categories.Add(catPic.Category); db.SaveChanges(); return RedirectToAction("Index"); } return View(); }

答案 2 :(得分:0)

我认为MVC脚手架功能将两种模型的关系视为“多对多”。这就是为什么它为你创建了两个下拉列表。根据您的场景,您可以在没有“图片”模型数据的情况下创建“类别”创建页面,因为“图片”是此处的主要实体。所以在图片中创建动作。

[HttpPost]
    public ActionResult Create(Picture picture)
    {
        if (ModelState.IsValid)
        {
            databaseContext.Pictures.Add(picture);
            databaseContext.SaveChanges();
            return RedirectToAction("Index");  
        }

        return View(picture);
    }

在创建图片的视图页面

@model YourProjectName.Models.Picture
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
    <legend>Picture</legend>
    <div class="editor-label">
        @Html.LabelFor(model => model.Url)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Url)
        @Html.ValidationMessageFor(model => model.Url)
    </div>
    <div class="editor-label">
        @Html.LabelFor(model => model.Categories.CategoryID, "Category")
    </div>
    <div class="editor-field">
        @Html.DropDownList("CategoryID", "Choose Category")
        @Html.ValidationMessageFor(model => model.Categories.CategoryID)
    </div>
    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>
}