Display contents of SharePoint 2010 document library on MVC page - asp.net-mvc

I have been struggling with this for a while now and I cannot find any helpful information on the interweb or forums etc.
Basically I have been asked to output the contents of my SharePoint 2010 document library onto a standard MVC web page.
Here is my code:
public class HomeController : Controller
{
public ActionResult Index()
{
using (ClientContext site = new ClientContext("Http://MySPSite"))
{
List list = site.Web.Lists.GetByTitle("MyList");
site.Load(list);
site.ExecuteQuery();
}
return View();
}

I managed to pull listitems that I wanted to using the following
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
List<string> documentTitles = new List<string>();
using (ClientContext context = new ClientContext("http://siteurl"))
{
List list = context.Web.Lists.GetByTitle("doctest");
context.Load(list);
CamlQuery query = new CamlQuery();
query.ViewXml = "<View/>";
ListItemCollection listItems = list.GetItems(query);
context.Load(list);
context.Load(listItems);
//context.Load(listItems ,items => items.Include(
// item=>item["FileLeafRef"]
// ));
context.ExecuteQuery();
foreach (ListItem item in listItems )
{
documentTitles.Add(item["FileLeafRef"].ToString());
}
}
return View(documentTitles);
}
FileLeafRef is the internal name for the "Name" column.
I commented out the include FileLeafRef since it is included by default but you may need it for other columns.
Also this needs to be done in .NET 3.5 since you are using the client libraries.
You will need to populate an object with the data you want and pass that to the view (If you are not aware of this you should look at some mvc examples. From your example I can't tell if you know mvc or not or if you are just posting code to demonstrate the SharePoint issue)
You may also have to set the context crentials
context.Credentials = new NetworkCredentials("Username", "Password", "Domain");
before calling execute.

Related

How to get specific rows in ASP.NET MVC?

I tried to call the database using ADO.NET and with the code I saw here last time...
private DBEntities db = new DBEntities();
public ActionResult ShowPage(int ID)
{
var query = from a in db.Products
where a.ID.Contains(ID)
select a;
var item = query.FirstOrDefault();
if (item != null)
return View(item);
else
return View(db.Products.ToList());
}
I got this code here and changed some of it.
It shows the whole table in the database
I'm new to programming that's why I don't know how to use it.
I'm not sure but I think I use ASP.NET Web Application .NET Framework 4.7.x when I created it.

ASP.NET MVC 5 API, Changing a class in GET function

I'm working on a dotnet mvc5 application. Here's a function from my api of customer controller
public IHttpActionResult GetCustomers()
{
var customerDtos = _context.Customers.ToList().Select(Mapper.Map<Customer, CustomerDto>);
return Ok(customerDtos);
}
I need to add "TYPEAHEAD" plugin to my application. The video series/instructor I'm following says to make the function code change to
public IHttpActionResult GetCustomers(string query = null)
{
var customersQuery = _context.Customers
.Include(c => c.MembershipType);
if (!String.IsNullOrWhiteSpace(query))
customersQuery = customersQuery.Where(c => c.Name.Contains(query));
var customerDtos = customersQuery
.ToList()
.Select(Mapper.Map<Customer, CustomerDto>);
return Ok(customerDtos);
}
in order to make "TypeAhead" plug in work on my view.
The only problem is previously while creating customers I didn't feel the need to add "MembershipType" class to my customer. So how do I use the new code without MembershipType. Is there any other attribute I can replace it with? Name, ID etc.
.Include(c => c.MembershipType);
essentially means that you also want to include the 'child' collection of MembershipType
See here for more information on Loading Related Entities
For your case, you can simply omit this.
public IHttpActionResult GetCustomers(string query = null)
{
var customersQuery = _context.Customers;
if (!String.IsNullOrWhiteSpace(query))
customersQuery = customersQuery.Where(c => c.Name.Contains(query));
var customerDtos = customersQuery
.ToList()
.Select(Mapper.Map<Customer, CustomerDto>);
return Ok(customerDtos);
}
You don't need to replace it with anything.
customersQuery is then an IQueryable<Customer> which the rest of this code can append Where clause to.
It is not executed against the database until the ToList call.

Creating pager for collection of anonymous type using PagedList.Mvc in ASP.NET MVC

I am developing an ASP.NET MVC project. In my project I need to implement pagination feature. So I use PagedList.Mvc for it. I installed it running this command,"install-package PagedList.Mvc" in package manager console. I know how to implement pagination using it. But I am having a problem with implementing for collection of anonymous type view.
This is my action method implementing pagination logic
public ActionResult IpList(int page = 1)
{
List<IpVisitInfo> ipVisitList = new List<IpVisitInfo>();
var rawVisits = trackTool.Visitors.GroupBy(x => x.IpAddress).Select(x => new { Visitors = x.Count(), IpAddress = x.Key, LastVisitedTime = x.OrderByDescending(c => c.Id).FirstOrDefault().VisitedAt }).ToPagedList(page,PageSize);
if(rawVisits!=null && rawVisits.Count()>0)
{
foreach(var visit in rawVisits)
{
IpVisitInfo info = new IpVisitInfo
{
IpAddress = visit.IpAddress,
LastVisitedAt = visit.LastVisitedTime,
TotalVisitors = visit.Visitors
};
ipVisitList.Add(info);
}
}
IpVisitListVM model = new IpVisitListVM
{
IpList = ipVisitList
};
return View(model);
}
As you can see I retrieved anonymous type collection and then loop through it and assign to strongly typed collection. I called to ToPagedList(PageNumber,PageSize) on anonymous type collection. But the problem is all the data required to implement pagination in view is in anonymous type collection. In view pagination has to be rendered something like this below.
#Html.PagedListPager(Model.Items, page => Url.Action("List", new { page }))
This is my view model
public class IpVisitListVM
{
public IEnumerable<IpVisitInfo> IpList { get; set; }
}
So according to what I am doing, IpList of my view model does not have required data to render pagination. If I retrieve all anonymous collection fist without using ToPagedList() on it, then loop through each record, performance will be very slow, because it is retrieving all records first from database. I will have so many records. How can I use PagedList on anonymous typed view and pass to strongly typed view to implement pagination?
In view model I am using this property
IEnumerable<IpVisitInfo> IpList
Instead of this
IPagedList<IpVisitInfo> IpList
because it does not have enough data to create pagination. Because I filtered in action.
But if I can pass following as list
trackTool.Visitors.GroupBy(x => x.IpAddress).Select(x => new { Visitors = x.Count(), IpAddress = x.Key, LastVisitedTime = x.OrderByDescending(c => c.Id).FirstOrDefault().VisitedAt }).ToPagedList(page,PageSize);
pagination is perfectly created and performance will be better. Is there a way to pass that list?

View not updating after post with ASP.Net MVC

I'm trying to build a very simple website to display some test data being added & updated using asp.net mvc (with razor) but whenever data is posted to my Post method, my data is not being updated. I'm trying to get a unordered list (for now) to be updated the second a post is triggered.
I'm posting my data as JSON using the following code:
string jsonDeviceData = SerializeHelper.Serialize<IDeviceData>(deviceData,
ContentTypeEnum.Json, false);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(localServerUrl);
webRequest.Method = "POST";
webRequest.ContentType = "application/json"; //"application/x-www-form-urlencoded";
byte[] deviceDataBuffer = Encoding.UTF8.GetBytes(jsonDeviceData);
Task<Stream> requestTask = webRequest.GetRequestStreamAsync();
using (Stream requestStream = requestTask.Result)
{
requestStream.Write(deviceDataBuffer, 0, deviceDataBuffer.Length);
}
Task<WebResponse> responseTask = webRequest.GetResponseAsync();
using (StreamReader requestReader = new StreamReader(responseTask.Result
.GetResponseStream()))
{
string webResponse = requestReader.ReadToEnd();
Debug.WriteLine("Web Response: " + webResponse);
}
Below is the code I'm using in the POST method. Don't worry about the logic being so simplistic and probably horrible, but I'm just dabbling with this idea. Data will be stored in SQL Server database and I'll use EF if I decide to go further with this:
[HttpPost()]
public ActionResult Index(DeviceModel model)
{
if (ModelState.IsValid && model != null)
{
var deviceViewModelList = HttpContext.Application["DeviceList"]
as List<DeviceViewModel> ?? new List<DeviceViewModel>();
if (deviceViewModelList.All(m => !string.Equals(m.Name,
model.Name,
StringComparison.InvariantCultureIgnoreCase)))
{
deviceViewModelList.Add(new DeviceViewModel(model));
}
HttpContext.Application["DeviceList"] = deviceViewModelList;
var homePageViewModel = new HomePageViewModel
{
DeviceList = deviceViewModelList
};
return RedirectToAction("Index");
}
else
{
return View();
}
}
My model is passed correctly and everything works ok when the data is posted my page is not updated, even after calling RedirectToAction("Index");
The code below gets called the first time the page is loaded and after calling the RedirectToActio("Index"):
public ActionResult Index()
{
ViewBag.Title = "Test Server";
var deviceViewModelList = HttpContext.Application["DeviceList"]
as List<DeviceViewModel> ?? new List<DeviceViewModel>();
var homePageViewModel = new HomePageViewModel
{
DeviceList = deviceViewModelList
};
return View(homePageViewModel);
}
This is the code I have in my .cshtml page:
<ul>
#if (Model?.DeviceList != null)
{
foreach (var device in Model.DeviceList)
{
<li>#device.Name</li>
}
}
</ul>
If I check Fiddler, the data, in this case, the list is build correctly.
If I press F5 my data is displayed correctly.
I've read so many articles at this stage and I still haven't got a solution, one of them being View not updated after post and while I've tried ModelState.Clear(); and as you can see from my code I'm using #device.Name which is one of the suggestion. I'm not sure about the last one.
Another article I read was ASP NET MVC Post Redirect Get Pattern but again to no avail.
I'm obviously missing something.
Most articles/samples I've been looking at refer to posting via a Form and I know I'm posting, but is that the same as posting via a Form?
Also my page's viewModel is for my page and it contains a list of devices. Is that OK rather than passing the list of device as the viewmodel to the page? The reason I'm doing this is that I will want to access other lists at a later stage.
Has anyone got any suggestions?
Much appreciated.

Displaying data in a MVC Web Page when the number of columns are not fixed?

I want to display the data in a Razor View in MVC from a customized datatype ('User' here) stored as a generic list. how to display that? the number of columns may vary, Is there a way to do this?
My code:
[HttpPost]
public ActionResult GetData(DataDTO data, FormCollection fc)
{
string server = fc["CategoryName"].ToString();
//"ctsintbmvodiaf1"
string cacheName = data.CacheName;
//"1CPlatformCache";
string keyName = data.KeyName;
//"UserContext_311581";
try
{
DataDAO.Initialize(server, cacheName);
var outPutData = DataDAO.dataCache.Get(keyName);
if (outPutData != null)
{
if (keyName.Contains("UserContext_"))
{
var ucOutput = (CTS.OneCognizant.Platform.Caching.User)outPutData;
CTS.OneCognizant.Platform.Caching.User userData = (CTS.OneCognizant.Platform.Caching.User)outPutData;
List<User> _user = new List<User>();
_user.Add(userData);
return View(_user);
}
}
}
}
You can try out the WebGrid HTML Helper that ships since ASP.NET MVC 3. Check out this blog post that shows how to use it. You can use it to easily render a grid of an "unknown" list.
You mention that you've used ASP.NET Web Forms databinding before, so if you imagine a simple GridView or DataGrid control, the WebGrid HTML Helper is fairly similar to that. A big difference is that the WebGrid helper does not have automatic edit/delete/insert support, so keep that difference in mind.

Resources