Why is my Blazor Server Side application throwing an error "Object reference not set to an Instance of an Object - razor

I am trying to load a TelerikGrid in my .razor UI and I am receiving an error "Object reference not set to an instance of an object", but I cannot find what is null. The two main parts _gridData and Grid are populated.
Here is something that I did find, that may or may not be part of the issue, the "ReadItems" method is executed twice, prior to rendering the screen. The first time, no error is thrown, but the second time, I receive the following error message:
The Error is being thrown after SaveState() is execute for a second time:
Note: I don't what is triggering "ReadItems" to be executed a second time.
Here is my code:
#page "/bidItemSetHeader"
#inject IModalService Modal
#inject IJSRuntime JSRuntime
#inject LocalStorage LocalStorage
#attribute [Authorize(Policies.BidRead)]
<SPALoader>
<ContentTemplate>
<TelerikLoaderContainer OverlayThemeColor="light" Visible="#( !_loadingComplete )"
Text="#null" Class="initial-data-loader">
<Template>
<TelerikLoader Type="#LoaderType.InfiniteSpinner" Size="#LoaderSize.Large"></TelerikLoader>
</Template>
</TelerikLoaderContainer>
<TelerikGrid Data="#_gridData" #ref="#Grid" Width="1625px"
Pageable=true TotalCount=TotalCount PageSize=PageSize
Sortable=true Class="bidgrid" Groupable=true
FilterMode="GridFilterMode.FilterMenu"
OnRead="ReadItems" SelectionMode="#GridSelectionMode.None"
OnStateInit="#((GridStateEventArgs<BidItemSetHeader> args) => OnStateInit(args))"
OnStateChanged="#((GridStateEventArgs<BidItemSetHeader> args) => OnStateChangedHandler(args))">
<GridColumns>
<GridColumn Field="BidItemSetHeaderId" Title="Bid Item Set Header Id" />
<GridColumn Field="BidNumber" Title="Bid Number" />
<GridColumn Field="Description" Title="Description" />
<TelerikGridButtonColumn EditLink="#_editLinkPath" DetailLink="#_detailLinkPath" EditPolicy="#Policies.BidCreateEdit" KeyField="Id" />
</GridColumns>
</TelerikGrid>
</ContentTemplate>
</SPALoader>
#code {
// for Mockup, create test data
public class BidItemSetHeader
{
public int BidItemSetHeaderId { get; set; }
public string BidNumber { get; set; }
public string Description { get; set; }
public int StatusId { get; set; }
public string Notes { get; set; }
public string BidNoLastApplied { get; set; }
public DateTime DateCreated { get; set; }
public string CreatedBy { get; set; }
public DateTime DateModified { get; set; }
public string ModifiedBy { get; set; }
}
private SearchResult<BidItemSetHeader> _bidsFiltered { get; set; }
private List<BidItemSetHeader> _gridData { get; set; }
private List<BidItemSetHeader> _bidItemSetHeaderData { get; set; }
public TelerikGrid<BidItemSetHeader> Grid { get; set; }
string _userId { get; set; }
private string _defaultLinkPath = "bidItemSetHeader";
private string _detailLinkPath;
private string _editLinkPath;
string stateStorageKey = "BidItemSetHeaderGridState";
int PageSize { get; set; } = 10;
int CurrentPage { get; set; } = 1;
int TotalCount { get; set; }
BidSearch _search { get; set; }
bool _loadingComplete { get; set; } = false;
Telerik.DataSource.DataSourceRequest _lastRequest { get; set; }
bool _allRecords { get; set; } = false;
private BidItemSetHeader _headerItem;
private async Task Get()
{
_userId = (await authState.GetAuthenticationStateAsync()).GetId();
_bidItemSetHeaderData = new List<BidItemSetHeader>();
//1
_headerItem = new();
_headerItem.BidItemSetHeaderId = 93;
_headerItem.BidNumber = "0066436";
_headerItem.StatusId = 5;
_headerItem.Description = "0066436 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2014-12-19");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2014-12-19");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//2
_headerItem = new();
_headerItem.BidItemSetHeaderId = 94;
_headerItem.BidNumber = "0066445";
_headerItem.StatusId = 6;
_headerItem.Description = "0066445 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2014-12-23");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2014-12-19");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//3
_headerItem = new();
_headerItem.BidItemSetHeaderId = 95;
_headerItem.BidNumber = "0066461";
_headerItem.StatusId = 6;
_headerItem.Description = "0066461 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2014-12-30");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2014-12-30");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//4
_headerItem = new();
_headerItem.BidItemSetHeaderId = 96;
_headerItem.BidNumber = "0066462";
_headerItem.StatusId = 6;
_headerItem.Description = "0066462 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2014-12-30");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2014-12-30");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//5
_headerItem = new();
_headerItem.BidItemSetHeaderId = 97;
_headerItem.BidNumber = "0066479";
_headerItem.StatusId = 6;
_headerItem.Description = "0066479 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-06");
_headerItem.CreatedBy = "Jeff S";
_headerItem.DateModified = Convert.ToDateTime("2015-01-06");
_headerItem.ModifiedBy = "Jeff S";
_bidItemSetHeaderData.Add(_headerItem);
//6
_headerItem = new();
_headerItem.BidItemSetHeaderId = 98;
_headerItem.BidNumber = "0066486";
_headerItem.StatusId = 6;
_headerItem.Description = "0066486 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-07");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2015-01-07");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//7
_headerItem = new();
_headerItem.BidItemSetHeaderId = 99;
_headerItem.BidNumber = "0066501";
_headerItem.StatusId = 6;
_headerItem.Description = "0066501 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-08");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2015-01-08");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//8
_headerItem = new();
_headerItem.BidItemSetHeaderId = 100;
_headerItem.BidNumber = "0066562";
_headerItem.StatusId = 6;
_headerItem.Description = "0066562 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-19");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2015-01-19");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//9
_headerItem = new();
_headerItem.BidItemSetHeaderId = 101;
_headerItem.BidNumber = "0066573";
_headerItem.StatusId = 6;
_headerItem.Description = "0066573 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-21");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2015-01-21");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//10
_headerItem = new();
_headerItem.BidItemSetHeaderId = 102;
_headerItem.BidNumber = "0066585";
_headerItem.StatusId = 6;
_headerItem.Description = "0066585 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-22");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2015-01-22");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//11
_headerItem = new();
_headerItem.BidItemSetHeaderId = 103;
_headerItem.BidNumber = "0066585";
_headerItem.StatusId = 6;
_headerItem.Description = "0066585 Additions";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-22");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2015-01-22");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//12
_headerItem = new();
_headerItem.BidItemSetHeaderId = 104;
_headerItem.BidNumber = "0066601";
_headerItem.StatusId = 2;
_headerItem.Description = "0066601 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-26");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2015-01-26");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//13
_headerItem = new();
_headerItem.BidItemSetHeaderId = 106;
_headerItem.BidNumber = "0066601";
_headerItem.StatusId = 1;
_headerItem.Description = "0066601 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-26");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2015-01-26");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//14
_headerItem = new();
_headerItem.BidItemSetHeaderId = 107;
_headerItem.BidNumber = "0066610";
_headerItem.StatusId = 6;
_headerItem.Description = "0066610 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-27");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2015-01-27");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
//15
_headerItem = new();
_headerItem.BidItemSetHeaderId = 108;
_headerItem.BidNumber = "0066634";
_headerItem.StatusId = 6;
_headerItem.Description = "0066634 Item Import";
_headerItem.DateCreated = Convert.ToDateTime("2015-01-30");
_headerItem.CreatedBy = "Amy Howard";
_headerItem.DateModified = Convert.ToDateTime("2015-01-30");
_headerItem.ModifiedBy = "Amy Howard";
_bidItemSetHeaderData.Add(_headerItem);
_loadingComplete = true;
await LoadState();
}
protected async Task ReadItems(GridReadEventArgs args)
{
var something = args.Request;
await FilterBidItemSetImportHeader();
}
private async Task FilterBidItemSetImportHeader()
{
_loadingComplete = false;
PageSize = 10;
TotalCount = _bidItemSetHeaderData.Count;
_loadingComplete = true;
//01/21/2022 SEO 681530
if ((await authState.GetAuthenticationStateAsync()).GetRole() != "Admin")
{
// _gridData = _gridData.Where(x => x.Active.Equals(true)).ToList();
}
_gridData = _bidItemSetHeaderData;
await SaveState();
StateHasChanged();
}
#region StateManagement
async Task LoadState()
{
GridState<BidItemSetHeader> storedState = await LocalStorage.GetItem<GridState<BidItemSetHeader>>(stateStorageKey);
if (Grid != null && storedState != null)
{
await Grid.SetState(storedState);
}
}
async Task SaveState()
{
var gridState = Grid.GetState();
gridState.SelectedItems = new List<BidItemSetHeader>();
await LocalStorage.SetItem(stateStorageKey, gridState);
//await LocalStorage.SetItem("BidSearch", _search);
}
private async Task OnStateInit(GridStateEventArgs<BidItemSetHeader> args)
{
try
{
var state = await LocalStorage.GetItem<GridState<BidItemSetHeader>>(stateStorageKey);
if (state != null)
{
args.GridState = state;
}
else
{
var FilterDescriptors = new List<Telerik.DataSource.FilterDescriptorBase>()
{
new Telerik.DataSource.FilterDescriptor() { Member = "Active", Operator = Telerik.DataSource.FilterOperator.IsEqualTo, Value = true, MemberType = typeof(bool) },
};
args.GridState.FilterDescriptors = FilterDescriptors;
}
}
catch (InvalidOperationException)
{
// the JS Interop for the local storage cannot be used during pre-rendering
}
}
async void OnStateChangedHandler(GridStateEventArgs<BidItemSetHeader> args)
{
await SaveState();
}
#endregion
protected override async Task OnInitializedAsync()
{
_detailLinkPath = _defaultLinkPath + "/{0}";
_editLinkPath = _detailLinkPath + "/edit";
await Get();
}
}

