General purpose paging and summary information - c#

I have a query that returns several thousand records and I'm using some paging to make the results present nicely to the user. In my view, however, I need to have a chart control that displays information of the entire result set, not just what page the user is on at any given time. I'm thinking of a couple ways to solve this:
Let the controller do it's paging thing and on the initial get from the page fire an AJAX call to fetch the entire query and set the chart's source with that.
Or add the entire JSON response as a property to a view model for my view. and do something like viewModelChart.JsonResponse = chart.dataSource kind of thing. Is there a particular pattern to follow when doing something like this? Any horror stories down the road to be aware of if I choose one path or the other?

Related

Re-rending the C# MVC Action using JS

I am using C# MVC for my project.
In Home page, I am rending one action using razor syntax.
Index.chtml Page
<div>
#Html.RenderAction("OrganizationManagerData","Home")
</div>
When I first time load Index page, "OrganizationManagerData" method also render and it shows employee data with all who are working under him/her in Tabular format.
Logged In manager can do many things in that like provide feedback to individual, give task, submit performance report of individual to higher authority, so on.
We have one more option on Index Page "Filter" when Manager clicks on it, it will show popup and can select the filter which needs like good performer, avg Performer, by task, so on.
What I want to achieve is when manager select Filters and click Apply, I want to re-render the table so that it will display filtered data.
What I am thinking is When user will click on "Apply", will call again DB and will show filtered Data
Is it good approach however I don't know how to re-render the "OrganizationManagerData" action again on Apply Click?
Or
Is it any better way to do it?
What is usually best practice to display intuitive dashboard which have loads of data.
Would like to hear your opinion.
Thanks in advance.
I just thought of maybe I will call Ajax for OrganizationManagerData and it will return json format which I will use to format table in JS.
However for this have to write lots of html in Javascript.
I have hide the rows which are not matching with my filter condition using JavaScript.

How to avoid code duplication if multiple pages look almost the same?

I have a couple of pages for e.g. Product that look almost the same. I have Product/Add and Product/Modify/{id} pages where one is an empty form to add new Product and the second one comes already filled with data for a current product and can be updated with additional information. Because Razor Pages separates this into Add and Modify PageModels, I have a different cshtml view for each of them.
I tried to use ViewComponents to build reusable parts of these views, but they are only good if all you want to do is display data. Because ViewComponents don't support Binding all I have left is somehow send ajax requests and append the data to submit, which even sounds wrong and probably isn't the right approach.
Is there any other way of creating these pages without duplication?
You can create one page for create and edit by sending a new object of the Product model (with no data in id attribute) and a created object (with data in id attribute) in case of editing. And in the view you can do rendering based on the sent object (whether it is new or not).

Keeping data across a redirect

I have a page with a form that accepts a list of account numbers into a text box, a bulk search essentially.
This does posts to the server, does a validation exercise and then if sucessful redirects to a display page.
Currently the list is added as a GET variable in the URL to the display page. This is limiting in that it means users can mess with it and larger data sets may be a problem. It also allows for a bypass of the validation but this is accounted for.
I see 2 general solutions which are basically variations of 1 theme:
Save the list to a DB and pass a key to load this to the diplay page.
Save to MemoryCache and again pass the key to the display page.
Based on these options it seems that 1. is better if I need multiple IIS node but needs manual cache cleanup where 2. will clean it's self up but may be a problem if I need to scale. This will be an intranet applcation so scale will probably not be required.
Is there a "industry standard" approach to this class of problem. I'm coming from the winforms world where keeping track of state wasn't an issue.
I don't think you really have to redirect to the display page at all. From the controller that gets the user input and prints the result just return the View that should render the results like:
public class SearchController : Controller
{
public ActionResult SearchForAccounts(string[] accounts)
{
var searchResults = db.Search(accounts);
return View('ResultsView', searchResults);
}
}
If you really really need to redirect, I guess you chould save the results into the application Cache and later if you need to scale you could use a Redis Cache provider for example, but again you should be able to show the required view.
Whether it's Webforms or MVC, I recommend not getting into the pattern of separating validation/processing and results into separate pages.
I'm guessing that if the data is invalid you want to put it back on the page so the user can edit it. (That's a guess inferred from what you're asking.)
You can post the data, and then if the data is valid then the "result" page shows the results. If the data isn't valid then the page can re-render the input form, populate it with the original inputs, and display a validation error. That way the user can modify their original input and try again. (Just be sure to escape/unescape if you're taking user input and reflecting it back onto the page.) That's easier if the form is a partial view (MVC) or a user control (Webforms.)

Overriding Telerik Radgrid data binding

