We have a Gridview, which gets filled via a DataSource. The datasource's SelectMethod is a function in the BL class, which calls a Stored Procedure that returns 2 Result-sets. The first result set is supposed to fill the gridview, so it's returned via the "return" keyword, and that works fine. The second result set is for later use (we're not separating them into 2 SP's because the query applies the same logic to get both result sets, and it's a long logic, so we don't want to run it twice). Our question is how to save the second result-set for the later use.
We initially thought of creating a global member in the BL class, and saving the result-set to it. But the problem is that when we need to use the second result-set, we're not in the same class where the gridview is, and that other class creates an instance of its own of the BL class, and of course that object doesn't have the data (the data is in the object created by the aspx page in which the gridview resides).
So then we thought of passing an "out" parameter the datasource's SelectMethod, and the method would save the second result set to that out parameter. But that's not working. I think we don't know how to tell the method that a parameter is "out". The way we pass the other parameters is by defining a method that is attached to the OnSelecting event, and then we pass them so:
e.InputParameters["schoolCode"] = currentSchoolCode;
e.InputParameters["levelCode"] = currentLayer;
Etc. However, we don't know how to tell the method that a parameter is "out". When we googled a little, all we could find was how to tell the method if a parameter is an output parameter - that is, passed to the SP as an output parameter. But that is not the case here.
So we will be very grateful if you help us find the solution for:
"Telling" the method that a certain parameter is "out", in order to get the value into it.
thanks.
Hmm... not quite understand your concern, but, how about this? pass your dataset to presentation layer and then:
dataset.Tables(0)
dataset.Tables(1)
or
DataReader.NextResult()
Related
I've got a Page, a GridView using an ObjectDataSource with a SelectMethod and a DropDownList. The SelectMethod, among other things, gets a string-array containing several IDs (to filter the Data) - but I also need it as DataSource for the DropDownList.
Alas, I cannot DataBind the DropDownList inside the SelectMethod since it's null.
An Idea would be to bind this string[] to a Session-Variable, but then I'd have to either re-set it upon every Page_Load or remove it from Session on every other page if I want it to update in case something on the Database changed.
What I'm looking for is some kind of variable that is available both in Page_Load and my ObjectDataSources SelectMethod, but that removes itself upon leaving the page (i.e. navigating to any other page on my Web-Application (preferably without having to call a method on EVERY other Page).
I hope you could understand my problem.
Thanks,
Dennis
As I understand the need to fetch the string array arises from the performance hit that a separate roundtrip will cause. To work around this you may create a separate object to feed your object data source. This object will have two methods one for getting the string array and another for getting the data for the grid (i.e. the select method)
You may then put an object like this in your page and fetch the data in it in a lazy manner. If the object makes a call for any of the data it stores the other part in a field. You can then use the ObjectDataSource ObjectCreating event to pass this object on your page to the ObjectDataSource
protected void odsSomething_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
e.ObjectInstance = YourInsntanceAlreadyInThePage;
}
This way you will avoid the roundtrip.
Also consider making two web service calls at the same time using the asynchronous client calls so that you can make both calls for the same time. If this is viable depends on the flow of your logic.
What I'm looking for is some kind of variable that is available both in Page_Load and my ObjectDataSource's SelectMethod, but that removes itself upon leaving the page (i.e. navigating to any other page on my Web-Application (preferably without having to call a method on EVERY other Page).
In a similar situation, I've used the Items property of the current HttpContext. It's an IDictionary (non-generic), so can hold arbitrary objects keyed by arbitrary objects, and its lifetime is precisely the duration of the current request, so will go away as soon as the request is ended. To use:
// Where you first get the data
HttpContext.Current.Items["SomeKey"] = new [] { "string1", "string2" };
// Where you want to to use the data
var strings = (string[])HttpContext.Current.Items["SomeKey"];
I have a question concerning Monotouch.
The situation: I have 2 ViewControllers. The first (let's call it VC-A) looks similar to the contacts edit screen, meaning it has a TableView with multiple Sections each containing Buttons and TextFields. Now when the user clicks one of these Buttons, he will get to the second ViewController (VC-B), which displays a TableView containing data from the database. When the user clicks on any of these rows, VC-B will be closed and i want to display the selected database entry (string) as the title of the Button (in VC-A) which opened VC-B in the first place.
When I did an objective-C project last year, I managed to send data back down the stack by using delegates, but I haven't found a way yet how this works in Monotouch.
I have read several questions here on SO about using the AppDelegate or using singletons, but I'm not sure that this is the right way of returning data from a subview.
You can kind of copy the delegate pattern. Add a C# delegate to your VC-B that takes one parameter, some data structure.
In VC-B's "ViewWillDisappear", call the delegate it it is not null and pass the data on to it.
This way, your calling VC can get acces to the data but you don't need tight coupling between the two controllers. All it has to do, is register a delegate-method in VC-B.
As MonoTouch is .NET4 you can use Func<MyDataStructure> or Action<MyDataStructure> and don't need to use full qualified delegate types.
I have a static singleton class that I use to store "state" type data about my app - current settings and selections that are needed in many different places in the app. That's one way to approach this.
You could also pass VC-B a reference to VC-A when you create VC-B, so that it can explicitly access it's parent view and pass back values that way.
I actually prefer to use TinyMessenger for cross container calls I find this to be very very useful when you don't want to keep references to your heavy viewcontrollers around which could potentially result in memory leaks!
var messageHub = new TinyMessengerHub();
// Publishing a message is as simple as calling the "Publish" method.
messageHub.Publish(new MyMessage());
// We can also publish asyncronously if necessary
messageHub.PublishAsync(new MyMessage());
// And we can get a callback when publishing is completed
messageHub.PublishAsync(new MyMessage(), MyCallback);
// MyCallback is executed on completion
https://github.com/grumpydev/TinyMessenger
SHORT VERSION
What's the best way to use reflection to turn something like string prop = "part1.first_name"; into a System.Reflection.PropertyInfo, so that I can use the GetValue and SetValue functions?
LONG VERSION
I'm using ASP .NET MVC to build a questionnaire for my organization. It's very long, so it's divided into several different pages. Since it's not uncommon for us to get requests like, "Can you move this question to that page, and this other question to another page," I need to build this to be pretty flexible for a junior programmer to change.
My model is a complex class (it's got five member classes that have mostly primitive-typed properties on them).
So, I access it by doing things like Model.part1.first_name or Model.part2.birth_date.
Since the same model is used on all of the pages, but not all of the questions are on every page, I have ActionAttributes that essentially clear out all of the properties that were submitted on the form except for the ones that were displayed on that page (so someone can't inject a hidden field into the form and have the value persist to the database).
I want to make sure that I only save valid field values and don't let the user proceed to the next page until the current one is entirely OK, but I also want to save the values that are valid, even if the user isn't allowed to proceed.
To do this, I have a function that takes two instances of my model class, a reference to the ModelStateDictionary, and a string[] of field names like "part1.first_name" and "part2.birth_date". That function needs to copy all of the values listed in the string array that do not have validation errors from the first (ie, form-submitted) object into the second (ie, loaded from the db) object.
As stated above, what's the best way to use reflection to turn something like "part1.first_name" into a System.Reflection.PropertyInfo, OR, is there a better way to accomplish this?
var infoParts = prop.Split('.');
var myType = Type.GetType(infoParts[0]);
var myPropertyInfo = myType.GetProperty(infoParts[1]);
Assuming "part1" is your type. Although this is very limited and very dependent on the string being in the correct format and the type being in the current scope.
I would probably handle this differently, using data. I would keep, in the database, which step each question belongs to. To render that step, I would select the questions that match that step and have a model that contains a list of question id/question pairs. Each input would be identified by the question id when posted back. To validate, simply compare the set of question ids with the expected ids for that step. This way, to change which question goes in which step is to only change the data in the database.
If you do end up going down that road, you'll need to split the string into parts and recursively or iteratively find the property on the object at each step.
PropertyInfo property = null;
Type type = questionModel.GetType();
object value = questionModel;
object previousObj = null;
foreach (var part in questionId.Split('.'))
{
property = type.GetProperty(part);
previousObj = value;
value = property.GetValue(value,null);
type = value.GetType();
}
// here, if all goes well, property should contain the correct PropertyInfo and
// value should contain that property's value...and previousObj should contain
// the object that the property references, without which it won't do you much good.
I have asp.net application. where on 2 web pages i have dropdown on each page. i want to populate the User list in drop down. so as usual i wrote the method FillUserDropDown() in common helper class.
and accessing this method on both page loads. but I am passing the Drop down control as parameter to this method so that method appears generic for all type of fill drop downs. Is this standard way? my seniors are avoiding me to passing the control as parameters.
So what is the best practice for this scenario? Please guide me.
To databind is better. But this is also acceptable just that you can let ASP.NET 'fill' it in automatically if you databind (it will generate the code for you). Return a datatable or list and and specify declarivly the binding.
Also tell your seniors that it's ok to do that too. If you've written the code already leave it.
Call Method By this way
FillDropDown(DropDownID, selectListItemText)
Set Below Code In your commonfile
DropDownID.DataTextField =
"TextFieldName";
DropDownID.DataValueField =
"ValueFieldName";
DropDownID.DataSource =
DatasourceName; DropDownID.DataBind();
if (includeSelectItem) {
DropDownID.Items.Insert(0, new
ListItem(selectListItemText,
selectListItemValue)); }
This way you can bind as you said above
I'm using a GridView in C#.NET 3.5 and have just converted the underlying DataSource from Adapter model to an object which gets its data from LINQ to SQL - i.e. a Business object that returns a List<> for the GetData() function etc.
All was well in Denmark and the Update, and conditional Select statements work as expected but I can't get the Delete function to work. Just trying to pass in the ID or the entire object but it's being passed in a "new" object with none of the properties set. I'm just wondering if it's the old OldValuesParameterFormatString="original_{0}" monster in the ObjectDataSource causing confusion again.
Anybody have any ideas?
I found the solution. I had to set the GridView's DataKeyNames property to the unique key that my data was returning (in this case a classically named ID field). I'm guessing that this property "unset" itself when the Grid refreshed.