Related

How to mock PATCH methods of WebAPI using MS Unit?

I have the following PATCH method for which I am writing Unit Tests.
[HttpPatch("{id}")]
public IActionResult Patch(Guid id, [FromBody] JsonPatchDocument<QuoteDraft> patch) {
Global.AccessToken = Request.Headers["Authorization"];
var draft = new QuoteDraft();
var json = string.Empty;
try {
draft = quoteDraftRepository.GetQuoteDraftById(id);
if (draft == null) {
throw new ArgumentException($"Draft quote not found for id {id}");
}
QuoteDraft quoteDraft = null;
foreach (var item in patch.Operations) {
json = Convert.ToString(item.value);
var lineItem = JsonConvert.DeserializeObject<LineItem>(json);
quoteDraft = AddLineItem(draft, lineItem);
}
return StatusCode(StatusCodes.Status200OK, new QuoteDraftResponse {
Message = messageHandler.GetMessage(MessageType.All),
QuoteDraft = quoteDraft
});
}
Below is my unit test method:
[testmethod]
public void patchtestmethod()
{
var jsonobject = new jsonpatchdocument<quotedraft>();
var quotedraft = new quotedraft
{
market = "noo",
program = "ils",
brochure = "2019",
season = "v1",
currency = "nok",
totalprice = 100,
};
var value = jsonconvert.serializeobject(quotedraft);
jsonobject.add("/lineitem/-", value);
quotecontroller.patch(it.isany<guid>(), jsonobject);
}
I am getting the error as shown in below screenshot:
Error Details
The json patch has to look something like this.
op: 'add',
path: '/lineItem/-',
value: {
destination: this.props.result.destination.code,
currency: this.props.result.currency.code,
sku: getSku(this.props.result.course.code, this.props.result.destination.code),
unitType: this.props.result.course.unitType,
startDate: format(this.props.result.startDate),
endDate: this.props.result.endDate,
quantity: this.props.result.numberOfWeeks.id,
category: 'Course',
language: 'NO',
departurePoint: this.props.result.departure ? this.props.result.departure.code : null,
description: this.props.result.course.description
},
Kindly let me know what I am missing.
Thanks
For jsonobject.Add, it accpets Expression<Func<TModel, TProp>> path which is used to define the path for this operation.
Model.cs
public class QuoteDraft
{
public string Market { get; set; }
public string Program
{
get; set;
}
public List<LineItem> LineItem { get; set; }
}
public class LineItem
{
public string Destination { get; set; }
public string Sku { get; set; }
}
Code
var jsonobject = new JsonPatchDocument<QuoteDraft>();
var quotedraft = new QuoteDraft
{
Market = "noo",
Program = "ils"
};
var lineItem = new LineItem
{
Destination = "D",
Sku = "S"
};
jsonobject.Add(q => q, quotedraft);
jsonobject.Add(q => q.LineItem, lineItem);
var value = JsonConvert.SerializeObject(jsonobject);

Not refreshing custom renderer Xamarin forms maps

I created a map with custom marker with real-time location update. But after adding a new pin to the map its not applying the custom renderer. If I zoomed-in or zoomed-out on the map its applying that custom renders for markers. Here is my code.
This Code is in Xamarin.Droid project
public class CustomMapRenderer : MapRenderer, IOnMapReadyCallback, GoogleMap.IInfoWindowAdapter
{
GoogleMap map;
List<Position> routeCoordinates;
List<CustomPin> customPins;
Action<CustomPin> onInfoWindowClicked;
public void OnMapReady(GoogleMap googleMap)
{
map = googleMap;
//map.InfoWindowClick += OnInfoWindowClick;
map.SetInfoWindowAdapter(this);
var polylineOptions = new PolylineOptions();
polylineOptions.InvokeColor(Android.Graphics.Color.Blue);
foreach (var position in routeCoordinates)
{
polylineOptions.Add(new LatLng(position.Latitude, position.Longitude));
}
map.AddPolyline(polylineOptions);
}
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
map.InfoWindowClick -= OnInfoWindowClick;
// Unsubscribe
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
routeCoordinates = formsMap.RouteCoordinates;
customPins = formsMap.CustomPins;
onInfoWindowClicked = formsMap.OnInfoWindowClicked;
((Android.Gms.Maps.MapView)Control).GetMapAsync(this);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (map != null)
{
map.Clear();
foreach (var pin in customPins)
{
var marker = new MarkerOptions();
marker.SetPosition(new LatLng(pin.Pin.Position.Latitude, pin.Pin.Position.Longitude));
marker.SetTitle(pin.Id.ToString());
marker.SetSnippet(pin.Pin.Address);
if(pin.UserType == global::Common.Models.UserType.Driver)
{
marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.car));
}
else if (pin.UserType == global::Common.Models.UserType.Rider)
{
marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.person));
}
map.AddMarker(marker);
}
}
}
void OnInfoWindowClick(object sender, GoogleMap.InfoWindowClickEventArgs e)
{
onInfoWindowClicked(GetCustomPin(e.Marker));
}
private CustomPin GetCustomPin(Marker marker)
{
return customPins.Find(x => x.Id.ToString() ==marker.Title.ToString());
}
public Android.Views.View GetInfoContents(Marker marker)
{
var inflater = Android.App.Application.Context.GetSystemService(Context.LayoutInflaterService) as Android.Views.LayoutInflater;
if (inflater != null)
{
Android.Views.View view;
var customPin = GetCustomPin(marker);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
view = inflater.Inflate(Resource.Layout.MapInfoWindow, null);
var infoImage = view.FindViewById<ImageView>(Resource.Id.markerInfoImage);
var infoTitle = view.FindViewById<TextView>(Resource.Id.markerInfoTitle);
var infoSummary = view.FindViewById<TextView>(Resource.Id.markerInfoSummary);
System.IO.Stream ims = Context.Assets.Open(customPin.Image);
// load image as Drawable
Drawable d = Drawable.CreateFromStream(ims, null);
// set image to ImageView
infoImage.SetImageDrawable(d);
//File file = new File(customPin.Image);
//var image = Android.Net.Uri.FromFile(file);
//var resource=ResourceManager.GetDrawableByName("driverLogActive_icon.png");
//infoImage.SetImageResource(resource);
//infoImag = customPin.Title;
infoTitle.Text = customPin.Title;
infoSummary.Text = customPin.MobileNo;
return view;
}
return null;
}
public Android.Views.View GetInfoWindow(Marker marker)
{
return null;
}
}
This code is in Xamarin.Forms project
public class CustomPin
{
public Pin Pin { get; set; }
public Guid Id { get; set; }
public string Title { get; set; }
public string MobileNo { get; set; }
public string Image { get; set; }
public string UserName { get; set; }
public UserType UserType { get; set; }
}
public class CustomMap : Map
{
public static readonly BindableProperty RouteCoordinatesProperty = BindableProperty.Create(nameof(RouteCoordinates), typeof(List<Position>), typeof(CustomMap), new List<Position>(), BindingMode.TwoWay);
public static readonly BindableProperty CustomPinsProperty = BindableProperty.Create(nameof(CustomPins), typeof(List<CustomPin>), typeof(CustomMap), new List<CustomPin>(), BindingMode.TwoWay);
public List<CustomPin> CustomPins
{
get { return (List<CustomPin>)GetValue(CustomPinsProperty); }
set { SetValue(CustomPinsProperty, value); }
}
public List<Position> RouteCoordinates
{
get { return (List<Position>)GetValue(RouteCoordinatesProperty); }
set { SetValue(RouteCoordinatesProperty, value); }
}
public Action<CustomPin> OnInfoWindowClicked;
public CustomMap()
{
RouteCoordinates = new List<Position>();
CustomPins = new List<CustomPin>();
}
}
This is how I use the custom map to render pin in Xamrin.Fomrs project
private void RenderPin(string longitudeCoordinate, string latitudeCoordinate,bool canMoveToLoacation, string lable,UserType userType,string mobileNo,string image,string userName)
{
double latitude = 0;
double longitude = 0;
double.TryParse(latitudeCoordinate, out latitude);
double.TryParse(longitudeCoordinate, out longitude);
var position = new Position(latitude, longitude);
var pin = new CustomPin
{
Pin = new Pin
{
Type = PinType.Place,
Position = position,
Label = lable,
},
Title = lable,
UserType = userType,
MobileNo = "Mobile No:" + mobileNo,
Image = "profile_images/" + image,
UserName = userName,
Id = Guid.NewGuid()
};
map.CustomPins.Add(pin);
map.Pins.Add(pin.Pin);
if (canMoveToLoacation)
{
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(latitude, longitude), Distance.FromKilometers(2)));
}
}
If you install the Xamarin.Forms.Maps pre-release (2.3.5.255-pre5), you can now just override the CreateMarker() method in MapRenderer. It's much more elegant, and it fixes this problem with pins not being updated when added after map creation.