I have a scenario where currently a telerik radgrid (webforms) is used on a page which currently allows telerik to control the paging, sorting, filtering etc. However I have noticed as this uses the default telerik behavior for these tasks it does it all in memory so nothing is lazy loaded.
In this instance there is a situation where upwards of 300,000 rows (1.2 million at one point), are returned and this seems to re-query every time it is paged, sorted etc which is cripplingly slow.
Now I want to push these concerns to the server side, as currently the db interactions happen via linq to sql so I would like to instead of just using the base (300k query) take the composable IQueryable and then add the filtering, sorting and paging logic in from the telerik control, as the data all seems to be there, I just dont know when I should be intercepting the controls data bindings to force it to only get the data it needs.
From my current investigating there is an OnSortCommand method, which seems to be triggered when a sort is requested, so I assume from there I can get the SortExpression and put that into the linq query, then there is also a FilterExpression which I can use to constrain the results in the query, and then finally there is the PageSize and CurrentPageIndex variables which allow me to work out how many pages I should be bringing back.
So all the data needed to constrain the queries exists there, however I dont know when I should be intercepting the binding process as currently if I were to intercept OnDataBinding and override the DataSource to take into account the filterexpression and paging details (as sorting is not available until a sorting command to my knowledge) then I would expect there to be only a query to pull back 50 rows (or whatever the page size is), however it seems to do the 300k query, then afterwards do the 50 row query, so I am confused as to if I should be intercepting another event or method.
If anyone could point me in a direction of what I should be intercepting/overriding I would be VERY grateful, as the documentation provided by telerik for this is not that great.
== Edit ==
Just to be a bit more specific about the scenario, I am not really wanting to internally create the datasource (advanced databinding) as they need to be re-usable components, so the control is created on the aspx page, then in the code behind on page load it will set the DataSource with an IQueryable object describing the query (the 300k one), then within this inherited control I want to be able to then use the filterexpression, sortexpression, pagesize and pageindex to append to the query. So the data source is provided external to this class.
== Edit 2 ==
Just to draw more attention to the crux of my confusion, one of the most baffling things for me currently is the fact that my grid is doing 3 queries:
one is to get the virtual row count from the IQueryable, that is fine returns the count as expected
the second is the unaltered 300k query, I dont have a clue why this is occuring
the third is the altered query which brings back 50 rows
As I have overridden the OnDataBinding method I do not know where else it is going to pull this data from, as the DataSource is updated before the end of the OnDataBinding to then have the altered IQueryable. So it is at some point doing something in Telerik Land to fetch this data when I dont want it to, as why do a huge query to get all data, then just query the minimal amount later? makes no sense...
Custom Pagging
Custom Sorting :- Please check "RadGrid2" in this link.
Custom Filtering
To achieve this thing i should suggest do not use AdvanaceDataBinding because it is very hard to manage with this.
Please Try to bind Radgird as we bind asp:Gridview.

How do I pass values from a database between pages in WPF?

I created an application that connects to an SDF database. The user is given a list of movies in a cinema. The user can select a movie and press an 'ok' button.
The user should then be presented with another datagrid which contains all the information of that movie.
I've tried passing the SelectedIndex between the two pages, it sends the SelectedIndex to the information page, but it won't assign it to the same SelectedIndex.
public Desc(int input_id)
{
InitializeComponent();
cinemaEntities = new cinema1.cinemaDBEntities();
movieViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("moviesViewSource")));
System.Data.Objects.ObjectQuery<cinema1.movie> moviesQuery = this.GetMovieQuery(cinemaEntities);
movieViewSource.Source = moviesQuery.Execute(System.Data.Objects.MergeOption.OverwriteChanges);
moviesListView.SelectedIndex = id;
What to do depends on the purpose of the software, but in any case I would recommend to spend a little more effort on the architecture of your software. As you want to use WPF, you should decide whether to go for a MVVM (Model-View-ViewModel) approach which is highly maintainable and has numerous advantages, but demands some time to get familiar with. The quick solution which is absoulutely fine for small or simple apllications is to code your GUI logic in the codebehind of your views and controls.
Anyway, I would create a model layer which mirrors your database data in according types (MovieDatabase has a Collection of Movies, etc. etc.). Then write an adapter to fill the model from the database.Then either use the model in your views - if you want to do it quickly - or write ViewModels to your Models (which is better) and use those in your views.
This being said, from the code you posted its hard to tell, what the problem is. Do you have a little bit more context? Why don't you pass the SelectedItem?
Why not just pass the Movie object to the second page? And then use .SelectedItem. Why does the second page need the whole list anyway if it is detail for just one movie?

Categories