Symfony get and set property in same controller? - database

i'm trying to add 1 year on a date in symfony, so i did:
#[Route(path: ['en' => '/upd', 'it' => '/upd'], name: 'upd')]
public function upd(ManagerRegistry $doctrine)
{
$em = $doctrine->getManager();
$domain = $em->getRepository(Domain::class)->find(473);
$domain->setPaymentDueDate(
$domain->getPaymentDueDate()->modify('+ 365 day')
);
$em->persist($domain);
$em->flush();
}
But it is still the same date, no changes.
If i use another get from the same entity, like this
$domain->setPaymentDueDate(
$domain->getCreationDate()->modify('+ 365 day')
);
everything work ok. Also on the dump, after flush(), it show me the date with +365 days so i really don't know what is hapening.
GET and SET functions are symfony's default.
class Domain
{
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
#[Assert\NotBlank(message: 'domain.creation_date.not_blank')]
private ?\DateTimeInterface $creation_date = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $expiration_date = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $payment_due_date = null;
I noticed that in ptofiler->doctrine, where queries are shown, there is not "Update" query. But when get/set are for different attributes then i see the "update" query.

you can clone it maybe before set it again :
$domain->setPaymentDueDate(
(clone $domain->getPaymentDueDate())->modify('+ 365 day')
);

Related

About load supported cultures from DB in .NET CORE

I have a Language entity with all supported languages in my db, each language has a culture string attribute. I want to load supported cultures from DB.
In my service initializer I have it:
public void ConfigureServices(IServiceCollection services)
{
// ... previous configuration not shown
services.Configure<RequestLocalizationOptions>(
opts =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-GB"),
new CultureInfo("en-US"),
new CultureInfo("en"),
new CultureInfo("fr-FR"),
new CultureInfo("fr"),
};
opts.DefaultRequestCulture = new RequestCulture("en-GB");
// Formatting numbers, dates, etc.
opts.SupportedCultures = supportedCultures;
// UI strings that we have localized.
opts.SupportedUICultures = supportedCultures;
});
}
How I can access my DB context inside it?
There is any other better way to do it?
I don't think there's an out of the box solution for this.
However, you can implement your own middleware that achieves this by using ASP.Net's RequestLocalizationMiddleware:
public class CustomRequestLocalizationMiddleware
{
private readonly RequestDelegate next;
private readonly ILoggerFactory loggerFactory;
public CustomRequestLocalizationMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
{
this.next = next;
this.loggerFactory = loggerFactory;
}
public async Task Invoke(HttpContext context /* You can inject services here, such as DbContext or IDbConnection*/)
{
// You can search your database for your supported and/or default languages here
// This query will execute for all requests, so consider using caching
var cultures = await Task.FromResult(new[] { "en" });
var defaultCulture = await Task.FromResult("en");
// You can configure the options here as you would do by calling services.Configure<RequestLocalizationOptions>()
var options = new RequestLocalizationOptions()
.AddSupportedCultures(cultures)
.AddSupportedUICultures(cultures)
.SetDefaultCulture(defaultCulture);
// Finally, we instantiate ASP.Net's default RequestLocalizationMiddleware and call it
var defaultImplementation = new RequestLocalizationMiddleware(next, Options.Create(options), loggerFactory);
await defaultImplementation.Invoke(context);
}
}
Then, we inject the required services and use the custom middleware in Startup.cs or Program.cs as follows:
services.AddLocalization()
/* ... */
app.UseMiddleware<CustomRequestLocalizationMiddleware>()
Do not call app.UseRequestLocalization(), because this would call ASP.Net's RequestLocalizationMiddleware again with the default options, and override the culture that has been resolved previously.

Entity Framework Core with ASP.NET Core Web API and SQL Server (+ Xamarin.Forms)