Google Place Autocomplete in Xamarin.Forms

Has anyone integrated Google Place Autocomplete using Xamarin.Forms? I am to use it on a map for location suggestions. I've only seen resources for Xamarin.Android and Xamarin.iOS but on the part of implementing the AutoCompleteView, that I also don't know. I would be very thankful if someone could guide me with this. Thank you!
Place autocomplete can be implemented by using the Google Place API, whenever user enter a character, matching location with the entered character will be fetched from the Google server and binding back in User Interface.
Here's the link how to use Google Map Place API in Xamarin form:
http://www.appliedcodelog.com/2015/05/google-place-api-with-autocomplete-in.html
Also, please read the Official Google Places API Web Service:
https://developers.google.com/places/web-service/autocomplete
For iOS
[assembly: ExportRenderer(typeof(CustomAutoCompleteLocation), typeof(CustomAutoCompleteRenderer))]
namespace Aesthetic.iOS.Renderer
{
public class CustomAutoCompleteProfileRenderer : EntryRenderer
{
IntPtr inptr;
string tx = "1";
CustomAutoCompleteLocation _view;
Place place;
UITextField textView;
public UIWindow Window
{
get;
set;
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
_view = (CustomAutoCompleteLocation)Element;
if (Control != null)
{
textView = (UITextField)Control;
textView.Font = UIFont.FromName("Lato-Light", textView.Font.PointSize);
textView.BorderStyle = UITextBorderStyle.Line;
textView.Layer.BorderWidth = 1f;
textView.Layer.CornerRadius = 0f;
// do whatever you want to the textField here!
UIView paddingView = new UIView(new RectangleF(10, 16, 10, 16));
textView.LeftView = paddingView;
textView.LeftViewMode = UITextFieldViewMode.Always;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var x = sender as CustomAutoComplete;
if (e.PropertyName == "IsFocused")
{
if (tx == "1")
{
Device.BeginInvokeOnMainThread(() =>
{
Window = new UIWindow(UIScreen.MainScreen.Bounds);
var controller = new LocationViewController();
Window.RootViewController = controller;
// make the window visible
Window.MakeKeyAndVisible();
controller.PlaceSelected1 += HandlePlaceSelection;
});
tx = "2";
}
else if (tx == "2") tx = "3";
else if (tx == "3") tx = "4";
else if (tx == "4") tx = "1";
}
}
private void HandlePlaceSelection(object sender, string locationData)
{
textView.Text = locationData;
Window.Hidden = true;
}
}
}
And this is location view controller
public partial class LocationViewController : UIViewController
{
public delegate void PlaceSelected(object sender, string locationData);
UITextField txtLocation;
public UIView backgroundView;
// UITextView txtLocation;
UIImageView googleAttribution;
UITableView tableViewLocationAutoComplete;
public event PlaceSelected PlaceSelected1;
public string strSampleString { get; set; }
LocationPredictionClass objAutoCompleteLocationClass;
string strAutoCompleteQuery;
LocationAutoCompleteTableSource objLocationAutoCompleteTableSource;
public LocationViewController() : base()
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
FnInitializeView();
FnClickEventInit();
}
void FnInitializeView()
{
backgroundView = new UIView(View.Frame);
backgroundView.BackgroundColor = UIColor.White;
View.AddSubview(backgroundView);
txtLocation = new UITextField();
txtLocation.Frame = new CoreGraphics.CGRect(20, 20, View.Frame.Width-20, 45.0f);
txtLocation.TranslatesAutoresizingMaskIntoConstraints = false;
txtLocation.ReturnKeyType = UIReturnKeyType.Done;
txtLocation.BackgroundColor = UIColor.FromRGB(221,221,221);
txtLocation.TextColor = UIColor.Black;
View.AddSubview(txtLocation);
txtLocation.BecomeFirstResponder();
tableViewLocationAutoComplete = new UITableView();
tableViewLocationAutoComplete.Frame = new CoreGraphics.CGRect(txtLocation.Frame.X, txtLocation.Frame.Height+ txtLocation.Frame.Y, View.Frame.Width, View.Frame.Height - txtLocation.Frame.Height - txtLocation.Frame.Y);
tableViewLocationAutoComplete.BackgroundColor = UIColor.White;
tableViewLocationAutoComplete.Source = objLocationAutoCompleteTableSource;
View.AddSubview(tableViewLocationAutoComplete);
tableViewLocationAutoComplete.Hidden = false;
txtLocation.ShouldReturn += (textField) => textField.ResignFirstResponder();
StringBuilder builderLocationAutoComplete = new StringBuilder(Constants.strPlacesAutofillUrl);
builderLocationAutoComplete.Append("?input={0}").Append("&key=").Append(Constants.strGooglePlaceAPILey);
strAutoCompleteQuery = builderLocationAutoComplete.ToString();
builderLocationAutoComplete.Clear();
builderLocationAutoComplete = null;
}
void FnClickEventInit()
{
txtLocation.EditingChanged += async delegate (object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(txtLocation.Text))
{
tableViewLocationAutoComplete.Hidden = true;
}
else
{
if (txtLocation.Text.Length > 2)
{
//Autofill
string strFullURL = string.Format(strAutoCompleteQuery, txtLocation.Text);
objAutoCompleteLocationClass = await RestRequestClass.LocationAutoComplete(strFullURL);
if (objAutoCompleteLocationClass != null && objAutoCompleteLocationClass.status == "OK")
{
if (objAutoCompleteLocationClass.predictions.Count > 0)
{
if (objLocationAutoCompleteTableSource != null)
{
objLocationAutoCompleteTableSource.LocationRowSelectedEventAction -= LocationSelectedFromAutoFill;
objLocationAutoCompleteTableSource = null;
}
tableViewLocationAutoComplete.Hidden = false;
objLocationAutoCompleteTableSource = new LocationAutoCompleteTableSource(objAutoCompleteLocationClass.predictions);
objLocationAutoCompleteTableSource.LocationRowSelectedEventAction += LocationSelectedFromAutoFill;
tableViewLocationAutoComplete.Source = objLocationAutoCompleteTableSource;
tableViewLocationAutoComplete.ReloadData();
}
else
tableViewLocationAutoComplete.Hidden = true;
}
else
{
tableViewLocationAutoComplete.Hidden = true;
}
}
}
};
}
void LocationSelectedFromAutoFill(Prediction objPrediction)
{
DismissViewController(true, null);
Console.WriteLine(objPrediction.description);
PlaceSelected1(this, objPrediction.description);
txtLocation.ResignFirstResponder();
}
}
public class RestRequestClass
{
static async Task<string> CallService(string strURL)
{
WebClient client = new WebClient();
string strResult;
try
{
strResult = await client.DownloadStringTaskAsync(new Uri(strURL));
}
catch
{
strResult = "Exception";
}
finally
{
client.Dispose();
client = null;
}
return strResult;
}
internal static async Task<LocationPredictionClass> LocationAutoComplete(string strFullURL)
{
LocationPredictionClass objLocationPredictClass = null;
LocationPredictionClass objLocationPredictClass12 = new LocationPredictionClass();
objLocationPredictClass12.predictions = new List<Prediction>();
string strResult = await CallService(strFullURL);
if (strResult != "Exception")
{
objLocationPredictClass = JsonConvert.DeserializeObject<LocationPredictionClass>(strResult);
}
foreach (Prediction objPred in objLocationPredictClass.predictions)
{
if (objPred.types[0] == "country")
{
objLocationPredictClass12.predictions.Add(objPred);
objLocationPredictClass12.status = "OK";
}
}
// string[] strPredictiveText = new string[data.Count];
//int index = 0;
// foreach (Prediction objPred in data)
// {
// strPredictiveText[index] = objPred.description;
// index++;
// }
return objLocationPredictClass12;
}
}
public class MatchedSubstring
{
public int length { get; set; }
public int offset { get; set; }
}
public class Term
{
public int offset { get; set; }
public string value { get; set; }
}
public class Prediction
{
public string description { get; set; }
public string id { get; set; }
public List<MatchedSubstring> matched_substrings { get; set; }
public string place_id { get; set; }
public string reference { get; set; }
public List<Term> terms { get; set; }
public List<string> types { get; set; }
}
public class LocationPredictionClass
{
public List<Prediction> predictions { get; set; }
public string status { get; set; }
}
public class Constants
{
public static string strGooglePlaceAPILey = "AIzaSyBXJntNIs2aAvKIRwrgCEwOGwnigbSWep8";
public static string strPlacesAutofillUrl = "https://maps.googleapis.com/maps/api/place/autocomplete/json";
}
public class LocationAutoCompleteTableSource : UITableViewSource
{
const string strCellIdentifier = "Cell";
readonly List<Prediction> lstLocations;
internal event Action<Prediction> LocationRowSelectedEventAction;
public LocationAutoCompleteTableSource(List<Prediction> arrItems)
{
lstLocations = arrItems;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return lstLocations.Count;
}
public override UIView GetViewForFooter(UITableView tableView, nint section)
{
return new UIView();
}
public override UITableViewCell GetCell(UITableView tableView, Foundation.NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell(strCellIdentifier) ?? new UITableViewCell(UITableViewCellStyle.Default, strCellIdentifier);
cell.TextLabel.Text = lstLocations[indexPath.Row].description;
cell.TextLabel.Font = UIFont.SystemFontOfSize(12);
return cell;
}
public override void RowSelected(UITableView tableView, Foundation.NSIndexPath indexPath)
{
if (LocationRowSelectedEventAction != null)
{
LocationRowSelectedEventAction(lstLocations[indexPath.Row]);
}
tableView.DeselectRow(indexPath, true);
}
}
}

