So I have a method that I "borrowed" from the internet that I use on many of my pages to handle the sorting of a grid column.
private string GetSortDirection(string column)
{
// By default, set the sort direction to ascending.
string sortDirection = "ASC";
// Retrieve the last column that was sorted.
string sortExpression = ViewState["SortExpression"] as string;
if (sortExpression != null)
{
// Check if the same column is being sorted.
// Otherwise, the default value can be returned.
if (sortExpression == column)
{
string lastDirection = ViewState["SortDirection"] as string;
if ((lastDirection != null) && (lastDirection == "ASC"))
{
sortDirection = "DESC";
}
}
}
// Save new values in ViewState.
ViewState["SortDirection"] = sortDirection;
ViewState["SortExpression"] = column;
return sortDirection;
}
Now it works great, but alas, I must copy it to every page that I want to call it from because it references the viewstate. So I want to move it to my helper class and have it store in the session state instead, however, I can referernce neither State in the helper class.
Is their any way to access the session from a help class? Can I pass by reference the session state?
If I understand the question correctly, you're looking to access ViewState or Session from a class that is not a page.
If so, you can use HttpContext.Current.Session, or, you should be able to typecast HttpContext.Current.CurrentHandler to type Page, and then access the ViewState.
Alternatively, you could always just put your code in a base class, which all your pages will inherit from, rather than inheriting from System.Web.UI.Page.
No you don't use Session, because if you test Session, you have user 1 that select One Columns 1, and he changes page, he will have the same selected columns, this is problem , becaue when use initilize page, he must have initial state and no selected state.
Technically you can use Session but for me functionaly it's not recomended
You can use HttpContext.Current.Session in any assembly which references System.Web and is executing in a web process.
However, putting generic (i.e. reused in multiple places, non-specific key) values like that in Session will cause all sorts of trouble. For example, what if the user opens two browser windows in the same session?
I would suggest either a base Page/Control/UserControl class, or a helper class which is initialized with data from the page. Your code sample looks more like it belongs in control-related base class.
You can use System.Web.HttpContext.Current however you could run into some syncing issues using session state like this. It's possible you could add your GetSortDirection method as an extension method to page which may be easier to accomplish.
Related
I'm learning XAF and I want to know how to access the value of a PropertyEditor to change it. I want to take the value from a PropertyEditor and put that value into another PropertyEditor's value. My code is like this:
Property Editor reserva = (PropertyEditor)((DetailView)View).FindItem("Reserva"); //This is a custom object
PropertyEditor dni = (PropertyEditor)((DetailView)View).FindItem("Dni");//This is a simple text editor
PropertyEditor dniReserva = (PropertyEditor)reserva.View.FindItem("Dni");//This is a variable from the custom object
dni.PropertyValue = dniReserva.ControlValue;
This does not work, any ideas? Thank you
Are you talking about copying the value of a non persistent property to another non persistent property? Because in any other case I believe there are more suitable ways to copy a value, working with the actual properties (here is usefull answer to help you with that)and not the editors.
If however you actually need this,I believe you could create a ViewController and use the PropertyEditor properties like this
foreach (PropertyEditor editor in ((DetailView)View).GetItems<PropertyEditor>())
{
var control = editor.Control as IntegerEdit;
if (control != null)
{
if (editor.Id == "Id" || editor.Caption == "Id")
{
control.Enabled = false;
}
}
}
Each property editor in XAF reads value from the specific property of the business object. This specificity reduces your task to copying the value of the specific property to another one.
In the ViewController, you can access the current business object using the View.CurrentObject property. Once the property is updated with an appropriate value, the new value will immediately appear in the property editor.
If the business object does not implement the INotifyPropertyChanged interface (for example, if you are using Entity Framework Code First), you may also want to call the View.Refresh method to make new values appear in the editor.
I have some controls in my page, when the page load first time the values are getting from database and placed in corresponding controls. When i click the another button again it will go to the controller and get the value from the database and bind the gridview. I have three class in my model, second and third class wrapped in first class. when i bind the second class in gridview, that time first class comes null so all the values are becoming null and bind the gridview only. How to solve this.
Again HTTP is stateless, unless you store your current model in a persistence medium like session, it will get lost in post back!
if I understood your question right !
when you bind your classes for the First Time , put them in a Session var then return it to the view ,
then when you post the second time when you click the other button, make sure to retrieve the session var in the actionmethod and then assign the new values to the class inside this session var, instead of just returning the new ones thinking that old ones are still there.
If I understand what you are asking then you can store it in TempData. TempData will persist until the next request.
public class YourView
{
public ActionResult Index()
{
string firstName = "Stephen";
TempData["FirstName"] = firstName;
return View();
}
public void ButtonClicked()
{
string firstName = (string)TempData["FirstName"];
}
}
Note though that temp data only lasts until the next request. So for this to work, after your view was loaded then the next call would have to be the ButtonClicked call.
The controller is stateless so if you need to persist something longer you have to make it kinda hackish and really ugly like this TempData["FirstName"] = TempData["FirstName"] in every spot that your controller will be called until you need to use that value. Like I said I don't recommend that (or for that case using Session) but if you needed to, then that's the safest way, in my opinion.
I'm working on asp.net mvc3 application. I guess it's described somewhere but a fast search didn't help much and also I get very diverse opinions on using Session variables but still I have a little time to make a decision.
The problem is that I have a razor view where in image gallery images are shown and user that has permissions can delete one or many images. However I can't delete each image at the time the user click the button, instead I have to collect the id's of the images that have been "deleted" from the user (I remove the span tag which holds the image) but the actual deleting is perform by service and I have to pass the service all the data at once.
All this is inside Html.BeginForm so the data is collected on submit and before that I need a way to store those values somehow. Using sessions seems the easiest way by now. I tried something like this :
public void DeletePicture(long documentImageID)
{
if (documentImageID != null)
{
Session["imagesIdForDeleting"] = documentImageID;
}
}
But with a simple debug I can not figure out first - how at all I can access the documentImageID value from the Session["imagesIdForDeleting"]. I don't know if it's just matter of syntax or I'm trying to make the things less complicated than they are in real. Also - I'm not sure if making something like this I'm actually saving all the values or I rewrite the previous value and always have only one value stored in the session variable. Anyways, Any help how to implement this right would be appreciated.
You can store list in Session.
e.g.
public void DeletePicture(long documentImageID)
{
if(Session["imagesIdForDeleting"] == null)
{
Session["imagesIdForDeleting"] = new List<long>();
}
if (documentImageID != null)
{
var list = (List<long >)Session["imagesIdForDeleting"];
list.Add(documentImageID);
}
}
I'm not sure if making something like this I'm actually saving all the
values or I rewrite the previous value and always have only one value
stored in the session variable.
Yes you are right about overwriting the stored value.
Use a typed list to store the images and put it in session.
public void DeletePicture(long documentImageID)
{
if (documentImageID != null)
{
if(Session["imagesIdForDeleting"]) == null
{
Session["imagesIdForDeleting"] = new List<long>();
}
((List<long>)Session["imagesIdForDeleting"]).Add( documentImageID);
}
}
I've created two classes in business layer.
the first one is called Users with id (int), pass (string) and privileges (Privilege) properties and the second one is called Privilege and has id (int) and privilegeName (string) properties.
I've a method that returns all the users, and I use a repeater (actually I bind it to a DataList to auto create the ItemTemplate for me and then use a repeater) and it works and displays all the properties well except for my List property. it generates instead something like this System.Collections.Generic.List`1[WebApplication2.Public.BLL.Users]
I want to display it in a friendly way like "User Privileges : Privi1, Privi2" but still I want to keep the layers of my application clean and structured, for example I won't store them in a database in the same table and just store them as a text and append it.
I hope to find a simple and good solution...Thanks in advance guys =)
PS : I don't want to display the object Privilege, I want to display privilege.privilegeName
When using repeaters, there are two approaches, one is the one suggested by Bugai13: to have a custom property that displays it. This is fine for certain types of nested data.
Your other option is to just have a repeater inside a repeater, and bind it appropriately (to what would be a list assigned to your main data object, depending on how you O/R Mapper works).
You can have the code for the custom display property not in the data model, but in your presentation layer somewhere (depending on your framework/design), so it's not a "bad" thing to do that. It's up to you, with whatever "feels" best.
Just create property at your Bussiness object, and bind it:
public string PrivilegiesString
{
get
{
var sb = new StringBuilder("User Privileges : ");
foreach(var item in privileges)
{
sb.AppendFormat("{0}, ",item.privilegeName);
}
return sb.ToString();
}
}
The situation is this:
I have an abstract class used globally that used to reference a Session variable via a public property. We now want to change its behavior to return a property on a master page.
(By simply changing the guts of this particular property, we hope to avoid doing a lot of rewrites)
This is just a snippet of the class:
public abstract class AppSession
{
public static CaseNumber CurrentCaseNo
{
/* OLD METHOD DELETED */
get
{
if (CurrentPage.Master != null)
// property on the master page
return CurrentPage.Master.CurrentCaseNo;
else
throw new Exception("This page has no master page");
}
}
}
Above, "CurrentPage" is not real/valid. I just wrote that there to show context.
Is this even possible?
Thanks!
J
Look at the HttpContext.Current object. I believe it's Handler property will return the currently executing page. It would be easier to read a value stored in the Session that pulling it out of a property since the Session is available off of HttpContext.Current.
Building on David's answer, this can be used statically throughout your application:
Page myPage = System.Web.HttpContext.Current.CurrentHandler as Page;
if( myPage != null )
return ((MyMaster)myPage.Master).CurrentCaseNo;
I think that you would need to work with something that took a "page" object in as a parameter, and from there, you could determine if the page that was passed is your master page. And do what you need from there....
But that adds quite a bit of overhead.
The real question here is what are you trying to avoid? Trying to get rid of session and move to viewstate?