ASP.NET MVC: перенос значения со страницы на страницу - PullRequest
2 голосов
/ 18 августа 2010

tldr> Как только клиент выбран, как все остальные контроллеры могут выполнять свои действия всегда в «контексте» этого клиента, не передавая идентификатор вручную?

Я пытаюсь выяснить, что«правильный» способ - справиться с ситуацией, когда весь контроллер (или несколько) полностью зависит от идеи предыдущего контроллера.Например, скажем, вы строили какую-то систему управления клиентами.Там будут все виды функций клиента, вероятно, расположены на CustomerController.Но затем, когда вы попали в управление заказами, вы, вероятно, захотите иметь OrderController.

Если бы у вас был только один OrderController, ваши методы могли бы выглядеть так:id) {...}

Идентификатор будет идентификатором заказа, верно?Я немного теряюсь, когда мне нужно вернуться к клиенту.Это как «контекст» всех действий, которые происходят внутри клиента.Вы могли бы сделать это, всегда добавляя идентификатор клиента в действия (URL):

http://site.com/Orders/Edit/1234?customerId=abc

Но, похоже, становится довольно утомительно захватывать это значение и вставлять его в каждое действие,Есть варианты, такие как Session, но это кажется небрежным.

Какой правильный способ сделать это?

Ответы [ 4 ]

3 голосов
/ 18 августа 2010

Вы можете уменьшить общую небрежность сеанса, написав оболочку вокруг сеанса, которая предоставляет строго типизированные свойства.

//Sloppy weak typing:
int userId = (int)HttpContext.Current.Session["UserId"];

//Strongly typed goodness
int userId = SessionWrapper.UserId;
0 голосов
/ 18 августа 2010

Если вы действительно хотите избежать сохранения своего значения в сеансе, вы можете использовать фильтр действий, который заботится о значении. Я использовал этот подход один раз, и он выглядит так:

  1. Создайте новый маршрут, который содержит заполнитель для вашего значения, например, идентификатор клиента.
  2. Когда клиент выбран, добавьте идентификатор к маршруту для следующего вызова GET или POST.
  3. Создайте фильтр действий, который считывает идентификатор из маршрута и добавляет его к параметрам действия до того, как действие произойдет (OnActionExecuting). Когда действие выполнено, этот же фильтр добавляет идентификатор из параметров действия обратно в данные маршрута (OnActionExecuted).
  4. Используйте этот новый фильтр действий где угодно, возможно, на уровне контроллера.

Теперь ваш идентификатор клиента легко сохраняется в URL, даже если вы не добавляете его вручную ко всем ссылкам. Если вам нужно использовать идентификатор клиента в методе действия, вы просто добавляете параметр с правильным именем. Он сохраняется при вызове метода действия, даже если вы не берете его в качестве параметра.

Если вы хотите пойти дальше, в вашем новом фильтре действий вы можете получить данные из базы данных и добавить их к параметрам действия вместо добавления только идентификатора. Таким образом, вы можете еще больше упростить свои методы действий.

0 голосов
/ 18 августа 2010

Сериализация информации о сеансе в зашифрованный файл cookie сеанса является еще одним решением здесь.Преимущество заключается в возможности избежать потребления ресурсов сервера и достичь той же цели:

    private void setSessionCookie() {
        HttpCookie ck = new HttpCookie(XConstants.X_SESSION_COOKIE_KEY) {
            Expires = DateTime.Now.AddMinutes(_sessionInfo.SessionTimeoutMinutes)
        };
        DateTime now = DateTime.UtcNow;
        _sessionInfo.SessionLastValidatedAt = now;
        ck.HttpOnly = true; // server-only cookie
        ck["LastCheck"] = now.ToString(XConstants.XDATEFORMAT);
        ck["Content"] = new Cipher().Encrypt(Serializer.Serialize(_sessionInfo).OuterXml,
            ConfigurationManager.AppSettings[XConstants.X_APPKEY_KEY]);
        System.Web.HttpContext.Current.Response.Cookies.Add(ck);
    }
0 голосов
/ 18 августа 2010

Сессия - это место для хранения подобных вещей.

Вы также можете использовать распределенный кеш (http://msdn.microsoft.com/library/cc645013.aspx), который хорошо масштабируется. Пример кода по ссылке выше

// CacheFactory class provides methods to return cache objects
// Create instance of CacheFactory (reads appconfig)
DataCacheFactory fac = new DataCacheFactory();
// Get a named cache from the factory
DataCache catalog = fac.GetCache("catalogcache");
//-------------------------------------------------------
// Simple Get/Put
catalog.Put("toy-101", new Toy("thomas", .,.));
// From the same or a different client
Toy toyObj = (Toy)catalog.Get("toy-101");
// ------------------------------------------------------
// Region based Get/Put
catalog.CreateRegion("toyRegion", true);
// Both toy and toyparts are put in the same region
catalog.Put("toy-101", new Toy( .,.), "toyRegion");
catalog.Put("toypart-100", new ToyParts(…), "toyRegion");
Toy toyObj = (Toy)catalog.Get("toy-101", "toyRegion");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...