how to show a alert if table is empty? - mudblazor

I want to show a alert if table is empty, problem is that i have to click twice before he is hitting
the else statement to show my alert.
I use a overlay to show the devices.
I tried OnafterrenderAsync, OnInitializedAsync, OnParameterSetAsync
If the api call gets devices than there is no problem, the table is loading but if there is no data in the table he doesn't go to the else statement to show my mudalert
<PageTitle>#AccountResource.DevicesLinkLabel</PageTitle>
#if (isLoading)
{
}
else
{
#if (!isShowing)
{
<MudTable T="DeviceModel" ServerData="#(new Func<TableState, Task<TableData<DeviceModel>>>(LoadData))" Hover="true" Breakpoint="Breakpoint.Sm" Dense="true" #ref="table">
<HeaderContent>
<MudTh>#AccountResource.DevicesLinkLabel</MudTh>
<MudTh>#SharedResource.Type</MudTh>
<MudTh>#SharedResource.Version</MudTh>
<MudTh>#SharedResource.VersionAppNumber</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="DeviceName">#context.DisplayName</MudTd>
<MudTd DataLabel="DeviceType">#context.Type</MudTd>
<MudTd DataLabel="DeviceVersion">#context.Version</MudTd>
<MudTd DataLabel="DeviceVersionAppNumber">#context.VersionAppNumber</MudTd>
</RowTemplate>
<PagerContent>
<MudTablePager />
</PagerContent>
</MudTable>
}
else
{
<MudAlert Severity="MudBlazor.Severity.Warning">#SharedResource.NothingToShow</MudAlert>
}
}
#code {
[Parameter]
public long UserId { get; set; }
[Parameter]
public long OrganisationId { get; set; }
[Parameter]
public EventCallback<ModelBase> ShowResponseInToast { get; set; }
private MudTable<DeviceModel>? table;
private bool isLoading = true;
private bool isShowing;
protected override async Task OnParametersSetAsync()
{
try
{
if (table != null)
{
//table.CurrentPage = 0;s
await table.ReloadServerData();
}
}
finally
{
isLoading = false;
}
}
private async Task<TableData<DeviceModel>> LoadData(TableState state)
{
var request = new GetDeviceRequest
{
OrganisationId = OrganisationId,
UserId = UserId,
Page = state.Page,
PageSize = state.PageSize,
};
var response = await DeviceManagerClient.GetDeviceResponseAsync(request);
if (table?.Items?.Any() == true)
{
isShowing = false;
return new TableData<DeviceModel>
{
Items = response.Results,
TotalItems = response.TotalCount
};
}
else
{
isShowing = true;
return new TableData<DeviceModel>
{
Items = response.Results,
};
}
}
}

Related

how to implement Android In App BillingClient in Xamarin.Android Asynchronously

