ASP.NET MVC 5:在Controller中持久存储变量 [英] ASP.NET MVC 5 : persisting variables in Controller

查看:95
本文介绍了ASP.NET MVC 5:在Controller中持久存储变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在视图的GET请求中实例化"plate"对象,然后在发布表单时访问它.平板对象将填充来自表单的数据.我还可以使用它来存储传递的坐标吗?还是做我想达到的目的的惯用方式是什么?

I instantiate the 'plate' object in the GET request of the view and then access it when the form is posted. The plate object is populated with the data from the form. Can I also use it to store the passed coordinates? Or what is the idiomatic way of doing what I'm trying to achieve?

谢谢!

public class DrawingController : Controller
{

        Plate plate;

        [HttpGet]
        public ActionResult Index()
        {   
            plate = new Plate()
            {
              Holes = new Holes()
            }
            return View(plate);
        }

        // called by ajax when user clicks on "Save" to save the input coordinates
        [HttpPost]
        public void PassCoordinates(string coordinates)
        {
          // why is plate null here?
          plate.Holes.coordinates = coordinates;
        }

        [HttpPost]
        public ActionResult Index(Plate plate)
        {
         // I want to access plate.Holes.coordinates that I set in 'PassCoordinates'
         // how can I achieve this?
        }
}

推荐答案

您看到的是预期的行为,因为 Http是无状态的.

What you see is the expected behavior, because Http is stateless.

每次调用操作方法时,都会创建一个控制器的新对象.因此,在您进行ajax调用的情况下,它将创建 DrawingController 的新对象,并且该对象将具有 Plate 类型的属性,但不会初始化为 Plate 对象.(您在 Index 方法调用中执行的)

Every time you make a call to your action method, a new object of the controller will be created. So in your case when you make the ajax call, it will create a new object of the DrawingController and this object will have a property of type Plate, but is not initialized to a Plate object. (which you do in your Index method call)

如果要获得相同的板实例,则可以在您的 PassCoordinates 操作方法中以不同的方式进行

If you want to get the same plate instance, in your PassCoordinates action method you can do in different ways

  1. 将您的ajax调用发布到Plate结构的js对象中,并在您的 Plate 类型的操作方法中添加一个参数.提交请求后,模型绑定器将能够构建新对象并映射不同属性的值

  1. Have your ajax call post the js object of Plate structure and have a parameter in your action method of Plate type. when the request is submitted, the model binder will be able to build the new object and map the values of different proeprties

将Plate对象存储在持久的介质中并读取它.因此,在您的Index操作方法中,您将创建对象,初始化属性值并将其存储到db表/Session状态等.您可以在第二个操作方法中从该位置再次读取它.使用静态变量是另一种选择

Store the Plate object in a persistent meedium and read it. So in your Index action method, you will create the object, intialize the proprety values and store it to a db table/Session state etc. You can read it again from this place in your second action method. Using a Static variable is another option

如果要使用选项#2并选择使用Session/Static变量,请记住,您正在尝试将有状态行为添加到无状态http.:(

If you are going for the option #2 and choose to use Session/Static variable, keep in mind that you are trying to add stateful behavior to the stateless http. :(

恕我直言,方法1是可行的方法.保持Http的无状态行为.让您的客户代码(进行ajax调用的代码)发送代表板对象的JS对象,并让模型联编程序为您构建该对象.

IMHO, Option 1 is the way to go. Keep the stateless behavior of Http. Have your client code (the code which makes the ajax call) send the JS object representing the plate object and have the model binder build the object for you.

当我查看您的代码时, PassCoordinates 方法唯一要做的就是简单地设置Plate对象的 Holes.coordinates 属性值(尽管将在控制器中可用).您可以完全删除该方法,并确保在表单的输入元素中这样做,以便在将表单提交给HttpPost索引操作方法时,该表单将在请求正文中可用,并且模型绑定器会将其映射到您的平板参数.

When i am looking at your code, the only thing PassCoordinates method is doing is, simply setting the Holes.coordinates property value of the Plate object (which you though will be available in the controller). You can totally remove that method and make sure that you do that in the input elements in your form so that when you submit the form to the HttpPost index action method, it will be available in the request body and model binder will map it to your Plate parameter.

@model Plate
@using (Html.BeginForm("Index", "Home"))
{      
     @Html.TextBoxFor(a=>a.Holes.coordinates)       
    <button type="submit" class="btn" >Save</button>    
}

这将在表单内创建一个名称为 Holes.coordinates 的输入元素.

This will create an input element with name Holes.coordinates inside the form.

<input id="Holes_coordinates" name="Holes.coordinates" type="text" value="">

输入一些值并提交表单.现在,如果您在HttpPost操作方法中设置了一个断点,您将看到您的平板对象的孔属性已填充,并且您可以访问在 coordinates 属性的文本框中输入的值.

Enter some value to it and submit the form. Now if you put a breakpoint in the HttpPost action method, you can see that your plate objects Hole proprety is populated and you can access the value you entered in the text box in the coordinates property.

现在您所要做的就是,无论客户端代码进行了ajax调用,而不是进行ajax调用,都要设置此输入的值.

Now all you have to do is, whatever client side code was making the ajax call, instead of making the ajax call, set the value of this input.

$("#Holes_coordinates").val("some value you want");

一切正常后,您只需将调用切换到 HiddenFor 助手即可将可见的文本框转换为隐藏的输入.

Once everything is working, you can convert the visible text box to a hidden input by simply switching the call to HiddenFor helper.

@Html.HiddenFor(a=>a.Holes.coordinates)

这篇关于ASP.NET MVC 5:在Controller中持久存储变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