Passing object in Navigation MAUI - c#

I'm developing small app to pratice and I'm having a problem understanding why the object I pass is Null.
I have a main ViewModelPage where I have a Button:
[RelayCommand]
private async Task CellDoubleTapped()
{
Patient patient = new Patient(Id, Date);
var navigationParameter = new Dictionary<string, object>
{
{ "obj", patient }
};
await Shell.Current.GoToAsync($"//{nameof(EditingPage)}", navigationParameter);
}
With this button I wanted to open a new page "EditingPage", where I pass my patient object, and there I present the user with fields to edit.
My EditingViewModel:
[QueryProperty(nameof(obj), "obj")]
public partial class EditingViewModel: BaseViewModel
{
public Patient obj { get; set; }
public string Date { get; set; }
public EditingViewModel()
{
ShowFields();
}
private void ShowFields()
{
Date = obj.Date;
}
}
I recieve an Exception stating my obj is NULL. "object reference not set to an instance of an object"
Can you help me understand which concepts I'm not understanding.
I expected to access the object I created in a page in another page. I'm trying to pass it through Navigation like presented in the documentation from Microsoft. Maybe my error is not about that but there's a concept about passing classes I'm consfusing

Related

How to Provide Fluent Validation on Multi-Select Component using MudBlazor

I have a Blazor app that manages a lot of form input. Every form is tied to an instance of type IncidentLog, and every UI element of the form is tied to a property of that IncidentLog instance.
In the form, we have a MudSelect component where T="Department". The MudSelect has MultiSelection="true", and the results are stored in a IEnumerable(Department) Departments property of the IncidentLog instance.
This component works totally fine, but I've tried implementing FluentValidation in the form and I'm not sure how to define the expression of the For parameter of this MudSelect component. It looks like it's expecting me to pass an object that matches T="Department", but the validation I need to run against the validator is based off of IEnumerable(Department)... I just want to check that the user has selected at least one department from the multiselect component.
Error message when trying to pass IEnumerable object to the For validator:
IncidentLogPropertiesComponent razor page - relevant blurb
<MudForm Model="#Log" #ref="#form" Validation="#(incidentLogValidator.ValidateValue)" ValidationDelay="100">
<MudCardContent Class="pt-0">
...
<MudSelect T="Department" ToStringFunc="#ConverterDepartment" Dense="true" Margin="Margin.Dense" Label="Affected Departments:" MultiSelection="true" #bind-SelectedValues="Log.Departments" Clearable>
#foreach (var department in Departments.OrderBy(o=>o.DepartmentName).ToList())
{
<MudSelectItem Value="#department"/>
}
</MudSelect>
...
</MudCardContent>
</MudForm>
IncidentLog.cs:
public class IncidentLog : Log
{
[Key]
public int IncidentID { get; set; }
....
[Write(false)]
public IEnumerable<Department> Departments { get; set; } = new HashSet<Department>();//3
....
}
IncidentLogPropertiesComponentBase
public class IncidentLogPropertiesComponentBase : OwningComponentBase<iIncidentLogRepository>, IDisposable
{
protected IncidentLogValidator incidentLogValidator = new IncidentLogValidator();
...
[Parameter]
public IncidentLog? Log
{
get
{
return (AppState.SelectedLog != null && AppState.SelectedLog.LogType.LogTypeID == 2) ? (IncidentLog)AppState.SelectedLog : null;
}
set
{
AppState.SetLog(value);
}
}
}
IncidentLogValidator:
public class IncidentLogValidator: AbstractValidator<IncidentLog>
{
public IncidentLogValidator()
{
...
RuleFor(t => t.Departments).NotEmpty().WithMessage("Must enter at least one department affected.");
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<IncidentLog>.CreateWithOptions((IncidentLog)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
*I didn't link my AppState state management file even though it's referenced in code above - I don't think it's relevant to the issue I'm having.
How do I provide Fluent Validation to Multi-Select Dropdowns using MudBlazor?

Impossible to deserialize a dependent transaction passed to an external API

I was trying to implement the example for DependentTransaction in
https://learn.microsoft.com/en-us/dotnet/api/system.transactions.dependenttransaction?view=netframework-4.8
The difference for me is that I pass the dependent transaction to an API and I am not able to restore the resulting object back into a DependentTransaction.
So here is the code:
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
// code that saves an entity in the database within the above scope
// code that creates an audit trail object
object dependantTxn = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
AuditTrailParamterModel model = new AuditTrailParamterModel()
{
AuditTrail = auditTrail,
transaction = dependantTxn
}
await client.PostAsJsonAsync("http//localhost/auditrail/api/InsertAuditTrail", model);
}
On the receiving end here is a portion of the code (like in the example):
[Route("api/InsertAuditTrail")]<br/>
[HttpPost]<br/>
public async Task<IHttpActionResult> InsertAuditTrail(AuditTrailParamterModel model)
{
// Create a DependentTransaction from the object passed to API
DependentTransaction dTx = (DependentTransaction)model.transation;
// more code ....
}
The problem is that model.transation is populated with the following:
{{"OletxTransactionPropagationToken":"AQAAAAMAAADYbd5tQr4RbyxnSSp5UW2AAAQAAAAAABsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADk4NGNmZDU1LTQyMmUtNDI4MC04NDk3LTg2NjM3ODE4NjZjNQAAMAAHAAAAZM1kzSAAAABRTi0wMDMwABAAAABRAE4ALQAwADAAMwAwAAAAAAAAAAAAAAAOAAAAdGlwOi8vUU4tMDAzMC8AAA=="}}
The line:
DependentTransaction dTx = (DependentTransaction)model.transation;
crashes.
The exception is
Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'System.Transactions.DependentTransaction'.
The type DependentTransaction inherits from Transaction and the members are as follows:
public static Transaction Current { get; set; }
public IsolationLevel IsolationLevel { get; }
public TransactionInformation TransactionInformation { get; }
public Guid PromoterType { get; }
and TransactionInformation has the following members:
public string LocalIdentifier { get; }
public Guid DistributedIdentifier { get; }
public DateTime CreationTime { get; }
public TransactionStatus Status { get; }
I also tried to see if I could use a decoder from Base64 format to see if that long string could be changed to a Transaction but it could not be done.
I have looked for hours online in order to find a solution to this and I can't find anything.
Can anyone help? I would really appreciate it.

Xamarin.ios and Realm issue with creating realm object

Having an issue with my first time using Realm on the Xamarin.ios platform. I am following this tutorial: Realm and Xamarin Tutorial
The issue im having is that when I try to create my object using realm.CreateObject(). I get an error saying "The non-generic method 'Realm.CreateObject(string, object)' cannot be used with type arguments"
Im at a dead end and do not know what to do from here. I have followed the tutorial exactly but still does not work at this point.
ViewController code:
private void AddNewCar()
{
var realm = Realm.GetInstance();
realm.Write(() =>
{
var newCar = realm.CreateObject<Car>(); //This is where it has an error
});
}
and this is my public class in another class file:
using System;
using Realms;
namespace RealmApp.Model
{
public class Car: RealmObject
{
public string Brand { get; set; }
public string Model { get; set; }
public Car()
{
}
}
}
Hopefully someone can help!
Jamie
Change your realm.CreateObject to this.
realm.Add(new Car { Brand = "Your Brand", Model = "Your model" });
You can also create the model outside of Add, and just do realm.Add(yourModel)

Updating navigation property works but entity does not appear in Collection

I've got 2 entities, User and Material. User holds the Collection of the materials.
public class User
{
...
private ICollection<Material> materials;
public virtual ICollection<Material> Materials
{
get { return materials ?? (materials = new List<Material>()); }
set { materials = value; }
}
}
And material:
public class Material
{
...
public int? UserId { get; set; }
public virtual User User { get; set; }
...
}
When logged User selects Material, I assign that User to Material.User and save changes. Works fine, changes are saved in db. But, if I want to access materials with User.Materials, collection contains no elements. I have tried with simple project and there it works. With my complex project, it does not. What to do?
Help me please, bothering with problem for 8 hours already and still havent fix it.
EDIT: Well, that is so... lame.
My code was actually working BUT... the problem was, when view-ing user details, I retrieved User from database and created a COPY of it with a cunstrictor. I was missing something:
public User(User otherUser)
{
Id = otherUser.Id;
FirstName = otherUser.FirstName;
LastName = otherUser.LastName;
Shift = otherUser.Shift;
PassCode = otherUser.PassCode;
Type = otherUser.Type;
Materials = otherUser.Materials; // this line was missing
}
After adding this line, it works. Just Visual Studio is complaining about that (virtual member call in constructor). What to do about it?
Your problem are here:
private ICollection<Material> materials;
public virtual ICollection<Material> Materials
{
get { return materials ?? (materials = new List<Material>()); }
set { materials = value; }
}
Entity Framework navigation property cannot be property with backing field. It can be only autoproperty. So you should use this code instead:
public class User
{
...
public virtual ICollection<Material> Materials
{
get;
set;
}
}

Creating and storing a session

I'm working on creating a session for a user login on my website. I can initialize the session and use its members just fine, but I also need a method within my session class that will store itself. I need to provide HttpSessionState as an input parameter, and then store it into an object like: Session["sessionName"]=this;.
Furthermore, when I want to retrieve the session, it won't yet be created, so it must be static. Then I need to return a new instance of my session class with the properties filled (username and companyID) out of the HttpSessionState.
How can this be done in my session class? What I've described above is from the research I've done that provides a particular solution to my problem, but since I'm new to using session, I don't quite understand it.
Thanks.
Snippet of my session class:
public class MySession : System.Web.UI.Page
{
private MySession()
{
Username = Business.User.labelUsername;
CompanyId = Business.User.labelCompanyId;
}
public static MySession Current
{
get
{
try
{
MySession session = (MySession)HttpContext.Current.Session["sessionName"];
if (session == null)
{
session = new MySession();
HttpContext.Current.Session["sessionName"]=session;
}
return session;
}
catch (NullReferenceException e)
{
Debug.WriteLine("NullReferenceException:");
Debug.WriteLine(e);
}
return null;
}
}
public string Username
{
get; set;
}
public string CompanyId
{
get; set;
}
}
You could try using a serialized "session info" object:
[Serializable]
public class SessionInfo
{
// Stuff to store in session
public string Name { get; set; }
public int Foo { get; set; }
private SessionInfo()
{
// Constructor, set any defaults here
Name = ""
Foo = 10;
}
public static SessionInfo Current
{
get
{
// Try get session info from session
var info = HttpContext.Current.Session["SessionInfo"] as SessionInfo;
// Not found in session, so create and store new session info
if (info == null)
{
info = new SessionInfo();
HttpContext.Current.Session["SessionInfo"] = info;
}
return info;
}
}
}
You can then use this from within your application like this:
SessionInfo.Current.Name = "Something Here";
SessionInfo.Current.Foo = 100;
The serialization/deserialization is all done within the SessionInfo object, and you get the benefit of type safe data.
What you are asking about is called serialization and deserialization.
Serialization is taking an object and converting it to a format, such as a string, that can be stored. Deserialization is the reverse of that action.
The "quick" way is to add the [Serializable] attribute to your class. However, without knowing the details of that class it's hard to say whether it is in fact easily serializable without a bit of work.
Here's a walkthrough: http://msdn.microsoft.com/en-us/library/vstudio/et91as27.aspx

Categories