Perform MVCPaging which is SEO friendly - asp.net-mvc

Hi I am trying to use MVC paging, I have created a partial view and place it in a View, to which I am passing IPagedList, now when I perform paging, I use following code
<%:Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount, new AjaxOptions { UpdateTargetId = "dv1" }).Options(o => o.Action("IndexPaging").AddRouteValue("currpage","page"))%> and IndexPaging returns PartialView, but my problem is that, on paging, I do not get to see the 2nd page data in view source. My requirement is to make it SEO friendly, so that when google crawler crawl's through my paging, it can read other page's data.

Related

MVC 4 load partial view dynamically on single page

I have a MVC 4 application which has a single home view. I have three link buttons and want to load three different forms dynamically based on the button click. I am using mvc partial views. So, if I click on button-1 it should load partialView-1 and should also send value-1 from the corresponding text box to partialView-1.
I am looking for mvc inbuilt approach rather than doing heavy javascript work.
You can do this like this.
A. Have different methods inside your controller returning PartialViewResult
[HttpGet]
public PartialViewResult GetPartialView1(int value)
{
return PartialView("_PartialView1"); //This view should exist in appropriate views folder.
}
B. Your buttons on the left handside should be #Ajax.ActionLink
#Ajax.ActionLink(
"Button1",
"GetPartialView1",
new {
value1 = 1},
new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "righthandsidebox"
}
)
C. The UpdateTargetId = "righthandsidebox" that should be the id of the div on the right hand side. Contents of righthandsidebox will be replace by the PartialView
There is nothing built into MVC to do this as what you want to do happens on the front-end. If you want to be dynamic you have to use javascript.
If you want to avoid javascript then it can't be dynamic. You would wrap each button and value in a form and have it submit its value to the back-end and by what is passed you then you have your view render what partial you want. But this wouldn't be dynamic as want it to be.
I'm not sure what you consider as "heavy" when it comes to javscript? With jQuery what you want you do doesn't take much.
(lighter javascript work) You can either have your View place all of the partial views on the page with a class that sets them to display:none then just javascript to simple change out the class to view the partial you would like. But you have a lot of partials then you can do the following.
Or have the buttons make an `ajax call to the back-end fetching the partial that you need.
The bottom line is... if you want dynamic you need to use javascript.

WebApi and Knockout patterns within MVC

I am having some issues around the patterns needed to bring my application into the WebApi + Knockout world. The following scenario has thrown be a bit.
I have a very basic grid partial view (_grid.cshtml). It uses a GridViewModel, which only has a QueryID. The Grid partial passes the QueryID using Ajax (which is defined in the ko ViewModel) to a WebApi method which returns a collection of objects in JSON. I then use knockout to bind the columns of the grid based on the returned JSON, and then loads the rows in.
This all works fine, but I'm uncertain if this is the correct approach.
// When the query is changed update the grid data.
self.selectedQueryID.subscribe(function (newQuery) {
self.SelectQuery(newQuery.ID());
});
// Execute the query and set the results as the rows of the table
self.SelectQuery = function (queryID) {
$.ajax({
url: '/api/Query/Execute?ID=' + queryID,
type: 'POST',
contenttype: 'application/json',
success: function (result) {
self.gridData(result);
}
});
};
The complexity comes when I have another partial view which is a list of available Queries that a user can choose from. This partial view sits adjacent to the grid partial view. I want to be able to somehow send the clicked query across to the grid so it can then shoot another ajax request off to get the data of the new query. I know this is completely the wrong way to think about an MVC application, but I just don't know enough about WebApi.
#Html.Partial("~/Views/Shared/_Grid.cshtml", Model.GridViewModel)
#Html.Partial("~/Views/Shared/_Queries.cshtml", Model.User)
This is all in an effort to implement some sort of default query for the grid, then give the user the option to select other queries.
I have also started looking into Backbone and Knockback but don't know (enough about them or) if this is the right direction.

ASP.Net Web Api + KnockoutJs + MVC4 - Tying it together

I am starting a new project, and keen to make use of the KnockoutJS + Web Api which are new to me, I have a good understanding of the Web Api, but Knockout is tough to get my head around at the moment.
This is my initial thoughts of how I want my app to work:
I have a standard MVC controller such as LeadsController
LeadsController has an Action called ListLeads, this doesn't actually return any data though, but just returns a view with a template to display data from Knockout.
The ListLeads view calls my api controller LeadsApiController via ajax to get a list of leads to display
The leads data is then mapped to a KnockoutJs ViewModel (I don't want to replicate my view models from server side into JavaScript view models)
I want to use external JavaScript files as much as possible rather than bloating my HTML page full of JavaScript.
I have seen lots of examples but most of them return some initial data on the first page load, rather than via an ajax call.
So my question is, how would create my JavaScript viewModel for Knockout when retrieved from ajax, where the ajax url is created using Url.Content().
Also, what if I need additional computed values on this ViewModel, how would I extend the mapped view model from server side.
If I haven't explained myself well, please let me know what your not sure of and I'll try and update my question to be more explicit.
I think your design is a good idea. In fact, I am developing an application using exactly this design right now!
You don't have to embed the initial data in your page. Instead, when your page loads, create an empty view model, call ko.applyBindings, then start an AJAX call which will populate the view model when it completes:
$(function () {
var viewModel = {
leads: ko.observableArray([]) // empty array for now
};
ko.applyBindings(viewModel);
$.getJSON("/api/Leads", function (data) {
var newLeads = ko.mapping.fromJS(data)(); // convert to view model objects
viewModel.leads(newLeads); // replace the empty array with a populated one
});
});
You'll want to put a "Loading" message somewhere on your page until the AJAX call completes.
To generate the "/api/Leads" URL, use Url.RouteUrl:
<script>
var apiUrl = '#Url.RouteUrl("DefaultApi", new { httproute = "", controller = "Leads" })';
</script>
(That's assuming your API route configured in Global.asax or App_Start\RouteConfig.cs is named "DefaultApi".)
The knockout mapping plugin is used above to convert the AJAX JSON result into a knockout view model. By default, the generated view model will have one observable property for each property in the JSON. To customise this, such as to add additional computed properties, use the knockout mapping plugin's "create" callback.
After getting this far in my application, I found I wanted more meta-data from the server-side view models available to the client-side code, such as which properties are required, and what validations are on each property. In the knockout mapping "create" callbacks, I wanted this information in order to automatically generate additional properties and computed observables in the view models. So, on the server side, I used some MVC framework classes and reflection to inspect the view models and generate some meta-data as JavaScript which gets embeded into the relevant views. On the client side, I have external JavaScript files which hook up the knockout mapping callbacks and generate view models according the meta-data provided in the page. My advice is to start out by writing the knockout view model customisations and other JavaScript by hand in each view, then as you refactor, move generic JavaScript functions out into external files. Each view should end up with only the minimal JavaScript that is specific to that view, at which point you can consider writing some C# to generate that JavaScript from your server-side view model annotations.
For the url issue add this in your _Layout.cshtml in a place where it is before the files that will use it:
<script>
window._appRootUrl = '#Url.Content("~/")';
</script>
Then you can use the window._appRootUrl to compose urls with string concatenation or with the help of a javascript library like URI.js.
As for the additional computed values, you may want to use a knockout computed observable. If that is not possible or you prefer to do it in .Net you should be able to create a property with a getter only, but this won't update when you update other properties on the client if it depends on them.

MVC Paging and Sorting Patterns: How to Page or Sort Re-Using Form Criteria

What is the best ASP.NET MVC pattern for paging data when the data is filtered by form criteria?
This question is similar to: Preserve data in .net mvc but surely there is a better answer?
Currently, when I click the search button this action is called:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Search(MemberSearchForm formSp, int? pageIndex, string sortExpression)
{}
That is perfect for the initial display of the results in the table.
But I want to have page number links or sort expression links re-post the current form data (the user entered it the first time - persisted because it is returned as viewdata), along with extra route params 'pageIndex' or 'sortExpression',
Can an ActionLink or RouteLink (which I would use for page numbers) post the form to the url they specify?
<%= Html.RouteLink("page 2", "MemberSearch", new { pageIndex = 1 })%>
At the moment they just do a basic redirect and do not post the form values so the search page loads fresh.
In regular old web forms I used to persist the search params (MemberSearchForm) in the ViewState and have a GridView paging or sorting event reuse it.
One possible solution is to attach a javascript click handler to the pager links that will submit the form by updating a hidden field containing the page number. This way you will get all the search criteria in the controller action.
Another possibility is to transform those pager links into submit buttons and place them inside the form.
A third possibility is to use the Session to persist search criteria.
You could perform a GET instead of a POST. if your request is to return search results, a GET might make more sense anyway. The benifit would be that all of your search fields are encoded into the URL. So, when you perform a page or sort on th exisiting URL, your data is perserved.
I have an example that using the MvcContrib Grid and Pager here:
http://weblogs.asp.net/rajbk/archive/2010/05/08/asp-net-mvc-paging-sorting-filtering-using-the-mvccontrib-grid-and-pager.aspx

ASP.Net MVC Best approach to render a results grid

I'm creating a search page, the page has a form that is being submitted using Ajax, after the search is performed I want to display a grid with the results.
My question is, should I create the grid when the page loads and then fill it with the data after the search is performed, or create the grid on the server when the search is performed and then just append the grid to the page.
I was thinking on creating a helper method to render the grid and invoking it from the controller after it gets the results, then returning the result of the helper method and appending it to the page, but this might be against MVC architecture (I'm defining UI on the controller).
What approach should I take?
Thanks
for the grid creation, you can have a look at MVCContrib grid helper
You could use jqGrid (http://www.trirand.com/blog/) or Flexigrid (http://www.flexigrid.info/) and load data with ajax and json. You submit search form with ajax, controller returns JsonResult, and then you load it into grid in callback. It is easy to implement and gives you additional functionalities (sorting and much, much more). Here you have some demos:
http://trirand.com/jqgrid/jqgrid.html

Resources