【问题标题】:Passing a global object back to view将全局对象传递回视图
【发布时间】:2017-01-16 19:49:57
【问题描述】:

我正在自学 asp.net C# MVC,但我并不真正了解如何将数据带回视图。

所有教程示例都很简单,即 1)创建模型(书) 2)在控制器中,您创建一个书籍对象(并复制到 ViewModel),即作者和标题以及章节的集合。 3) 在视图中引用视图模型对象,即@Model.Title 等。

但是在我的例子中,我有一个之前已经创建的对象,我想将它发送回视图。

例如。假设一个图书馆有一本在 controller1 中创建的书。 (这称为 book1,然后返回到视图。

我有另一个控制器 (controller2),它将在 book1 中添加一个新章节。

所以问题是:

a) 创建 book1 以便我可以在所有控制器中引用的最佳位置在哪里? b) 一旦 book1 对象被创建,它是如何返回到视图中的——从我的例子看来,只有在特定控制器中创建的对象才能返回到它们的关联视图中?

【问题讨论】:

    标签: c# asp.net-mvc asp.net-core


    【解决方案1】:

    实际上,您的控制器不应该缓存它创建的对象。如果您有 GET Edit 用例,让数据库存储对象并再次检索它。 您不想记住请求之间的状态(RESTful 架构)。 这意味着您必须将操作所需的所有数据作为参数发送。

    假设你有一个 BookController 有一个 CreateBook 动作。 此操作应返回数据库中创建的 Book 的 ID。 (或者它返回一个视图,其中用于编辑图书的 ActionLink 使用正确的 ID 进行了初始化)。 必须将此 ID 传递给编辑现有图书的所有操作。

    例如,在创建图书后显示的视图中:

    @Model ExistingBookViewModel
    
    @Html.ActionLink("Add chapter", "AddChapter", "Chapter", new { bookId = Model.Id })
    

    这里,ExistingBookViewModel.Id 是创建的书的 ID,并在 BookController 中设置。

    然后你的 ChapterController 可以像这样定义 AddChapter Action:

    [HttpGet]
    public ActionResult AddChapter(long bookId) {
        var book = dbContext.Books.Find(bookId);
        var viewModel = new AddChapterViewModel {
            BookId = bookId,
            BookName = book.Name,
            ChapterName = string.Empty // to be provided by User in AddChapter view
            // ...
        };
        return View("AddChapter", viewModel);
    }
    
    [HttpPost]
    public ActionResult AddChapter(AddChapterViewModel postData) {
        var book = dbContext.Books.Find(postData.BookId);
    
        var newChapter = new Chapter {
            Name = postData.ChapterName,
            // ...
        };
    
        book.Chapters.Add(newChapter);
        dbContext.SaveChanges();
        return new HttpStatusCodeResult(HttpStatusCode.OK);
    }
    

    【讨论】:

    • 我认为这是一个很好的答案。只有一个细节 - 您可以将更新的书籍模型返回给 View 而不是 HttpStatusCodeResult。
    • 感谢详细的回复!
    【解决方案2】:

    a) 我会将模型与任何控制器文件分开,并通过包含命名空间在需要它的任何控制器/视图中引用它。这将保持井井有条。

    b) 您可以使用Controller.View 方法将您想要的任何模型传递给视图,但视图应该定义该模型(例如 -@model MyApp.Models.MyModel)以便它使用它。从那里您可以使用将模型绑定到您的视图来显示数据。

    【讨论】:

      【解决方案3】:

      在任何类中创建静态变量,其他类都可以访问。

      但是为什么不再选择对象呢?性能不错,但简单且无错误的算法更为重要。

      如果要缓存数据库,可以考虑缓存sql语句的结果:

      string sql = "select ...";
      string hash = "book_" + sql.GetHashCode();
      Book b = null;
      if (HttpRuntime.Cache[hash] != null)
      {
           b = (Book)HttpRuntime.Cache[hash];
      }
      else
      {
           b = SelectBookFromSql(sql);
           HttpRuntime.Cache[hash] = b;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多