Convert objects to JSON in C#

I have a class:
public class StatististikaByCustomer
{
public string data { get; set; } // Array or String?
public string xkey {get;set;}
public Array ykey {get;set;}
public Array labels {get;set;}
}
How can I get JSON like this?
{
"data":[
{
"timeinterval":"2015-10-22T00:00:00",
"Firm":4,
"Firm1":4,
"Firm2":22,
"Firm3":30,
"Firm4":19
},
{
"timeinterval":"2015-10-23T00:00:00",
"Firm":2,
"Firm1":5,
"Firm2":29,
"Firm3":34,
"Firm4":219
}
],
"xkey":"timeinterval",
"ykey":["Firm","Firm1","Firm2","Firm3","Firm4"],
"labels":[" Firm","Firm1","Firm2","Firm3","Firm4"]
}
Firm cannot be hard coded. It all must be dynamic.
My Controller Action:
public JsonResult StatistikaJson()
{
ArrayList arrayList = new ArrayList();
StatistikaByCustomer statisikaObject = new StatistikaByCustomer();
List<Data> listData = new List<Data>();
string jsonTemp = null;
DbDataReader reader = null;
using (var cmd = db.Database.Connection.CreateCommand())
{
if (db.Database.Connection.State == ConnectionState.Closed)
{
db.Database.Connection.Open();
}
cmd.CommandText = "EXEC GetClientConnectsByCustomer #start='" + DateTime.Now.AddMonths(-1).Date.ToString("yyyy-MM-dd") + "',#end='" + DateTime.Now.Date.ToString("yyyy-MM-dd") + "',#interval = 24";
reader = cmd.ExecuteReader();
var tempYkey = Enumerable.Range(1, reader.FieldCount - 1).Select(reader.GetName).ToArray();
statisikaObject.ykey = tempYkey.Select(x => x.Replace(" ", "")).ToArray();
if (reader.HasRows)
{
while (reader.Read())
{
string name = reader.GetName(0);
object value = reader.GetDateTime(0);
listData.Add(new Data() { Name = name, Value = value });
for (int i = 1; i < reader.FieldCount - 1; i++)
{
name = reader.GetName(i).Replace(" ", "");
value = reader.GetInt32(i);
listData.Add(new Data() { Name = name, Value = value });
}
//arrayList.Add(JsonConvert.SerializeObject(listData.ToDictionary(x => x.Name, y => y.Value)));
jsonTemp += JsonConvert.SerializeObject(listData.ToDictionary(x => x.Name, y => y.Value));
jsonTemp += ",";
listData.Clear();
//Debug.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", reader.GetName(0), reader.GetDateTime(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3), reader.GetInt32(4));
}
}
else
{
Debug.WriteLine("No rows found.");
}
statisikaObject.xkey = reader.GetName(0);
statisikaObject.labels = Enumerable.Range(1, reader.FieldCount - 1).Select(reader.GetName).ToArray();
reader.Close();
//the number of affected records, if the query returns it var result = cmd.ExecuteNonQuery();
//or a single scalar value //var result = cmd.ExecuteScalar();
//or even a data reader var result = cmd.ExecuteReader();
db.Database.Connection.Close();
}
statisikaObject.data = oSerializer.Serialize(arrayList);
//string json = JsonConvert.SerializeObject(statisikaObject);
//string json = JsonConvert.SerializeObject(l);
return Json(statisikaObject, JsonRequestBehavior.AllowGet);
}
I get JSON, but it's escaped and morris.js doesn't like it.
In my view, I would like to use it like this:
<script type="text/javascript">
$.getJSON('#Url.Action("StatistikaJson")', function (result)
{
new Morris.Line({
element: 'line-example',
data: result.data,
xkey: "timeinterval",
ykeys: result.ykey,
labels: result.labels
});
});
</script>
I can use Json.NET if necessary. If posible, I would like to get ride off the JSON string appending. I would like to have an array and call serialize to get data: json objects in array format that morris.js needs: http://jsbin.com/uqawig/441/embed?js,output
{"data":"{"timeinterval":"2015-10-22T00:00:00","Firm":4,...},{"timeinterval":"2015-10-22T00:00:00","Firm":5,...},...}
ViewModel:
public class StatistikaByCustomer
{
public ArrayList data { get; set; }
public string xkey { get; set; }
public List<string> ykey { get; set; }
public List<string> labels { get; set; }
}
Controller:
public JsonResult StatistikaJson()
{
StatistikaByCustomer statisikaObject = new StatistikaByCustomer();
ArrayList arrayList = new ArrayList();
List<Data> listData = new List<Data>();
DbDataReader reader = null;
using (var cmd = db.Database.Connection.CreateCommand())
{
if (db.Database.Connection.State == ConnectionState.Closed)
{
db.Database.Connection.Open();
}
cmd.CommandText = "EXEC GetClientConnectsByCustomer #start='" + DateTime.Now.AddMonths(-1).Date.ToString("yyyy-MM-dd") + "',#end='" + DateTime.Now.Date.ToString("yyyy-MM-dd") + "',#interval = 24";
reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
string name = reader.GetName(0);
object value = reader.GetDateTime(0).ToString("yyyy-MM-dd");
listData.Add(new Data() { Name = name, Value = value });
for (int i = 1; i <= reader.FieldCount - 1; i++)
{
name = reader.GetName(i).Replace(" ", "");
value = reader.GetInt32(i);
listData.Add(new Data() { Name = name, Value = value });
}
arrayList.Add(JsonConvert.SerializeObject(listData.ToDictionary(x => x.Name, y => y.Value)));
listData.Clear();
//Debug.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", reader.GetName(0), reader.GetDateTime(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3), reader.GetInt32(4));
}
}
statisikaObject.data = arrayList;
statisikaObject.xkey = reader.GetName(0);
statisikaObject.labels = Enumerable.Range(1, reader.FieldCount - 1).Select(reader.GetName).ToList();
var tempYkey = Enumerable.Range(1, reader.FieldCount - 1).Select(reader.GetName).ToArray();
statisikaObject.ykey = tempYkey.Select(x => x.Replace(" ", "")).ToList();
reader.Close();
db.Database.Connection.Close();
}
return Json(statisikaObject, JsonRequestBehavior.AllowGet);
}
View:
<script type="text/javascript">
$.getJSON('#Url.Action("StatistikaJson")', function (result)
{
new Morris.Line({
element: 'line-example',
data: $.parseJSON("[" + result.data + "]"),
xkey: result.xkey,
ykeys: result.ykey,
labels: result.labels
});
});
</script>
public class Datum
{
public string timeinterval { get; set; }
public int Firm { get; set; }
public int Firm1 { get; set; }
public int Firm2 { get; set; }
public int Firm3 { get; set; }
public int Firm4 { get; set; }
}
public class RootObject
{
public List<Datum> data { get; set; }
public string xkey { get; set; }
public List<string> ykey { get; set; }
public List<string> labels { get; set; }
}
By putting this code get Serialize json string
var collection = new List<RootObject>();
dynamic collectionWrapper = new
{
people = new RootObject()
{
xkey = "timeinterval",
data = new List<Datum>
{
new Datum()
{
timeinterval = "2015-10-22T00: 00: 00",
Firm = 4,
Firm1= 4,
Firm2= 22,
Firm3= 30,
Firm4= 19
},
new Datum()
{
timeinterval = "2015-10-23T00: 00: 00",
Firm = 2,
Firm1= 5,
Firm2= 29,
Firm3= 34,
Firm4= 219
}
},
ykey = new List<string> { "Firm", "Firm1", "Firm2", "Firm3", "Firm4" },
labels = new List<string> { "Firm", "Firm1", "Firm2", "Firm3", "Firm4" }
}
};
var output = JsonConvert.SerializeObject(collectionWrapper);
Edit:
var collection = new StatististikaByCustomer
{
xkey = "timeinterval",
ykey = new List<string>{"Firm","Firm1","Firm2","Firm3","Firm4"},
labels = new List<string> { "Firm", "Firm1", "Firm2", "Firm3", "Firm4" },
data = new Dictionary<string, string>
{
{ "timeinterval", "2015-10-22T00: 00: 00" },
{ "Firm", "4" },
{ "Firm1", "4" },
{ "Firm2", "22" },
{ "Firm3", "30" },
{ "Firm4", "19" }
}
};
string json = JsonConvert.SerializeObject(collection);
Class:
public class StatististikaByCustomer
{
public string xkey { get; set; }
public Dictionary<string, string> data { get; set; }
public List<string> ykey { get; set; }
public List<string> labels { get; set; }
}
Update:
var collection = new StatististikaByCustomer
{
xkey = "timeinterval",
ykey = new List<string> { "Firm", "Firm1", "Firm2", "Firm3", "Firm4" },
labels = new List<string> { "Firm", "Firm1", "Firm2", "Firm3", "Firm4" },
data = new List<Dictionary<string,string>>
{
new Dictionary<string, string>
{
{ "timeinterval", "2015-10-22T00: 00: 00" },
{ "Firm", "4" },
{ "Firm1", "4" },
{ "Firm2", "22" },
{ "Firm3", "30" },
{ "Firm4", "19" }
},
new Dictionary<string, string>
{
{ "timeinterval", "2015-10-23T00: 00: 00" },
{ "Firm", "2" },
{ "Firm1", "5" },
{ "Firm2", "29" },
{ "Firm3", "34" },
{ "Firm4", "219" }
}
}
};
string json = JsonConvert.SerializeObject(collection);
Class:
public class StatististikaByCustomer
{
public string xkey { get; set; }
public List<Dictionary<string, string>> data { get; set; }
public List<string> ykey { get; set; }
public List<string> labels { get; set; }
}

