【问题标题】:variable set null after method方法后变量设置为空
【发布时间】:2017-04-12 18:19:59
【问题描述】:

我正在构建一个网站,我需要显示一个客户列表。 When a customer is selected, to show his items, I send the id of the customer from the view with this:

 <th>
 @using (Html.BeginForm("SetID", "Client", FormMethod.Post, new 
{ id = item.id.ToString() }))
   {
    @Html.Hidden("id", item.id.ToString());
    <input type="submit" value="see items" />
   }
   </th>

我在控制器中收到 id 并将其保存以进行查询并以这种方式显示值。

private string customer_id
[HttpPost]
public ActionResult SetCustomer(string id) {
    Save(id);
    return RedirectToAction("Index");
}

private void Save(string id) {
    this.customer_id = id;
}

但是当我被重定向到索引视图时,变量“customer_id”为空。我有什么遗漏吗?

【问题讨论】:

    标签: c# asp.net-mvc-4 http-post


    【解决方案1】:

    因为您没有在任何地方保留该值。

    HTTP 是无状态的。这在 ASP.NET 中意味着每个 HTTP 请求都会导致请求控制器的 新实例。因此,这里发生了以下一系列事件:

    1. 用户向SetCustomer 发出请求,创建该类的新实例
    2. 值存储在类级变量中
    3. 请求响应完成,类的实例被销毁
    4. 用户向Index 发出请求,创建该类的新实例

    因为它是一个新实例,所以没有设置任何值。您可以在很多地方存储数据,它只需要在两个请求都可以访问的上下文中。示例(不分先后)包括:

    1. 数据库
    2. 会话
    3. 网址查询字符串
    4. 饼干

    基本上,您必须将值写入在请求之间持续存在的某个位置。内存中的变量在 Web 应用程序中不会这样做。


    这里的一个简单示例是在重定向中包含查询字符串的值。在 ASP.NET MVC 中,可能看起来像这样:

    return RedirectToAction("Index", new { customer_id = id });
    

    这会在用户被重定向时在 URL 参数中包含 customer_id 值。因此,您的 Index 操作可以接受该参数:

    ActionResult Index(int? customer_id = null)
    {
        // use the customer id if one is provided
    }
    

    在这种情况下,我假设该值应该可以为空,以防Index 被请求。但是你喜欢做什么取决于你。基本上,此操作现在有一个可选参数,您可以使用它,但您当前正在尝试使用它。

    这样做的好处是它保持了 Web 应用程序的预期无状态。您将状态(customer_id 值)存储在请求/响应本身中,而不是您负责维护它的其他介质(会话、数据库等)。

    【讨论】:

    • 谢谢,我没看到,我尝试使用 Session["customer_id"] 来解决问题:D,非常感谢这个菜鸟的帮助哈哈。 :)
    • @Jose_av28:使用会话状态可以解决问题,至少在这个有限的范围内。但它为 Web 应用程序引入了状态性,除非绝对必要,否则应避免这种情况。一个陷阱的例子是,如果您将应用程序托管在一个自动扩展的云解决方案中,您无法控制 Web 服务器的排列/配置方式。存储会话的网络服务器可能不是试图检索它的网络服务器。向用户提供值会将其附加到请求本身,因此任何服务器都可以处理请求。
    • 好吧,我只是需要从管理员帐户进行一些查询,然后将其删除,所以我不知道如何实现这个主题:S.
    【解决方案2】:

    ASP.NET MVC 控制器被实例化以服务每个请求。您的本地变量 this.customer_id 不应该在对服务器的调用中继续存在。如果你想保存一些东西,它应该放在一个数据库表、一个文件或某个持久化的地方。

    您也可以像缓存一样将其存储在内存中,但这需要引用比控制器寿命更长的东西(在服务器响应浏览器后将被丢弃)。

    如果您希望像我描述的那样长期存在,您可能需要使用服务注入到您的控制器中。许多人会使用 DI 或 IOC 框架和生命周期配置来完成此任务。

    【讨论】:

    • 谢谢,你在哪里对,我使用会话变量,所以可以随时访问:D.
    猜你喜欢
    • 1970-01-01
    • 2018-03-16
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    相关资源
    最近更新 更多