I have a Xamarin.Forms project with a user registration page, which sends a serialized Customer object via HttpClient to an ASP.NET Core Web API Controller's [HttpPost] method. The body of this [HttpPost] method is supposed to add a row to a Customers table in an SQL Server database hosted in Azure, via Entity Framework Core.
This is the RegistrationController class in my ASP.NET Core Web API project:
[Route("api/[controller]")]
public class RegistrationController : Controller
{
private readonly RegistrationContext _context;
public RegistrationController(RegistrationContext context)
{
_context = context;
}
[HttpPost]
public async Task<IActionResult> Post([FromBody] Customer customer)
{
var customerEntry = new Customer
{
FirstName = customer.FirstName,
LastName = customer.LastName,
EmailAddress = customer.EmailAddress,
PhoneNumber = customer.PhoneNumber
};
try
{
_context.Add(customerEntry);
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return Ok(true);
}
}
And this is the RegistrationContext class:
public class RegistrationContext : DbContext
{
public virtual DbSet<Customer> Customers { get; set; }
public RegistrationContext(DbContextOptions<RegistrationContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>(entity =>
{
entity.Property(e => e.FirstName).IsRequired();
entity.Property(e => e.LastName).IsRequired();
entity.Property(e => e.EmailAddress).IsRequired();
entity.Property(e => e.PhoneNumber).IsRequired();
});
}
}
The Azure SQL Server database is configured in the Startup.cs file:
public void ConfigureServices(IServiceCollection services)
{
container.services.AddMvc();
var connection = #"Server=myAzureSQLServerUrl;Database=myDatabaseName;User Id=mySQLServerLoginId;Password=mySQLServerPassword;";
services.AddDbContext<RegistrationContext>(options => options.UseSqlServer(connection));
}
For some reason, I keep getting an HTTP 500 status code as a response when performing the HttpClient PostAsync method from the Xamarin.Forms client application, which most likely means there is something wrong with the code inside the body of the RegistrationController (or RegistrationContext) in the Web API.
Testing on localhost reveals this exception at await _context.SaveChangesAsync();:
{System.Data.SqlClient.SqlException (0x80131904): Cannot insert the value NULL into column 'Id', table 'zwabydb.dbo.Customers'; column does not allow nulls. INSERT fails. The statement has been terminated.
Does Entity Framework Core not assign the Id integer property of the Customer object automatically? (I set it as the primary key in the SQL Server database). If I assign a value to the Id property manually in the [HttpPost] method, say 1, now I get a 200 OK.
Thank you!
This depends on how you setup your SQL database. If you have an int Id column, you need to set the seed, and autoincrement properties, to have it automatically define a value in that column.
If your Id is a string, then you will need to manually define a value. Normally something like a GUID. e.g. Guid.NewGuid().ToString()

Auth::attempt changing default password to default field like in DB

I have a form and I'm trying to login by using Laravels Auth method.
At the moment I have this snippet:
$input = Input::all();
$login = Auth::attempt([
'username' => $input['username'],
'password' => $input['password']
]);
if($login){
return "Logged in";
}
dd('problem');
But even after entering correct credentials I'm getting to see "problem"
in models/User.php I've changed my table name to tbl_login(like I have in the DB) and that is the only change I've made in it
and in my login model I have
class Login extends Eloquent {
protected $guarded = array();
protected $table = "tbl_login";
protected $primaryKey = "pk_loginID";
public static $rules = array();
}
I also checked this topic but didn't really help and I'm hoping that you guys can help me with this now.
Just as info and a sidenote: table name in Db = tbl_login
primary key field is pk_loginID
username field = username
password field = password
Did I forget something or did I do something wrong?
EDIT:
I've found the problem more specific, but not a solution for it. My password field in the DB has another name than the default password field that Laravel uses. How can I say to Laravel to use my custom password field?
I've found the solution
In the User model in the method getAuthPassword()
public function getAuthPassword()
{
return $this->attributes['passwordFieldinYourTable'];//change the 'passwordFieldinYourTable' with the name of your field in the table
}
That's it :)
You can't change it, but you probably can fix that by creating new mutators to the password field:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
...
public function getPasswordAttribute()
{
return $this->YourPasswordField;
}
public function setPasswordAttribute($password)
{
$this->YourPasswordField = $password;
}
}

Why would my entity not return with updated values?

I have a Customer entity defined in EF Code First with an AccountNumber property. I can get and update a single Customer with their AccountNumber without issue. But when I get all Customers the AccountNumber is old for sometime and then eventually updates after a change. The database always returns the correct AccountNumber value.
I have profiled SQLServer and found that the call to get all Customers does make it to the database and it returns the latest value but the response from the DbContext gives an old AccountNumber. So it seems like EFCF is caching my data.
Please help.
UPDATE: Code examples -
public IQueryable<Customer> GetCustomers()
{
return this.acmeDbContext.Customer
.Include(x => x.IpAddressRange)
;
}
public Customer GetCustomer(Guid id)
{
var Customer = this.acmeDbContext.Customer
.Include(x => x.Contacts)
.Include(x => x.IpAddressRange)
.OrderByDescending(x => x.Id)
.FirstOrDefault(x => x.CustomerId == id);
return Customer;
}
public void SaveCustomer(Customer Customer)
{
this.acmeDbContext.SaveChanges();
}
I ended up using the Reload method to reload each customer:
if (noCache)
customers.ToList().ForEach(x => acmeDbContext.Entry(x).Reload());

How to list all users along with user profile from ASP.NET Membership?

Right now I'm working with silverlight project and I'm stuck on how to list all of users and user profile together.
Now I'm using this method to get all user via WCF
public IEnumerable<MembershipServiceUser> GetAllUsers()
{
return Membership.GetAllUsers().Cast<MembershipUser>().Select(u => new MembershipServiceUser(u));
}
public void FromMembershipUser(MembershipUser user)
{
this.Comment = user.Comment;
this.CreationDate = user.CreationDate;
this.Email = user.Email;
this.IsApproved = user.IsApproved;
this.UserName = user.UserName;
}
I can get all user from those code above but I don't know how extactly to get user profile
eg. Firstname , Lastname , etc..
You can create a new instance of ProfileBase and access the profile fields with the method GetPropertyValue("propertyName"), where propertyName is the name of your custom registration data.
var profile = ProfileBase.Create(user.UserName);
this.CustomProperty = profile.GetPropertyValue("customPropertyName");
I'm not 100% sure about the syntax, I come from a vb environment and haven't written any c# in a while.
ProfileInfoCollection profiles = ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All);
foreach (ProfileInfo pi in profiles)
{
ProfileCommon p = Profile.GetProfile(pi.UserName);
countries.Add(p.Country);
}

Resources