代码之家  ›  专栏  ›  技术社区  ›  kolin

将图像映射到asp中的页面。净mvc

  •  2
  • kolin  · 技术社区  · 10 年前

    问题 我需要在另一个模型的编辑视图中映射一个模型。我有一个图像,在它的编辑视图中有两个选项卡(图像编辑选项卡和映射页面选项卡)。 “编辑视图”选项卡按预期工作。并且“映射的页面”选项卡正确列出了映射到图像的所有页面。 我想做的是在“映射页面”选项卡中有一个表单,我可以在其中选择一个页面来映射此图像。我尝试将整个编辑视图包含在表单中,并基于提交值执行ActionResult(没有成功),我尝试将表单创建为部分视图,但也没有成功。我宁愿尝试做最好的练习,而不是去做。我读过编辑器模板,但我不确定它们是我需要的。

    我有以下三种模型(缩小了此问题的范围):

    页

    public class PageContent
    {
        public int PageId {get;set;}
        public string PageTitle {get;set;}
        public string PageContent {get;set;}
    
        public virtual ICollection<PageImageXmap> PageImages {get;set;}
    }
    

    形象

    public class SiteImage
    {
        public int ImageId {get;set;}
        public string ImageTitle {get;set;}
        public string ImageFilename {get;set;}
    
        public virtual ICollection<PageImageXmap> ImagePages {get;set;}
    }
    

    XML映射

    public class PageImageXmap
    {
        [Key, Column(Order = 0)]
        public int PageId {get;set;}
        [Key, Column(Order = 1)]
        public int ImageId {get;set;}
    
        public virtual PageContent PageContents {get;set;}
        public virtual SiteImages SiteImages {get;set;}
    }
    

    使我获得最大成功的控制器方法(它实际上向Xmap表/模型添加了PageId和ImageId,但在尝试重新加载页面时失败了)的开头是 已更新 :

    public ActionResult Edit(Int? id)
    {
        /*get image from DB*/
        ViewBag.Pages = new SelectList(db.PageContents, "PageId", "PageTitle")
        return View(siteImage);
    }
    
    public ActionResult Edit(SiteImage siteImage, string AddXMap, string Save, string PageId)
    {
        if(!String.IsNullOrEmpty(AddXMap) // If the map submit button is click
        {
            /* adds the xmap model to the database */
            ViewBag.Pages = new SelectList(db.PageContents, "PageId", "PageTitle")
            return View(siteImage);
        }
        else
        {
            /* saves the existing siteImage */
            return View(siteImage);
        }
    }
    

    虽然当我列出这个图像映射到的页面时,返回实际的-编辑视图时,这就失败了(500:对象引用没有设置为PageTitle上的对象实例)。如果我硬重新加载页面,它就可以正常工作。 在发生错误的地方更新

    @model MyCode.DAL.SiteImage
    
    /* Razor code for editing the image details */
    
    @foreach(var item in Model.ImagePagesXMap) // <--- Object reference not set to an instance of an object on return View
    {
        <tr>
            <td>@item.PageContents.PageTitle</td>
        </tr>
    }
    @Html.DropDownList("PageId", (IEnumerable<SelectListItem>)Viewbag.Pages)
    <input type="submit" name="AddXMap" id="AddXMap" value="Map current image to page" />
    

    更新#1 显示更多控制器/剃须刀代码以及出现500的位置

    更新#2 如果我添加 siteImage = db.SiteImages.Find(siteImage.ImageId); 在我之前 return view(siteImage); 然后我得到一个 object reference not set 在…上 @item.PageContents.PageTitle 与Model.ImagePagesXMap相对。我之所以尝试这样做,是因为这是第一次加载编辑视图时正确工作的代码。由于没有图像数据被编辑,我想这只会重新加载siteImage对象,但没有。

    问题 我是不是遗漏了一些显而易见的东西,有没有更好的方法?我已经做了很多搜索,但我找不到任何人尝试类似的东西,这让我觉得我正在接近这个错误。(我有点MVC n00b)

    1 回复  |  直到 10 年前
        1
  •  0
  •   kolin    10 年前

    所以我实际上自己设法解决了这个问题。这似乎不是正确的方法,但目前已经足够了。

    在我的剃须刀看来,我最终得到了:

    <h2>Image on pages</h2>
            <input id="PageIdToRemove" name="PageIdToRemove" value="0" type="hidden" />
            <input id="RemoveXMap" name="RemoveXMap" value="" type="hidden" />
            <table class="table table-striped">
                <tr>
                    <th>Page title</th>
                    <th>Image order</th>
                    <th>Actions</th>
                </tr>
                @foreach (var item in Model.ImagePagesXMap) {
                <tr>
    
                    <td>@item.PageContents.PageTitle</td>
                    <td>@item.ImageOrder</td>
                    <td><button class="btn  btn-danger  js-button-removexmap" data-buttonvalue="@item.PageContents.PageId">
                                    <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
                                    Remove image from page</button></td>
                </tr>
                }
            </table>
            <h2>Add this image to another page</h2>
            <div class="form-group">
                <label for="PageId">Page</label>
                @Html.DropDownList("PageId", (IEnumerable<SelectListItem>)ViewBag.Pages, String.Empty, new { @class="form-control"})
            </div>
            <div class="form-group">
                <label for="ImageOrder">Order on page</label>
                <input type="number" id="ImageOrder" name="ImageOrder" class="form-control" />
            </div>
            <hr />
            <p><input type="submit" name="AddXMap" id="AddXMap" value="Add to page" class="btn btn-success" /> | @Html.ActionLink("Cancel", "Index", null, new { @class = "btn btn-default" })</p>
    <script type="text/javascript">
    $(function () {
                $('.js-button-removexmap').click(function () {
                    $('#PageIdToRemove').val($(this).data('buttonvalue'));
                    $('#RemoveXMap').val('1');
                    $('form').submit();
                });
    });
    </script>
    

    这里的大部分代码实际上是删除交叉映射的图像。 在这种情况下,它设置的值为 #PageIdToRemove 是在按钮元素的数据部分指定的项id,也是RemoveXMap的值。

    在控制器中,我有:

    [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Edit(SiteImage siteimage, string AddXMap, string Save, int ImageOrder, int PageId, string RemoveXMap, int PageIdToRemove)
            {
    
    
                if (!String.IsNullOrEmpty(AddXMap))
                {
                    if (PageId > 0)
                    {
                        var xmapAdd = new MyLibrary.BLL.GetPageImageXMap();
                        xmapAdd.AddImageXMap(siteimage.ImageId, PageId, ImageOrder);
    
                        var imageQuery = new MyLibrary.BLL.GetImagesQuery();
                        siteimage = imageQuery.GetImage(siteimage.ImageId);
                    }
    
                }
    
                if (!String.IsNullOrEmpty(RemoveXMap))
                {
                    var xmapRemove = new MyLibrary.BLL.GetPageImageXMap();
                    xmapRemove.RemoveImageXMap(siteimage.ImageId, PageIdToRemove);
    
                    var imageQuery = new MyLibrary.BLL.GetImagesQuery();
                    siteimage = imageQuery.GetImage(siteimage.ImageId);
                }
    
                if (!String.IsNullOrEmpty(Save))
                {
                    if (ModelState.IsValid)
                    {
                        db.Entry(siteimage).State = EntityState.Modified;
                        db.SaveChanges();
                    }
                }
    
                ViewBag.Pages = new SelectList(db.PageContents, "PageId", "PageTitle");
    
                return View(siteimage);
            }
    

    我的想法是 siteimage 最初返回的内容与发布的内容来自相同的上下文,因此不需要刷新。所以这段代码:

    var imageQuery = new MyLibrary.BLL.GetImagesQuery();
    siteimage = imageQuery.GetImage(siteimage.ImageId);
    

    实际上,使用新保存的xmap数据重新加载siteimage。(因为我没有编辑站点图像,所以我只是使用它的imageid来添加或删除xmap)

    然后将此视图传递回视图。这是否是最好的方法(可能不是)是另一个问题。如果有人想建议其他解决方案,那也很酷。

    推荐文章