I am just converting and app from C#/WPF to C#/UWP (Windows 10) and it seems that IList does not update the UWP ListView.
So first question - should it ?
and if not then how should I bind the IList property to ensure the ListView will update if items are added or removed?
Maybe some more context - new items are getting created on a background thread - and the exact same method/code seems to work fine with C#/WPF.
<ListView x:Name="siteListView" SelectionChanged="SiteListView_SelectionChanged"
DataContext="{x:Bind _this}"
ItemsSource="{x:Bind Customer.items, Mode=OneWay}" >
public class Customer : RealmObject
{
[PrimaryKey]
public string id { get; set; } = Guid.NewGuid().ToString();
public string name { get; set; }
public string address { get; set; }
public string contact { get; set; }
public float complianceScore { get; set; }
public string completionStatus { get; set; }
public IList<Site> sites { get; }
}
So it seems Realm IList does not implement the IList interface because of some conflicts with Android and as a result UWP bindings won't work. BUT I found a relatively simple solution. https://github.com/realm/realm-dotnet/issues/1575
public partial class SimpleList : ContentPage
{
ObservableCollection<Item> observableItems = new ObservableCollection<Item>();
IRealmCollection<Item> rawItems;
public class SimpleList()
{
InitializeComponent();
rawItems = realm.All<Item>().AsRealmCollection();
foreach (Item item in rawItems)
{
observableItems.Add(item);
}
rawItems.SubscribeForNotifications((sender, changes, error) =>
{
if (changes != null)
{
foreach (int i in changes.DeletedIndices)
{
observableItems.RemoveAt(i);
}
foreach (int i in changes.InsertedIndices)
{
observableItems.Insert(i, rawItems[i]);
}
foreach (int i in changes.ModifiedIndices)
{
observableItems.RemoveAt(i);
observableItems.Insert(i, rawItems[i]);
}
}
if (error != null)
{
// TODO: Handle Exceptions
}
});
MyListView.ItemsSource = observableItems;
}
async void Handle_ItemSelected(object sender, ItemTappedEventArgs e)
{
if (e.Item == null)
{
return;
}
// DO Stuff
// Deselect Item
((ListView)sender).SelectedItem = null;
}
}
Related
I have a class showbookings with salesinformation list.
public class ShowBookings
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string ShowId { get; set; }
public DateTime ShowTime { get; set; }
public List<SalesInformation> SalesInformation { get; set; }
}
public class SalesInformation
{
public string SeatNo { get; set; }
public string SalesOrderConfirmationId { get; set; }
}
While calling update method I need to update for SeatNo and SalesOrderConfirmationId but this list is not accessible to me inside for loop.I need to return the list of items after updating showid,seatno SalesOrderConfirmationId but item.SalesInformation = salesInfo shows an error cannot convert salesinformation to generic list.Pls let me know how to sort this issue
public async Task<ActionResult<List<ShowBookings>>> UpdateShowBookings(string ShowId, string SeatNo, string SalesOrderConfirmationId)
{
var showBookings = new List<ShowBookings>();
var salesInformation = new List<SalesInformation>();
showBookings = await _context.DbCollection.Find(ShowBookings => ShowBookings.ShowId == ShowId)
.ToListAsync().ConfigureAwait(false);
if (showBookings != null)
{
var _sbList = showBookings.ToList();
foreach (var item in _sbList)
{
var salesInfo = new SalesInformation();
item.ShowId = ShowId;
salesInfo.SeatNo = SeatNo;
item.SalesInformation = salesInfo;
_sbList.Add(item);
}
return _sbList;
}
else
{
return new List<ShowBookings>();
}
}
"SalesInformation" is a list, while salesInfo is a object. You need to do:
item.SalesInformation.Add(salesInfo);
Also, in ShowBooking, inside constructor, initialize your List, else you will receive NullReferenceException.
Try to use
item.SalesInformation = new List<SalesInformation> { salesInfo };
SalesInformation of ShowBookings is List<SalesInformation> type,so you need to set its value with a list.
you already have list of showbookings
public async Task<ActionResult<List<ShowBookings>>> UpdateShowBookings(string ShowId, string SeatNo, string SalesOrderConfirmationId)
{
var salesInformation = new List<SalesInformation>();
var showBookings = await _context.DbCollection.Find(ShowBookings => ShowBookings.ShowId == ShowId)
.ToListAsync().ConfigureAwait(false);
if (showBookings != null)
{
return showBookings;
}
else
{
return new List<ShowBookings>();
}
}
I am writing a Provider Hosted APP using SP 2013 and I have a data layer which uses REST to CRUD on sharepoint lists. Now I got the List items in JSON format but I am not able to iterate through the list data can you please help in doing that? (is there any class for List Items which I can deserialize into?)
This is the code
public JToken GetListData(string webUrl, string userName, SecureString password, string listTitle)
{
using (var client = new WebClient())
{
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
client.Credentials = new SharePointOnlineCredentials(userName, password);
client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
var endpointUri = new Uri(new Uri(webUrl), string.Format("/sites/DTF/_api/web/lists/getbytitle('{0}')/Items", listTitle));
var result = client.DownloadString(endpointUri);
var t = JToken.Parse(result);
return t["d"];
}
}
You need to use the DataContractJsonSerializer class to deserialize the data as is demonstrated here:
http://www.codeproject.com/Articles/272335/JSON-Serialization-and-Deserialization-in-ASP-NET
To make this work though you have to create classes that match the structure of the Json. The easiest way to do this copying a raw Json response into a tool which will generate the classes like this one:
http://json2csharp.com/
The actual classes you will need to generate varies based on the structure of the data you are getting in your REST response. Here is an example I created that demonstrates making a request, parsing the Json Response and downloading a file based on the result:
public class JsonHelper
{
/// JSON Serialization
public static string JsonSerializer<T>(T t)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream();
ser.WriteObject(ms, t);
string jsonString = Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
return jsonString;
}
/// JSON Deserialization
public static T JsonDeserialize<T>(string jsonString)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj = (T)ser.ReadObject(ms);
return obj;
}
}
//Custom Json Classes
public class RootObject
{
public D d { get; set; }
}
public class D
{
public GetContextWebInformation GetContextWebInformation { get; set; }
public List<Result> results { get; set; }
}
public class GetContextWebInformation
{
public int FormDigestTimeoutSeconds { get; set; }
public string FormDigestValue { get; set; }
public string LibraryVersion { get; set; }
public string SiteFullUrl { get; set; }
public string WebFullUrl { get; set; }
}
public class Result
{
public ContentType ContentType { get; set; }
public string EncodedAbsUrl { get; set; }
public string FileLeafRef { get; set; }
public Folder Folder { get; set; }
public int FileSystemObjectType { get; set; }
public int Id { get; set; }
public string ContentTypeId { get; set; }
public string Title { get; set; }
public int? ImageWidth { get; set; }
public int? ImageHeight { get; set; }
public string ImageCreateDate { get; set; }
public object Description { get; set; }
public object Keywords { get; set; }
public string OData__dlc_DocId { get; set; }
public int ID { get; set; }
public string Created { get; set; }
public int AuthorId { get; set; }
public string Modified { get; set; }
public int EditorId { get; set; }
public object OData__CopySource { get; set; }
public int? CheckoutUserId { get; set; }
public string OData__UIVersionString { get; set; }
public string GUID { get; set; }
}
//SharePoint Calls
class Program
{
static void Main()
{
string url = "https://sharepoint.wilsonconst.com/";
string filename = "2010-07-23 13.32.22.jpg";
string digest = "";
HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.BaseAddress = new System.Uri(url);
string cmd = "_api/contextinfo";
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("ContentType", "application/json");
client.DefaultRequestHeaders.Add("ContentLength", "0");
StringContent httpContent = new StringContent("");
HttpResponseMessage response = client.PostAsync(cmd, httpContent).Result;
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
RootObject sp = JsonHelper.JsonDeserialize<RootObject>(content);
digest = sp.d.GetContextWebInformation.FormDigestValue;
}
client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.BaseAddress = new System.Uri(url);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("X-RequestDigest", digest);
client.DefaultRequestHeaders.Add("X-HTTP-Method", "GET");
string uri = "_api/web/lists/GetByTitle('Wilson Pictures')/Items?$select=ID,FileLeafRef,EncodedAbsUrl&$filter=FileLeafRef eq '" + filename + "'";
HttpResponseMessage response2 = client.GetAsync(uri).Result;
response2.EnsureSuccessStatusCode();
if (response2.IsSuccessStatusCode)
{
string listItems = response2.Content.ReadAsStringAsync().Result;
RootObject sp = JsonHelper.JsonDeserialize<RootObject>(listItems);
foreach (Result result in sp.d.results)
{
MemoryStream stream = (MemoryStream)client.GetAsync(result.EncodedAbsUrl).Result.Content.ReadAsStreamAsync().Result;
using(FileStream fileStream = System.IO.File.Create(#"C:\" + result.FileLeafRef))
{
stream.WriteTo(fileStream);
}
}
}
else
{
var content = response.Content.ReadAsStringAsync();
}
}
This seems like a lot of complexity, but really it makes working with Json objects quite easy and takes only moments to setup before you can start calling your custom objects to easily manipulate the data.
Assuming that you want to retrieve data from SharePoint Online the following example demonstrates how to consume SharePoint REST Interface via WebClient Class:
using (var client = new SPRestClient(webUri.ToString()))
{
client.Credentials = GetCredentials(webUri,userName,password);
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
var data = client.GetJson("/_api/lists/getbytitle('Tasks')/items"); //get list items
//print list item's title
foreach (var item in data["d"]["results"])
{
Console.WriteLine(item["Title"]);
}
}
where
public static SharePointOnlineCredentials GetCredentials(Uri webUri, string userName, string password)
{
var securePassword = new SecureString();
foreach (var ch in password) securePassword.AppendChar(ch);
return new SharePointOnlineCredentials(userName, securePassword);
}
and
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace SharePoint.Client
{
public class SPRestClient : WebClient
{
public SPRestClient(string webUri)
{
BaseAddress = webUri;
FormatType = JsonFormatType.Verbose;
}
public JObject GetJson(string requestUri)
{
return ExecuteJson(requestUri, HttpMethod.Get, null, default(string));
}
public JObject ExecuteJson<T>(string requestUri, HttpMethod method, IDictionary<string, string> headers, T data)
{
string result;
var uri = BaseAddress + requestUri;
if (headers != null)
{
foreach (var key in headers.Keys)
{
Headers.Add(key, headers[key]);
}
}
EnsureRequest(method);
switch (method.Method)
{
case "GET":
result = DownloadString(uri);
break;
case "POST":
if (data != null)
{
var payload = JsonConvert.SerializeObject(data);
result = UploadString(uri, method.Method, payload);
}
else
{
result = UploadString(uri, method.Method);
}
break;
default:
throw new NotSupportedException(string.Format("Method {0} is not supported", method.Method));
}
return JObject.Parse(result);
}
private void EnsureRequest(HttpMethod method)
{
var mapping = new Dictionary<JsonFormatType, string>();
mapping[JsonFormatType.Verbose] = "application/json;odata=verbose";
mapping[JsonFormatType.MinimalMetadata] = "application/json; odata=minimalmetadata";
mapping[JsonFormatType.NoMetadata] = "application/json; odata=nometadata";
Headers.Add(HttpRequestHeader.ContentType, mapping[FormatType]);
Headers.Add(HttpRequestHeader.Accept, mapping[FormatType]);
if (method == HttpMethod.Post)
{
Headers.Add("X-RequestDigest", RequestFormDigest());
}
}
private string RequestFormDigest()
{
var endpointUrl = string.Format("{0}/_api/contextinfo", BaseAddress);
var result = UploadString(endpointUrl, "Post");
var contentJson = JObject.Parse(result);
return contentJson["FormDigestValue"].ToString();
}
public JsonFormatType FormatType { get; set; }
}
public enum JsonFormatType
{
Verbose,
MinimalMetadata,
NoMetadata
}
}
SPRestClient.cs
I've used the following code to add two properties to Form Designer but they won't display. The field type is similar to Sitecore.Form.Web.UI.Controls.CheckboxList and I need it to display the same properties. Unfortunately I can't step into this code and the module isn't throwing any errors so I feel like I'm missing something simple.
public class CheckBoxListPipedField : Sitecore.Forms.Mvc.Models.Fields.CheckBoxListField
{
[VisualCategory("List")]
[VisualFieldType(typeof(Sitecore.Form.Core.Visual.ListField))]
[VisualProperty("Items:", 100)]
public ListItemCollection ListItems { get; set; }
[VisualCategory("List")]
[VisualFieldType(typeof(MultipleSelectedValueField))]
[VisualProperty("Selected Value:", 200)]
public ListItemCollection SelectedValue { get; set; }
public CheckBoxListPipedField(Item item) : base(item)
{
}
public override ControlResult GetResult()
{
var values = new List<string>();
StringBuilder stringBuilder1 = new StringBuilder();
if (this.Items != null)
{
foreach (SelectListItem selectListItem in
from item in this.Items
where item.Selected
select item)
{
values.Add(selectListItem.Value);
stringBuilder1.AppendFormat("{0}, ", selectListItem.Text);
}
}
var results = string.Join("|", values);
return new ControlResult(base.ID.ToString(), base.Title, results, stringBuilder1.ToString(0, (stringBuilder1.Length > 0 ? stringBuilder1.Length - 2 : 0)));
}
}
Not sure why they wouldn't show up as the default code for the CheckboxListField doesn't have those, but try:
[TypeConverter(typeof(ListSelectItemsConverter))]
public override List<SelectListItem> Items
{
get
{
return base.Items;
}
set
{
base.Items = value;
if (this.Items != null)
{
this.Value = (
from x in this.Items
where x.Selected
select x.Value).ToList<string>();
}
}
}
[ParameterName("selectedvalue")]
[PropertyBinder(typeof(ListFieldValueBinder))]
[TypeConverter(typeof(ListItemsConverter))]
public override object Value
{
get;
set;
}
You might be able to just set these to get { return base.Column }, etc, but here is how it looks on the base class.
[DefaultValue(1)]
public int Columns
{
get;
set;
}
[TypeConverter(typeof(StringToDirection))]
public Direction Direction
{
get;
set;
}
public int Rows
{
get
{
if (this.Items.IsNullOrEmpty<SelectListItem>())
{
return 1;
}
int num = (this.Columns == 0 ? 1 : this.Columns);
if (this.Items.Count % num <= 0)
{
return this.Items.Count / num;
}
return this.Items.Count / num + 1;
}
}
There was nothing wrong with the code in question. I neglected to add the assembly and class to the new Field Type, and had only set the MVC type.
I am trying to write some unit tests for my account controller web apis which make use of UserManager but I keep receiving null on the line in the title in the following section:
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
I have tried so many different ways to fix this as I have read that I need to Mock some of the parts of ApplicationUser but have not managed to get any of them to fix my problem. Below is some of the code I have implemented following a tutorial to unit test:
public interface IStoreAppContext : IDisposable
{
//IDbSet<User> Users { get; }
DbSet<User> u { get; }
DbSet<SportProgram> SportContext { get; set; }
int SaveChanges();
void MarkAsModified(User item);
}
}
The api I am trying to unit test in my account controller is:
(This line below "var user..." is where the problem starts. it calls the line in the title of this question)
[Route("userProfile/{username}")]
public IHttpActionResult getUserProfile(String username)
{
var user = UserManager.FindByName(username);
if (user != null)
{
db2.MarkAsModified(user);
return Ok(user);
}
else
{
return NotFound();
}
}
Then in my TestProject I have the following context class:
class TestStoreAppContext : IStoreAppContext
{
public TestStoreAppContext()
{
this.u = new TestProductDbSet();
}
public DbSet<User> u { get; set; }
public DbSet<SportProgram> SportContext { get; set; }
public int SaveChanges()
{
return 0;
}
public void MarkAsModified(User item) { }
public void Dispose() { }
}
}
Finally in my test controller where i test the api:
[TestMethod()]
public void getUserProfileTest()
{
var context = new TestStoreAppContext();
context.u.Add(GetDemoProduct());
var controller = new AccountController(context);
var result = controller.getUserProfile("john") as OkNegotiatedContentResult<User>;
Assert.AreEqual("john", result.Content.UserName);
}
The GetDemoProduct called above:
User GetDemoProduct()
{
return new User()
{
Id = "3",
UserName = "john",
Password = "Password-1",
};
}
Can anyone point me in the right direction please?
I'm trying to add a new scheduler event to database. It's added to the scheduler datasource and its visible in scheduler, but isn't call controller Create method.
Edit or delete newly added event also don't call controller methods, but change datasource.
Already exists events work well.
Model:
public class ResourceSchedulerModel : ISchedulerEvent
{
public string Title { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public string EndTimezone { get; set; }
public string StartTimezone { get; set; }
public int BTS_Id { get; set; }
public ResourceSchedulerModel() { }
public ResourceSchedulerModel(BusyTimeSlot bts)
{
BTS_Id = bts.BTS_Id;
Start = bts.BTS_From;
End = bts.BTS_To;
Title = bts.BTS_Name;
Description = bts.BTS_Description;
ResId = bts.BTS_RES_Id;
}
}
Controller methods:
public virtual JsonResult Read([DataSourceRequest] DataSourceRequest request)
{
EntityWrapper ew = new EntityWrapper();
List<BusyTimeSlot> btss = ew.GetAllBusyTimeSlots();
List<ResourceSchedulerModel> sm = new List<ResourceSchedulerModel>();
foreach (BusyTimeSlot b in btss)
sm.Add(new ResourceSchedulerModel(b));
return Json(sm.ToDataSourceResult(request));
}
public virtual JsonResult Destroy([DataSourceRequest] DataSourceRequest request, ResourceSchedulerModel task)
{
if (ModelState.IsValid)
{
// delete
}
return Json(new[] { task }.ToDataSourceResult(request, ModelState));
}
public virtual JsonResult Create([DataSourceRequest] DataSourceRequest request, ResourceSchedulerModel task)
{
if (ModelState.IsValid)
{
//add
}
return Json(new[] { task }.ToDataSourceResult(request, ModelState));
}
public virtual JsonResult Update([DataSourceRequest] DataSourceRequest request, ResourceSchedulerModel task)
{
if (ModelState.IsValid)
{
// edit
}
return Json(new[] { task }.ToDataSourceResult(request, ModelState));
}
View:
#(Html.Kendo().Scheduler<SchedulerTry.Models.ResourceSchedulerModel>()
.Name("scheduler")
.Date(new DateTime(2014, 10, 11))
.MinorTickCount(1)
.Views(views =>
{
views.DayView();
views.WeekView(weekView => weekView.Selected(true));
views.MonthView();
views.AgendaView();
})
.DataSource(d => d
.Model(m => {
m.Id(f => f.BTS_Id);
m.Field(f => f.Title).DefaultValue("No title");
})
.Read("Read", "Resource")
.Create("Create", "Resource")
.Destroy("Destroy", "Resource")
.Update("Update", "Resource")
)
)
In addition, when I try close or cancel the edit window of new event I get an error
Uncaught TypeError: Cannot read property 'BTS_Id' of undefined kendo.all.min.js:11
Try updating the BTS_Id as below intialization as below:
public int bTS_Id;
public string BTS_Id
{
get
{
return bTS_Id;
}
set
{
bTS_Id = value;
}
}
My bad, I have another Create method in controller.