I am trying to implement below java code in c# referring to Android documentation
List<String> skuList = new ArrayList<> ();
skuList.add("premium_upgrade");
skuList.add("gas");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
#Override
public void onSkuDetailsResponse(BillingResult billingResult,
List<SkuDetails> skuDetailsList) {
// Process the result.
}
});
I have here 2 questions. I thought that i would run this code on a separate thread than UI thread like below to keep my ui responsive while network connection is done. is that the correct approach? QuerySkuDetailsAsync is called async but doesnt implement as async. how should this be working and how to handle in c# because it will fire and forget but Listener to handle the response.
public async Task<List<InAppBillingProduct>> GetProductsAsync(List<string> ProductIds)
{
var getSkuDetailsTask = Task.Factory.StartNew(() =>
{
var prms = SkuDetailsParams.NewBuilder();
var type = BillingClient.SkuType.Inapp;
prms.SetSkusList(ProductIds).SetType(type);
BillingClient.QuerySkuDetailsAsync(prms.Build(), new SkuDetailsResponseListener());
return InAppBillingProducts;
});
return await getSkuDetailsTask;
}
2nd question regarding how to handle with the listener as below. How do I return value from the listener. I need return list of InAppBillingProduct object.
public class SkuDetailsResponseListener : Java.Lang.Object, ISkuDetailsResponseListener
{
public void OnSkuDetailsResponse(BillingResult billingResult, IList<SkuDetails> skus)
{
if (billingResult.ResponseCode == BillingResponseCode.Ok)
{
// get list of Products here and return
}
}
}
FYI. This is how I did it. This is not a complete code but this will give you and idea.
Listener - PCL
============
private async Task EventClicked()
{
var skuList = new List<string>();
skuList.Add("[nameofsubscriptionfoundinyourgoogleplay]");
if (await _billingClientLifecycle.Initialize(skuList, DisconnectedConnection))
{
var firstProduct = _billingClientLifecycle?.ProductsInStore?.FirstOrDefault();
if (firstProduct != null)
{
//purchase here
}
}
}
private void DisconnectedConnection()
{
//Todo.alfon. handle disconnection here...
}
Interface - PCL
===========
public interface IInAppBillingMigratedNew
{
List<InAppBillingPurchase> PurchasedProducts { get; set; }
List<InAppBillingProduct> ProductsInStore { get; set; }
Task<bool> Initialize(List<String> skuList, Action onDisconnected = null);
}
Dependency - Platform Droid
===============
[assembly: XF.Dependency(typeof(InAppBillingMigratedNew))]
public class InAppBillingMigratedNew : Java.Lang.Object, IBillingClientStateListener
, ISkuDetailsResponseListener, IInAppBillingMigratedNew
{
private Activity Context => CrossCurrentActivity.Current.Activity
?? throw new NullReferenceException("Current Context/Activity is null");
private BillingClient _billingClient;
private List<string> _skuList = new List<string>();
private TaskCompletionSource<bool> _tcsInitialized;
private Action _disconnectedAction;
private Dictionary<string, SkuDetails> _skusWithSkuDetails = new Dictionary<string, SkuDetails>();
public List<InAppBillingPurchase> PurchasedProducts { get; set; }
public List<InAppBillingProduct> ProductsInStore { get; set; }
public IntPtr Handle => throw new NotImplementedException();
public Task<bool> Initialize(List<string> skuList, Action disconnectedAction = null)
{
_disconnectedAction = disconnectedAction;
_tcsInitialized = new TaskCompletionSource<bool>();
var taskInit = _tcsInitialized.Task;
_skuList = skuList;
_billingClient = BillingClient.NewBuilder(Context)
.SetListener(this)
.EnablePendingPurchases()
.Build();
if (!_billingClient.IsReady)
{
_billingClient.StartConnection(this);
}
return taskInit;
}
#region IBillingClientStateListener
public void OnBillingServiceDisconnected()
{
Console.WriteLine($"Connection disconnected.");
_tcsInitialized?.TrySetResult(false);
_disconnectedAction?.Invoke();
}
public void OnBillingSetupFinished(BillingResult billingResult)
{
var responseCode = billingResult.ResponseCode;
var debugMessage = billingResult.DebugMessage;
if (responseCode == BillingResponseCode.Ok)
{
QuerySkuDetails();
QueryPurchases();
_tcsInitialized?.TrySetResult(true);
}
else
{
Console.WriteLine($"Failed connection {debugMessage}");
_tcsInitialized?.TrySetResult(false);
}
}
#endregion
#region ISkuDetailsResponseListener
public void OnSkuDetailsResponse(BillingResult billingResult, IList<SkuDetails> skuDetailsList)
{
if (billingResult == null)
{
Console.WriteLine("onSkuDetailsResponse: null BillingResult");
return;
}
var responseCode = billingResult.ResponseCode;
var debugMessage = billingResult.DebugMessage;
switch (responseCode)
{
case BillingResponseCode.Ok:
if (skuDetailsList == null)
{
_skusWithSkuDetails.Clear();
}
else
{
if (skuDetailsList.Count > 0)
{
ProductsInStore = new List<InAppBillingProduct>();
}
foreach (var skuDetails in skuDetailsList)
{
_skusWithSkuDetails.Add(skuDetails.Sku, skuDetails);
//ToDo.alfon. make use mapper here
ProductsInStore.Add(new InAppBillingProduct
{
Name = skuDetails.Title,
Description = skuDetails.Description,
ProductId = skuDetails.Sku,
CurrencyCode = skuDetails.PriceCurrencyCode,
LocalizedIntroductoryPrice = skuDetails.IntroductoryPrice,
LocalizedPrice = skuDetails.Price,
MicrosIntroductoryPrice = skuDetails.IntroductoryPriceAmountMicros,
MicrosPrice = skuDetails.PriceAmountMicros
});
}
}
break;
case BillingResponseCode.ServiceDisconnected:
case BillingResponseCode.ServiceUnavailable:
case BillingResponseCode.BillingUnavailable:
case BillingResponseCode.ItemUnavailable:
case BillingResponseCode.DeveloperError:
case BillingResponseCode.Error:
Console.WriteLine("onSkuDetailsResponse: " + responseCode + " " + debugMessage);
break;
case BillingResponseCode.UserCancelled:
Console.WriteLine("onSkuDetailsResponse: " + responseCode + " " + debugMessage);
break;
// These response codes are not expected.
case BillingResponseCode.FeatureNotSupported:
case BillingResponseCode.ItemAlreadyOwned:
case BillingResponseCode.ItemNotOwned:
default:
Console.WriteLine("onSkuDetailsResponse: " + responseCode + " " + debugMessage);
break;
}
}
#endregion
#region Helper Methods Private
private void ProcessPurchases(List<Purchase> purchasesList)
{
if (purchasesList == null)
{
Console.WriteLine("No purchases done.");
return;
}
if (IsUnchangedPurchaseList(purchasesList))
{
Console.WriteLine("Purchases has not changed.");
return;
}
_purchases.AddRange(purchasesList);
PurchasedProducts = _purchases.Select(sku => new InAppBillingPurchase
{
PurchaseToken = sku.PurchaseToken
})?.ToList();
if (purchasesList != null)
{
LogAcknowledgementStatus(purchasesList);
}
}
private bool IsUnchangedPurchaseList(List<Purchase> purchasesList)
{
// TODO: Optimize to avoid updates with identical data.
return false;
}
private void LogAcknowledgementStatus(List<Purchase> purchasesList)
{
int ack_yes = 0;
int ack_no = 0;
foreach (var purchase in purchasesList)
{
if (purchase.IsAcknowledged)
{
ack_yes++;
}
else
{
ack_no++;
}
}
//Log.d(TAG, "logAcknowledgementStatus: acknowledged=" + ack_yes +
// " unacknowledged=" + ack_no);
}
private void QuerySkuDetails()
{
var parameters = SkuDetailsParams
.NewBuilder()
.SetType(BillingClient.SkuType.Subs)
.SetSkusList(_skuList)
.Build();
_billingClient.QuerySkuDetailsAsync(parameters, this);
}
private void QueryPurchases()
{
if (!_billingClient.IsReady)
{
Console.WriteLine("queryPurchases: BillingClient is not ready");
}
var result = _billingClient.QueryPurchases(BillingClient.SkuType.Subs);
ProcessPurchases(result?.PurchasesList?.ToList());
}
#endregion
}

