ASP.NET setting and getting viewstate in a property - asp.net

can someone please explain me the code written below
public IList<GetProductPrice> CurrentPage
{
get { return ViewState["CurrentPage"] as List<GetProductPrice>; }
set { ViewState["CurrentPage"] = value; }
}

It is called a Property. They generate a getter and setter functions when compiled:
List<GetProductPrice> GetCurrentPage(){
return ViewState["CurrentPage"] as List<GetProductPrice>;
}
void SetCurrentPage(List<GetProductPrice> value) {
ViewState["CurrentPage"] = value;
}
//i think its actual get_.. but it doesn't matter for the example
So its generates ease of use getter setters. which you can just call by using:
var test = CurrentPage; //compiled to var test = GetCurrenctPage();
CurrentPage = test; //compiled to SetCurrentPage(test);
If you leave the getter and setter empty like this:
public int CurrentPage
{
get;
set;
}
it will also generate a backing field on the class where it stores the data:
private int _currentPage;
public GetCurrentPage(){ return _currentPage }
public SetCurrentPage(int value) { _currentPage = value }
Why do we do this?
Using getters and setters is a very old best practise from java (where ide's would have an option to generate them). But this would lead to a lot of boilerplate code!
In C# they try to counter this by adding these properties. But why do we need getters and setters? For example if you want to be notified when a value changes (to mark the classes it self as dirty). I think entity framework uses it to track if a model is changed otherwise it wont do a db update call. There are also other usefull tools that inject code in properties on compile time. to add extra functionality.
How not to use it:
using properties to return HttpContext.Current Is a dangerous one because you secretly depend on the HttpContext so try not to do this at any time!
Generally its also bad practise to use it when the code inside the get or set is very heavy (very instensive). Its bad practise because someone else using the code might think he is just setting a property/field while actually some very heavy code is executed. its best practice to make a special function for this instead and private the getter/setter:
public int Property {get; private set; }
public SetProperty(int value){
//intensive code here:
Property = value;
}

This property is letting the consumer of the property to use it like Local collection without referring the ViewState in the code. It will make the code simple and easy to use.
get { return ViewState["CurrentPage"] as List<GetProductPrice>; }
Here the ViewState object ViewState["CurrentPage"] is converted to list of GetProductPrice
set { ViewState["CurrentPage"] = value; }
Here the List is assigned to ViewState["CurrentPage"]

This code will only work in a controller, where ViewState is a property. This CurrentPage property provides a statically-typed way to access a certain ViewState item through that property.
So instead of sprinkling ViewState["CurrentPage"] as List<GetProductPrice> all over your controller code where you want to access the "current page", you can now simply use the CurrentPage property.
Of course "current page" is a term made up by the developer who chose to name things like this, I don't see how a List<GetProductPrice> has a relation to the "current page".

Related

Unable to store the value of IEnumerable of type in viewstate in asp.net

I am trying to store the result of the api call that returns results of type IEnumerable to a viewstate in my asp.net application. After executing line
this.PendingApprovalUserChangeRequest = pendingChangeRequest , i see the value null in this.PendingApprovalUserChangeRequest though the pendingChangeRequest contains value
What could be the problem ?
protected IEnumerable<PendingApprovalUserChangeRequest> PendingApprovalUserChangeRequest
{
get
{
if (ViewState["UserChangeRequestsDataTable"] != null)
{
return (IEnumerable<PendingApprovalUserChangeRequest>)ViewState["PendingApprovalUserChangeRequest"];
}
else
{
return null;
}
}
set { ViewState["PendingApprovalUserChangeRequest"] = value; }
}
var pendingChangeRequest = Task.Run(async () => await service.GetPendingChangeRequest()).Result;
this.PendingApprovalUserChangeRequest = pendingChangeRequest;
Albeit the real core problem is using ASP.NET Web Forms at all, your next underlying problem is using ViewState in your getter/setter implementations.
That is too much responsibility for a class property, and hides implementation magic from users of PendingApprovalUserChangeRequest property in the future.
What if another developer wants to use PendingApprovalUserChangeRequest property but not in an ASP.NET context and ViewState does not exist?
Simply declare your property for your class:
protected IEnumerable<string> PendingApprovalUserChangeRequest { get; set; }
Then use ViewState in the Service/Controller/Manager.:
var result = Task.Run(async () => await service.GetPendingChangeRequest()).Result;
MyClass.PendingApprovalUserChangeRequest = result; //examples setting the property
ViewState["PendingApprovalUserChangeRequest"] = result; //if you need to store the result for View to use
DisplayUserChangeRequestsData(result); //call the function you mentioned in your comments
This way you do not have to deal with the confusion of your getter/setter for hydrating/populating your ViewState key "PendingApprovalUserChangeRequest".
This concept of an instance of a class persisting its own properties beyond its own instantiation in memory is an anti-pattern and you should be thinking about other components/mechanisms persisting the state of your class that contains the property "PendingApprovalUserChangeRequest". Why wouldn't you persist an instance of the class? Either way, a property worrying about its own persistence via ViewState or some other pattern is definitely a bad idea, buggy, confusing and wrought with design flaws and headaches.

PersistenceMode vs. Storing property in ViewState

What is the difference in utility/performance between using PersistenceMode on a property and storing the value of said property in ViewState in an ASP.NET web page?
This:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[PersistenceMode(PersistenceMode.InnerProperty)]
public int ClientUno { get; private set; }
versus this:
public int ClientUno
{
get
{
if (ViewState["ClientUno"] == null) return 0;
else return (int)(ViewState["ClientUno"]);
}
set { ViewState["ClientUno"] = value; }
}
I have done some googling around the internets and can't figure this one out. It seems like this would have come up before - I just can't find the answer. Anyone?
PersistanceMode has nothing to do with storing data in a ViewState. It is used to create custom server controls and affects server code.
For example see: How do I make a control with a child control collection in ASP.Net

Flex - how to detect if Object DATA has changed?

In Flex (Flash Builder 4), I need a way to know if something in an array collection has changed.
I have a custom object:
[Bindable]
public var _myobject:MyObject;
It's basically just a class containing a bunch of different String and Number properties.
I need a reliable way to know if any of the properties have been changed. For example, I am binding the properties to a user interface (fields), but it's also possible for some of the properties to change through code.
Is there a way to do this? I found ChangeWatcher, but that looks like it only looks at a single simple property, such as a String or Number. I need to watch or detect changes in all the properties in my object, hopefully without having to add ChangeWatcher events to every property. Is this possible?
You're probably better off just dispatching binding events on the specific properties you want bindable. Better yet, dispatch a custom binding event, so that all of the things that are bound don't have to filter for "is this the property I care about?" It's really easy with Flash Builder 4.5 to do this, just select your variable name and press Ctrl-1, select "Create getter and setter," select getter and setter and check "Bindable" and "create custom event."
This will create code for you that looks something like this:
private var _yourProperty:String;
[Bindable (event='yourPropertyChange')]
public function get yourProperty():String {
return _yourProperty;
}
public function set yourProperty(value:String):void {
if (value !=== _yourProperty) {
_yourProperty = value;
dispatchEvent(new Event('yourPropertyChange'));
}
}
This will be much less verbose and more performant than the code that Flash Builder generates for you behind the scenes when you just use the Bindable tag on its own.
If you use defined classes as VO/DAO and apply the [Bindable] tag to the class, this will do binding on all properties for you (so long as they are read/write).
Anonymous object detection is difficult at best, let alone adding additional headaches of loosing compiler type checking.
Super basic example: - the key is to tie it to the dispatcher, so internally it can send out the PropertyChangeEvent.
[Bindable]
public class Actor extends EventDispatcher
{
public var fName:String;
public var lName:String;
public var age:uint;
public function get displayName():String
{
return lName +', '+ fName;
}
public function Actor()
{
super();
}
}
public class BindableDictionary extends EventDispatcher {
public function BindableDictionary() {
super();
}
public var dictionary:Dictionary = new Dictionary();
[Bindable("change")]
public function get(key:Object):Object {
return dictionary[key];
}
public function put(key:Object, value:Object):void {
dictionary[key] = value;
dispatchEvent(new Event(Event.CHANGE));
}
}
maybe this class will give you some new idea

JSF data binding

I am having trouble using JSF just wanted to run it by so if there is anything obvious someone can spot. I have a managed bean which is giving me trouble. In my faces-config.xml I have:
<managed-bean>
<description>Info Bean</description>
<managed-bean-name>InfoBean</managed-bean-name>
<managed-bean-class>bean.InfoBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
In my JSF I have the following:
<h:outputText value="#{InfoBean.deviceModel}" rendered="true"></h:outputText>
I have a POJO for InfoBean as follows:
public class InfoBean {
String deviceModel;
String userEmail;
String active;
public InfoBean() {
// TODO Auto-generated constructor stub
}
public String getDeviceModel() {
return deviceModel;
}
public void setDeviceModel(String deviceModel) {
this.deviceModel = deviceModel;
}
public String getUserEmail() {
return userEmail;
}
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
public String getActive() {
return active;
}
public void setActive(String active) {
this.active = active;
}
}
There is a no arg constructor in POJO too, but for some reason the deviceModel value does not get displayed to the screen and I cannot figure out why! Any help much appreciated. I have a handler which is also in the faces-config as a separate managed bean, when the user clicks a button, control goes to handler class which calls a service that populates fields in the POJO InfoBean, so as I can see it should appear but it does not!
Any help much appreciated.
I have sorted out the issue and the solution is that since I had a model like this: JSP button is clicked->call goes to Handler->handler calls method in service->Service populates the managed bean InfoBean and returns it to handler
The managed bean even though declared in the config file with scope as session was NOT actually part of the session. In my handler after returning the InfoBean I added:
HttpSession session = (HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(false);
session.setAttribute("InfoBean", InfoBean);
This placed it in the session and immediately and values started appearing! :-))
I have read several articles about this and never seen this mentioned, so I am wondering how it is done otherwise. One other suggestion I got was make InfoBean a private instance of the Handler with getters and setters, this way it will get created with the handler and will also be olk. I have not tried this approach though. Thanks to all who helped.
How your deviceModel property of the bean is populated?
Are you sure that it is not null? You can eventually check that by putting a log in the getter method:
public String getDeviceModel() {
System.out.println("Getter called: " + deviceModel + ".");
return deviceModel;
}
Eventually, you can modify the scope of the bean to set it as session.
Your post shows it being defined in request scope not session scope. If you change it to session, you won't need put it in using setAttribute(). Or maybe I'm missing something.
Despite changign the scope to session, it was not working, the above code where I add it to the HttpSession is necessary in order for this to work, or so I have found.
Thanks.

Is it possible to remove properties from a dynamic class?

I have a dynamic ActionScript Class that is used to send parameters to a WebService. Some of these parameters are always present, so they are public properties of the Class:
package
{
[Bindable]
public dynamic class WebServiceCriteria
{
public var property1:int;
public var property2:String;
public var property3:String;
public var property4:String;
}
}
But, I am also adding properties at runtime that can change over time:
criteria.runTimeProperty = "1";
I'm not very familiar with using dynamic classes, so I was wondering if it is possible to "remove" the new property. Let's say the next time I call the WebService I don't want that property sent - not even as a null. How can I remove it from the Class instance without creating a new instance each time?
I believe all you'd need to do is this:
delete criteria.runTimeProperty;
or
delete criteria["runTimeProperty"];
Either should do the same thing.
See the delete documentation for specifics.

Resources