why I see validation messages before form submiting

I've created a form and when I load the page with it I see validation messages before I submit the form. Why? You can download my code from github
The similar question. It's because of mvc4
#model MyMustAgreeValidation.Models.NewUserProfileModel
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
#Html.MyEditFor(m=>m.Login)
#Html.MyEditFor(m=>m.Password)
#Html.MyEditFor(m=>m.ConfirmPassword)
#Html.MyEditFor(m=>m.DisplayName)
#Html.MyEditFor(m=>m.Email)
#Html.MyEditFor(m=>m.Homepage)
#Html.MyEditFor(m=>m.AgreementAccepted)
<p><input type="submit" value="#CreateRes.CreateProfileButton"/></p>
</fieldset>
}
Where Html.MyEditFor is
public static MvcHtmlString MyEditFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression)
{
return html.Partial("Item", new LabelEditorValidation() { Label = html.LabelFor(expression), Editor = html.EditorFor(expression), Validation = html.ValidationMessageFor(expression) });
}
And Item is partial view:
#model MyMustAgreeValidation.Models.LabelEditorValidation
<div class="editor-label">
#Model.Label
</div>
<div class="editor-field">
#Model.Editor
#Model.Validation
</div>
LabelEditorValidation:
public class LabelEditorValidation
{
public MvcHtmlString Label { get; set; }
public MvcHtmlString Editor { get; set; }
public MvcHtmlString Validation { get; set; }
}
Scripts included:
<script src="/Scripts/jquery-1.7.1.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="/Scripts/Validation/EqualAttribute.js"></script>
Form model NewUserProfileModel:
public class NewUserProfileModel : UserProfileModel, IValidatableObject
{
[Display(Name="Password", ResourceType = typeof(NewUserProfileRes))]
[DataType(DataType.Password)]
[Required(ErrorMessageResourceName = "FieldIsRequired", ErrorMessageResourceType = typeof(ErrorsRes))]
[StringLengthRange(6, 64, ErrorMessageResourceType = typeof(ErrorsRes), ErrorMessageResourceName = "InvalidStringLength")]
public string Password { get; set; }
[Display(Name="ConfirmPassword", ResourceType = typeof(NewUserProfileRes))]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessageResourceType = typeof(NewUserProfileRes), ErrorMessageResourceName = "PasswordsDontMatch")]
public string ConfirmPassword { get; set; }
[Display(Name="AgreementAccepted", ResourceType = typeof(NewUserProfileRes))]
[Equal(true, ErrorMessageResourceType = typeof(NewUserProfileRes), ErrorMessageResourceName = "MustAgreeWithEULA")]
public bool AgreementAccepted { get; set; }
public NewUserProfileModel()
{
var property = GetType().GetProperty("Login");
var list = property.GetCustomAttributes(true);
foreach (var item in list)
{
Console.WriteLine(item);
}
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var userRepository = new UserRepository();
if (userRepository.IsLoginExists(Login))
{
yield return new ValidationResult(NewUserProfileRes.LoginAlreadyExists, new []{"Login"});
}
}
UserProfileModel:
public class UserProfileModel
{
[Display(Name = "Login", ResourceType = typeof(UserProfileRes))]
[DataType(DataType.Text)]
[Required(ErrorMessageResourceName = "FieldIsRequired", ErrorMessageResourceType = typeof(ErrorsRes))]
[StringLengthRange(3, 64, ErrorMessageResourceName = "InvalidStringLength", ErrorMessageResourceType = typeof(ErrorsRes))]
public string Login { get; set; }
[Display(Name="DisplayName", ResourceType = typeof(UserProfileRes))]
[DataType(DataType.Text)]
[Required(ErrorMessageResourceName = "FieldIsRequired",
ErrorMessageResourceType = typeof(ErrorsRes))]
[StringLengthRange(3, 32,
ErrorMessageResourceName = "InvalidStringLength",
ErrorMessageResourceType = typeof(ErrorsRes))]
public string DisplayName { get; set; }
[Display(Name = "Email", ResourceType = typeof(UserProfileRes))]
[DataType(DataType.EmailAddress)]
[Required(ErrorMessageResourceType = typeof(ErrorsRes), ErrorMessageResourceName = "FieldIsRequired")]
[RegularExpression(#"[\w\.-]*[a-zA-Z0-9_]#[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]", ErrorMessageResourceType = typeof(ErrorsRes), ErrorMessageResourceName = "InvalidEmailAddress")]
[StringLength(64, ErrorMessageResourceType = typeof(ErrorsRes), ErrorMessageResourceName = "StringTooLong")]
public string Email { get; set; }
[Display(Name="Homepage", ResourceType = typeof(UserProfileRes))]
[DataType(DataType.Url)]
[RegularExpression(#"(http(s)?://)?([\w-]+\.)+[\w-]+(/[\w- ;,./?%&=]*)?", ErrorMessageResourceType = typeof(ErrorsRes), ErrorMessageResourceName = "IvalidUrl")]
[StringLength(96,
ErrorMessageResourceType = typeof(ErrorsRes), ErrorMessageResourceName = "StringTooLong")]
public string Homepage { get; set; }
}
EqualAttribute.js:
jQuery.validator.addMethod("equal", function (value, element, param) {
if($(element).attr("type")=="checkbox")
{
value = String($(element).attr("checked"));
param = param.toLowerCase();
}
return (value == param);
});
jQuery.validator.unobtrusive.adapters.addSingleVal("equal", "valuetocompare");