2015-11-19 2 views
4

Я пытаюсь сохранить сложный объект в Viewstate, чтобы избежать его вызова каждый раз при загрузке страницы. Я понимаю, что его нужно сериализовать, чтобы сохранить и извлечь из Viewstate, что означает, что мой класс должен быть помечен как [Serializable]ASP.NET - Сохранение в ViewState Без сериализации

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

Class Article 
{ 
    Albums albumList { get; set; } 
    Authors authorList { get; set; } 
    ... 
} 

Возможно ли это и есть ли какой-либо возможный выход для сохранения и извлечения объекта Viewstate без сериализации?

+0

Как насчет кэша в памяти? Вы можете сохранить объекты _live_. –

+1

Вы можете обернуть свой класс в класс-оболочку, который реализует ISerializable, а затем вы можете реализовать его, как вам нравится, без указания различных зависимых классов как Serializable. Тем не менее, мой опыт показывает, что лучше всего уменьшить размер зрительного центра в максимально возможной степени. Если вы помещаете потенциально большой объект в viewstate, он отправляется клиентам, а затем он отправляет его обратно на * каждый * запрос/ответ. Это почти всегда менее эффективно, чем альтернативные варианты. – mikey

+0

Я избегу кэша по каким-то неизбежным причинам. В любом случае спасибо! –

ответ

1

Мне кажется, что из вашего прецедента, что «чтобы не называть его каждый раз при загрузке страницы» крики для кеша. Я думаю, если вы хотите, чтобы он истекал, возможно, установите некоторые зависимости, это might work better than session (мы не знаем всех деталей).

Теперь вы можете использовать json.net, который поможет вам сериализовать вашу информацию без изменения ваших объектов. Просто не злоупотребляйте viewstate, он может стать противным, если вы позволите ему расти. Использование сеанса или кеша (если оно соответствует вашим потребностям) - это то, что может улучшиться в долгосрочной перспективе.

Если это предмет отображения, обратите внимание также на Output cache, поскольку, возможно, вы можете отделить свой повторный контент в пользовательском элементе управления или что-то в этом роде.

Все сказанное, я хотел бы добавить маленький пример того, что вы на самом деле спросил использованием Json.NET (пример украдена из них):

//Doesnt need to be marked as serializable 
Product product = new Product(); 
product.Name = "Apple"; 
product.Expiry = new DateTime(2008, 12, 28); 
product.Sizes = new string[] { "Small" }; 
//Use this string to save into view state 
string json = JsonConvert.SerializeObject(product); 
ViewState["something"]=json; 

После этого, получить строку обратно из ViewState [что-то] и десериализировать его.

string json = (string)ViewState["something"]; 
Product m = JsonConvert.DeserializeObject<Product>(json); 

Предупреждение, код написан без его компиляции.

+0

О! Я должен был подумать об этом. Json.net подходит мне. Благодаря! –

1

Вы можете использовать ASP.NET Session объект вместо (это позволяет избежать маршрут сериализации, потому что все в Session хранится как Object), как это:

var theArticle = new Article(); 

Session["MyArticle"] = theArticle; 

Все в Session хранится как объект, так при извлечении Article объекта, то вам нужно, чтобы бросить его в Article, как это:

var myArticleFromSession = Session["MyArticle"] as Article; 

Примечание: рекомендуется ставить в проверках, чтобы увидеть, если Session ключа на самом деле существует, прежде чем пытаться получить доступ к значению, например:

if(Session["MyArticle"] != null) 
{ 
    // The key MyArticle exists, so it is safe to attempt to get the object value 
    var myArticleFromSession = Session["MyArticle"] as Article; 

    // Since we used as to attempt the cast, 
    // then myArticleFromSession will be null if the cast failed 
    // so check for null before using myArticleFromSession 
    if(myArticleFromSession != null) 
    { 
     // Use myArticleFromSession here 

    } 
} 
+0

Спасибо за ваш ответ Карл. Я попытался сохранить и загрузить его с помощью сеанса, но, к сожалению, он возвращает объект NULL. Хотя я делал это раньше, и я видел, как он работал, но, к сожалению, не работал в этом случае. –

0

Сериализации следует избегать, если это возможно, потому что это относительно медленно (не масштабируется).

Если вы хотите кэшировать конкретный объект между постбэк или между страницами, используйте ASP.NET Session объект для кэширования сеанса специфичного в Application объект для веба-узла кэширования, или использовать System.Web.Caching.Cache для собственного пользовательского кэширования поведение. Вы также можете кэшировать вывод страниц ASP.NET или частей страниц. Больше информации здесь: ASP.NET Caching

Но если вы хотите кэшировать окно просмотра всей страницы, существует возможность сохранения на уровне сервера на стороне сервера. В этом случае вам нужно будет создать новый BasePage. Например, это очень полезно, когда браузеры ограничивают размер очень больших просмотров. Вы можете получить более подробную информацию об этом подходе здесь: Server Side Viewstate

Смежные вопросы