Accessing elements of types with runtime indexers using expression trees

I want to validate rule against input array data with runtime indexer not with some fixed zero index value.
It works if i insert data one by one in session.Insert()
It does't work if i use sesion.InsertAll() with array data
I tried providing Expression.Constant value to indexer but no action triggers
class Program
{
static void Main(string[] args)
{
RuleTestWithSingleInsertData();
// RuleTestWithInsertDataAll();
Console.ReadKey();
}
public static void RuleTestWithSingleInsertData()
{
try
{
CustomRuleRepository repository = new CustomRuleRepository();
List<RuleEngineEntity> rules = new List<RuleEngineEntity>();
rules.Add(new RuleEngineEntity { FieldName = "Age", Name = "CustomerCheck", Value = 25 });
repository.LoadRuleForTest1(rules.FirstOrDefault());
//Compile rules
var factory = repository.Compile();
//Create a working session
var session = factory.CreateSession();
RuleEngineRequestModel ruleEngineRequestModel = new RuleEngineRequestModel
{
ruleList = rules,
customerData = new List<Customer>() { new Customer { Name = "A", Age = 19 },
new Customer { Name = "B", Age = 26 } }.ToArray()
};
session.InsertAll(ruleEngineRequestModel.customerData);
var IspassedorNot = session.Fire();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public static void RuleTestWithInsertDataAll()
{
try
{
CustomRuleRepository repository = new CustomRuleRepository();
List<RuleEngineEntity> rules = new List<RuleEngineEntity>();
rules.Add(new RuleEngineEntity { FieldName = "Age", Name = "CustomerCheck", Value = 25 });
repository.LoadRuleForTest2(rules.FirstOrDefault());
//Compile rules
var factory = repository.Compile();
//Create a working session
var session = factory.CreateSession();
RuleEngineRequestModel ruleEngineRequestModel = new RuleEngineRequestModel
{
ruleList = rules,
customerData = new List<Customer>() { new Customer { Name = "A", Age = 28 },
new Customer { Name = "B", Age = 26 } }.ToArray()
};
session.InsertAll(ruleEngineRequestModel.customerData);
var IspassedorNot = session.Fire();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
public class RuleEngineRequestModel
{
public List<RuleEngineEntity> ruleList { get; set; }
public Customer[] customerData { get; set; }
public List<Customer> customerDataList { get; set; }
}
public class RuleEngineEntity
{
public string Name { get; set; }
public int Value { get; set; }
public string Operator { get; set; }
public string FieldName { get; set; }
public bool SendEmail { get; set; }
}
public class Customer
{
public string Name { get; set; }
public int Age { get; set; }
}
public class CustomRuleRepository : IRuleRepository
{
private readonly IRuleSet _ruleSet = new RuleSet("customerRule");
public IEnumerable<IRuleSet> GetRuleSets()
{
return new[] { _ruleSet };
}
public void LoadRuleForTest1(RuleEngineEntity rule)
{
_ruleSet.Add(BuildRuleForTest1(rule));
}
public void LoadRuleForTest2(RuleEngineEntity rule)
{
_ruleSet.Add(BuildRuleForTest2(rule));
}
public List<IRuleDefinition> BuildRuleForTest1(RuleEngineEntity rule)
{
return Test1(rule);
}
public List<IRuleDefinition> BuildRuleForTest2(RuleEngineEntity rule)
{
return Test2(rule);
}
public List<IRuleDefinition> Test1(RuleEngineEntity rule)
{
RuleBuilder builder = new RuleBuilder();
builder.Name("DefaultRules");
try
{
var modelPattern = builder.LeftHandSide().Pattern(typeof(Customer), "CustomerCheck");
var modelParameter = modelPattern.Declaration.ToParameterExpression();
var expres = Expression.Property(modelParameter, rule.FieldName);
var binaryExpression = Expression.GreaterThan(expres, Expression.Constant(rule.Value));
LambdaExpression expressionCondition = Expression.Lambda(binaryExpression,
modelParameter);
modelPattern.Condition(expressionCondition);
Expression<Action<IContext, Customer, RuleEngineEntity>> action =
(ctx, CustomerCheck, rules) => FireActionAsync(ctx, CustomerCheck, rules);
builder.RightHandSide().Action(action);
}
catch (Exception e)
{
// throw new Exception(e.Message);
}
var buildRule = builder.Build();
return new List<IRuleDefinition> { buildRule };
}
public List<IRuleDefinition> Test2(RuleEngineEntity rule)
{
RuleBuilder builder = new RuleBuilder();
builder.Name("DefaultRules");
try
{
var modelPattern = builder.LeftHandSide().Pattern(typeof(RuleEngineRequestModel), "CustomerCheck");
var modelParameter = modelPattern.Declaration.ToParameterExpression();
var customerDataInArray = Expression.Property(modelParameter, nameof(RuleEngineRequestModel.customerData));
var indx = Expression.Parameter(typeof(int), "index");
var customerData = Expression.ArrayIndex(customerDataInArray, indx);
var expres = Expression.Property(customerData, rule.FieldName);
var binaryExpression = Expression.GreaterThan(expres, Expression.Constant(rule.Value));
LambdaExpression expressionCondition = Expression.Lambda(binaryExpression,
modelParameter);
modelPattern.Condition(expressionCondition);
Expression<Action<IContext, Customer>> action =
(ctx, CustomerCheck) => FireActionAsync(ctx, CustomerCheck, null);
builder.RightHandSide().Action(action);
}
catch (Exception e)
{
// throw new Exception(e.Message);
}
var buildRule = builder.Build();
return new List<IRuleDefinition> { buildRule };
}
public void FireActionAsync(IContext ctx, Customer customer, RuleEngineEntity rule=null)
{
Console.WriteLine($"{rule.Name} Triggered");
}
}
Error: variable 'index' of type 'System.Int32' referenced from scope '', but it is not defined
Expected: want to validate rule against array data with dynamic indexer.
At a quick glance, it appears that you are passing in an array of Customers when inserting the facts into the session, but the rule is looking for the RuleEngineRequestModel.
Also, side note - why are you initialising an array as a List, then converting to an array, rather than just initialising as an array? i.e.
var ruleEngineRequestModel = new RuleEngineRequestModel
{
ruleList = rules,
customerData = {
new Customer { Name = "A", Age = 28 },
new Customer { Name = "B", Age = 26 }
}
};
Finally, why are you inserting the rules at the same time as the data? That seems like it would cause more headaches than benefits, especially seeing as your runtime rule builder ignores them entirely.
EDIT: Having had a chance to see the updated code, this confirms my suspicions - if you use Rule 1 for both tests, it should work (rather, it will fire for each individual customer). The reason why Rule 2 never works is because it's expecting a RuleEngineRequestModel, but you are passing the IEnumerable in directly. Either pass in the request model directly and continue to use Rule 2, or scrap Rule 2 entirely.

Permission Contacts in Xamarin Forms iOS

I met an error display when I tried to access user contact to fetch all contacts: The splash screen hide the permission dialog.
Did anyone meet this error before?
Interface:
public interface IUserContactsService
{
List<PhoneContactInfo> GetAllPhoneContacts(IEnumerable<int> filterIds = null);
}
UserContactService.cs:
[assembly: Dependency(typeof(UserContactService))]
namespace Test.iOS
{
public class PhoneContact
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string Name { get => $"{FirstName} {LastName}"; }
}
public class UserContactService : IUserContactsService
{
string phoneNumber(string number)
{
string callNumber = number;
int i = 0;
while (i < callNumber.Length)
{
if (callNumber[i] == ' ' || callNumber[i] == 160 || callNumber[i] == '-')
callNumber = callNumber.Remove(i, 1);
else
i++;
}
return callNumber;
}
public List<PhoneContactInfo> GetAllPhoneContacts(IEnumerable<int> filterIds = null)
{var keysTOFetch = new[] { CNContactKey.GivenName, CNContactKey.FamilyName, CNContactKey.EmailAddresses };
NSError error;
CNContact[] contactList;
var ContainerId = new CNContactStore().DefaultContainerIdentifier;
using (var predicate = CNContact.GetPredicateForContactsInContainer(ContainerId))
using (var store = new CNContactStore())
{
contactList = store.GetUnifiedContacts(predicate, keysTOFetch, out error);
}
var contacts = new List<PhoneContactInfo>();
foreach (var item in contactList)
{
if (null != item && null != item.EmailAddresses)
{
contacts.Add(new PhoneContactInfo
{
contactName = item.GivenName,
contactNumber = item.PhoneNumbers.ToString()
});
}
}
return contacts;
}
}
Here is my solution:
public List<PhoneContactInfo> GetAllPhoneContacts (IEnumerable<int> filterIds = null)
{
// if the app was not authorized then we need to ask permission
if (ABAddressBook.GetAuthorizationStatus() == ABAuthorizationStatus.Authorized)
{
GetContacts();
}
else Console.WriteLine("Error");
}

Does the IClientValidator support input file?

Edit
I found that the problem is that View Components are unable to have an #section (see ViewComponent and #Section #2910 ) so adding custom client-side validation using the unobtrusive library seems imposible (or very complex). Moreover, the inability of including the required javascript into a View Component makes me regret of following this approach to modularize my app in the first place...
I am learning to make custom validation attributes with client-side support. I was able to implement a custom validator for a string property and it works pretty well, but when I tried to make one for input file it doesn't work (i.e. when I select a file in my computer, the application doesn't display the validation messages. The server-side validation works. Here is some code that shows my implementation.
The class of the model
public class UploadPanelModel
{
public int? ID { get; set; }
public string Title { get; set; }
public string Description { get; set; } //Raw HTML with the panel description
[FileType(type: "application/pdf")]
[FileSize(maxSize: 5000000)]
public IFormFile File { get; set; }
public byte[] FileBytes { get; set; }
public ModalModel Modal { get; set; } //Only used if the Upload panel uses a modal.
The validator
public class FileSizeAttribute : ValidationAttribute, IClientModelValidator
{
private long _MaxSize { get; set; }
public FileSizeAttribute (long maxSize)
{
_MaxSize = maxSize;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
UploadPanelModel panel = (UploadPanelModel)validationContext.ObjectInstance;
return (panel.File==null || panel.File.Length <= _MaxSize) ? ValidationResult.Success : new ValidationResult(GetFileSizeErrorMessage(_MaxSize));
}
private string GetFileSizeErrorMessage(long maxSize)
{
double megabytes = maxSize / 1000000.0;
return $"El archivo debe pesar menos de {megabytes}MB";
}
public void AddValidation(ClientModelValidationContext context)
{
if(context == null)
{
throw new ArgumentNullException(nameof(context));
}
MergeAttribute(context.Attributes, "data-val", "true");
MergeAttribute(context.Attributes, "data-val-filesize", GetFileSizeErrorMessage(_MaxSize));
var maxSize = _MaxSize.ToString();
MergeAttribute(context.Attributes, "data-val-filesize-maxsize", maxSize);
}
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
}
The javascript in the Razor View
#section Scripts{
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
$.validator.addMethod('filesize',
function (value, element, params) {
var size = $((params[0]).val()).size(),
maxSize = params[1];
if (size < maxSize) {
return false;
}
else {
return false;
}
}
);
$.validator.unobtrusive.adapters.add('filesize',
['maxSize'],
function (options) {
var element = $(options.form).find('input#File')[0];
options.rules['filesize'] = [element, options.params['maxSize']];
options.messages['filesize'] = options.message;
}
);
</script>
I always return false in the javascript method to force the application to show the validation error regardless the chosen file, but it still doesn't work.
Your addMethod() function will be throwing an error because params[0] is not a jQuery object and has no .val() (you also have the $ in the wrong place). You would need to use
var size = params[0].files[0].size;
However I suggest you write you scripts as
$.validator.unobtrusive.adapters.add('filesize', ['maxsize'], function (options) {
options.rules['filesize'] = { maxsize: options.params.maxsize };
if (options.message) {
options.messages['filesize'] = options.message;
}
});
$.validator.addMethod("filesize", function (value, element, param) {
if (value === "") {
return true;
}
var maxsize = parseInt(param.maxsize);
if (element.files != undefined && element.files[0] != undefined && element.files[0].size != undefined) {
var filesize = parseInt(element.files[0].size);
return filesize <= maxsize ;
}
return true; // in case browser does not support HTML5 file API
});

PetaPoco returns empty object

Inside my applocation, the petapoco poco returns an empty object (all values are null). Using the UI-O-Matic Nuget package inside my Umbraco 7.5.12.
The query i'm currently running:
var dbContext = ApplicationContext.Current.DatabaseContext;
var objects = dbContext.Database.Fetch<ObjectDB>("select Id, Name, CreatedOn, PlaceId, InActive, CityMapping, CountryIsoMapping, Globalsearch from ObjectsDB");
return objects.Where(n => n.PlaceId == PlaceId).FirstOrDefault();
TableDB is my PetaPoco model with the fields like:
[UIOMatic("ObjectsDB", "Object", "Object", FolderIcon = "icon-globe-inverted-europe-africa", ItemIcon = "icon-pin-location", RenderType = UIOMaticRenderType.List)]
[TableName("ObjectsDB")]
[PrimaryKey("Id", autoIncrement = false)]
[ExplicitColumns]
public class ObjectDB
{
[PrimaryKeyColumn(AutoIncrement = true)]
public int Id { get; set; }
[UIOMaticListViewFilter]
[UIOMaticListViewField(Name = "Name")]
[UIOMaticField(Name = "Name", Description = "Name")]
public string Name { get; set; }
}
When debuging:
`Debug result: con.Single<ObjectsDB>("select Name, Id from ObjectsDB where Id = 4")
This retruns the object:
{Umbraco.Extensions.Models.Custom.ObjectsModel.ObjectsDB} _createdOn: {1/1/0001 12:00:00 AM}
CityMapping: null
CountryIsoMapping: null
CreatedOn: {5/19/2017 4:22:16 PM}
Globalsearch: false
Id: 0
InActive: false
InCache: false
Name: null
Object: null
PlaceId: null `
Inserting data is working with the same dbContext, that's working.
What am I missing here?
I have used Petapoco in various Umbraco project and my approach is a bit different than your approach. I am sharing it here, hope it helps you.
This is the nuget package that I have used:(http://nuget.org/List/Packages/PetaPoco)
Please see my sample code below or in my blog:
[PetaPoco.TableName("fsCarts")]
[PetaPoco.PrimaryKey("RecordID")]
public class Cart
{
[Key]
public int RecordId { get; set; }
public string CartId { get; set; }
public Guid ProductId { get; set; }
public int Count { get; set; }
public DateTime DateCreated { get; set; }
}
UmbracoDatabase con = ApplicationContext.Current.DatabaseContext.Database;
public void AddToCart(Product product)
{
try
{
var cartItem = con.FirstOrDefault<Cart>("SELECT * FROM fsCarts WHERE CartID=#0 AND ProductID=#1", ShoppingCardId, product.ProductId);
if (cartItem == null)
{
cartItem = new Cart
{
ProductId = product.ProductId,
CartId = ShoppingCardId,
Count = 1,
DateCreated = DateTime.Now
};
con.Insert("fsCarts", "RecordID", cartItem);
}
else
{
cartItem.Count++;
con.Update("fsCarts", "RecordID", cartItem);
}
}
catch (Exception ex)
{
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception("Shopping Cart AddToCart: " + ex.ToString())));
}
}
////////////////////
public int RemoveFromCart(int id)
{
int itemCount = 0;
try
{
var cartItem = con.FirstOrDefault<Cart>("SELECT * FROM fsCarts WHERE CartID=#0 AND RecordId=#1", ShoppingCardId, id);
if (cartItem != null)
{
if (cartItem.Count > 1)
{
cartItem.Count--;
itemCount = cartItem.Count;
con.Update("fsCarts", "RecordID", cartItem);
}
else
{
con.Delete("fsCarts", "RecordID", cartItem);
}
}
}
catch (Exception ex)
{
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception("Shopping Cart RemoveFromCart: " + ex.ToString())));
}
return itemCount;
}
////////////////////
public List<Cart> GetCartItems()
{
List<Cart> cartItemList = new List<Cart>();
try
{
cartItemList = con.Query<Cart>("SELECT * FROM fsCarts WHERE CartID=#0", ShoppingCardId).ToList();
}
catch (Exception ex)
{
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception("Shopping Cart GetCartItems: " + ex.ToString())));
}
return cartItemList;
}
////////////////////
public decimal GetTotal()
{
decimal? total = null;
try
{
total = con.ExecuteScalar<decimal>("SELECT SUM(ISNULL(p.Price,0)*c.Count) FROM fsCarts c INNER JOIN fsProducts p ON c.ProductID=p.ProductID WHERE c.CartID=#0", ShoppingCardId);
}
catch (Exception ex)
{
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception("Shopping Cart GetTotal: " + ex.ToString())));
}
return total ?? decimal.Zero;
}
Removing the attribute [ExplicitColumns] above my class fixed the problem. No everything works as expected. Also the other decorations are working. So #Nurhak Kaya was partially right. After removing that attribute deleting the table and rebuild / generating the table.

Resources