|
Yes I did, and it's not that easy to do, so it may take some time
And I'm still wondering about approach to this too, should I create new "module xxx" or leave the current one with "existing model check" ~~
modified 25-Mar-21 21:01pm.
|
|
|
|
|
How do I add migrations and update the test project Database?, I’ve executed the Add-Migration and Update-Database command in the Test project, the database was created and added the Migration too , of course the database is empty, but even after succeeded Migration, I’m still having 227 test failing because of Backing Model changed.
“The model backing the 'TestingContext' context has changed since the database was created. Consider using Code First Migrations to update the database”
Can you help me please, I will be happy to have all my test passed.
Second question.
There is more than tree failing test caused by bad date format of data picker, I supposed that the actual value will be retrieved from the translated string in script folder, but it look like it is being retrieved from the system date time format.
Help please, than you very much.
Expected: <input autocomplete="off" class="form-control datepicker" id="Relation_Date" name="Relation.Date" type="text" value="2011.01.01" />
Actual: <input autocomplete="off" class="form-control datepicker" id="Relation_Date" name="Relation.Date" type="text" value="2011-01-01" />
$.datepicker.regional['lt-LT'] = {
closeText: 'Uždaryti',
prevText: '<Atgal',
nextText: 'Pirmyn>',
currentText: 'Šiandien',
monthNames: ['Sausis', 'Vasaris', 'Kovas', 'Balandis', 'Gegužė', 'Birželis', 'Liepa', 'Rugpjūtis', 'Rugsėjis', 'Spalis', 'Lapkritis', 'Gruodis'],
monthNamesShort: ['Sau', 'Vas', 'Kov', 'Bal', 'Geg', 'Bir', 'Lie', 'Rugp', 'Rugs', 'Spa', 'Lap', 'Gru'],
dayNames: ['sekmadienis', 'pirmadienis', 'antradienis', 'trečiadienis', 'ketvirtadienis', 'penktadienis', 'šeštadienis'],
dayNamesShort: ['sek', 'pir', 'ant', 'tre', 'ket', 'pen', 'šeš'],
dayNamesMin: ['Se', 'Pr', 'An', 'Tr', 'Ke', 'Pe', 'Še'],
weekHeader: 'Sav',
dateFormat: 'yy.mm.dd',
firstDay: 1,
isRTL: false,
showMonthAfterYear: false,
yearSuffix: ''
};
$.timepicker.regional['lt-LT'] = {
timeOnlyTitle: 'Pasirinkite laiką',
timeText: 'Laikas',
hourText: 'Valandos',
minuteText: 'Minutės',
secondText: 'Sekundės',
millisecText: 'Milisekundės',
microsecText: 'Mikrosekundės',
timezoneText: 'Laiko zona',
currentText: 'Dabar',
closeText: 'Uždaryti',
timeFormat: 'HH:mm',
amNames: ['priešpiet', 'AM', 'A'],
pmNames: ['popiet', 'PM', 'P'],
isRTL: false
};
$.datepicker.setDefaults($.datepicker.regional['lt-LT']);
$.timepicker.setDefaults($.timepicker.regional['lt-LT']);
/***********************************************************************
AM: null,
PM: null,
patterns: {
d: "yyyy.MM.dd",
dt: "yyyy.MM.dd HH:mm",
D: "yyyy 'm.' MMMM d 'd.'",
t: "HH:mm",
T: "HH:mm:ss",
f: "yyyy 'm.' MMMM d 'd.' HH:mm",
F: "yyyy 'm.' MMMM d 'd.' HH:mm:ss",
M: "MMMM d 'd.'",
Y: "yyyy 'm.' MMMM"
}
}
}
});
}( this ));
Globalize.culture("lt-LT");
AF Matambo
|
|
|
|
|
1) Just try deleting database file and it's connection in SQL explorer and rerun update-database on both Data and Test projects. Because there are a lot of stuff which can brake migrations.
2) Could you provide failing test names? I'm 99% sure that it's machine culture related.
modified 25-Mar-21 21:01pm.
|
|
|
|
|
Ok I'll do it but need time to collect all test names.
AF Matambo
|
|
|
|
|
I’m having problems when I add more languages in the globalization, when it starts the foreach loop after selecting the third element it is being returned null string in abbreviation attribute. The error is occurring in the GlobalizationProvider method when adding elements to the LanguageDictionary.
According to your reply on this issue in my previous question, I have everything in place, but I had a problem this time in updated application to 1.3.0 version of the template, if I comment all the additional languages, the application runs smoothly with the 2 languages.
Where did I am doing something wrong?
Thank you in advance.
="1.0"="utf-8"
<globalization>
<language name="English" culture="en-GB" abbreviation="en" default="true" />
<language name="Lietuvių" culture="lt-LT" abbreviation="lt" />
<language name="Español" culture="es-ES" abbrevation="es" />
<language name="Português" culture="pt-PT" abbrevation="pt" />
<language name="Français" culture="fr-FR" abbrevation="fr" />
<language name="Italiano" culture="it-IT" abbrevation="it" />
<language name="Deutsch" culture="de-DE" abbrevation="de" />
</globalization>
public void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes
.MapRoute(
"DefaultMultilingual",
"{language}/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { language = "es|pt|fr|it|de|lt" },
new[] { "VumbaSoft.AdventureWorks.Controllers" })
.DataTokens["UseNamespaceFallback"] = false;
routes
.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { language = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
new { language = "en" },
new[] { "VumbaSoft.AdventureWorks.Controllers" })
.DataTokens["UseNamespaceFallback"] = false;
}
public override void RegisterArea(AreaRegistrationContext context)
{
context
.MapRoute(
"AdministrationMultilingual",
"{language}/Administration/{controller}/{action}/{id}",
new { area = "Administration", action = "Index", id = UrlParameter.Optional },
new { language = "es|pt|fr|it|de|lt" },
new[] { "VumbaSoft.AdventureWorks.Controllers.Administration" });
context
.MapRoute(
"Administration",
"Administration/{controller}/{action}/{id}",
new { language = "en", area = "Administration", action = "Index", id = UrlParameter.Optional },
new { language = "en" },
new[] { "VumbaSoft.AdventureWorks.Controllers.Administration" });
}
}
public GlobalizationProvider(String path)
{
XElement languagesXml = XElement.Load(path);
LanguageDictionary = new Dictionary<String, Language>();
foreach (XElement languageNode in languagesXml.Elements("language"))
{
Language language = new Language();
language.Culture = new CultureInfo((String)languageNode.Attribute("culture"));
language.IsDefault = (Boolean?)languageNode.Attribute("default") == true;
language.Abbreviation = (String)languageNode.Attribute("abbreviation");
language.Name = (String)languageNode.Attribute("name");
LanguageDictionary.Add(language.Abbreviation, language);
}
Languages = LanguageDictionary.Select(language => language.Value).ToArray();
DefaultLanguage = Languages.Single(language => language.IsDefault);
}
AF Matambo
|
|
|
|
|
Its "abbreviation" not "abbrevation"
modified 25-Mar-21 21:01pm.
|
|
|
|
|
oh yes, this was a problem, I made the correction and now all work very well. many thanks.
AF Matambo
|
|
|
|
|
1- Is this a way of programming in T4 language for generating the Delete and Edit validation for all newly generated Validators? Do I need to correct somewhere in this assembly or Test project?
2- How can I create the respective resources: Validations.EditOrDeleteAllowedToCreatorUser, Validations.EditOrDeleteNotAllowed, Validations.EditIsNotAllowed and Validations.DeleteIsNotAllowed
namespace Vumbasoft.AdventureWorks.Validators
{
public interface <#= Model.IValidator #> : IValidator
{
Boolean CanCreate(<#= Model.View #> view);
Boolean CanDelete(<#= Model.View #> view);
Boolean CanEdit(<#= Model.View #> view);
}
}
********************************************************************************
namespace Vumbasoft.AdventureWorks.Validators
{
public class <#= Model.Validator #> : BaseValidator, <#= Model.IValidator #>
{
public <#= Model.Validator #>(IUnitOfWork unitOfWork)
: base(unitOfWork)
{
}
public Boolean CanCreate(<#= Model.View #> view)
{
boolean isValid = ModelState.IsValid;
return isValid;
}
public Boolean CanDelete(<#= Model.View #> view)
{
boolean isValid = ModelState.IsValid;
isValid &= IsAllowedAction(view, "CanDelete");
return isValid;
}
public Boolean CanEdit(<#= Model.View #> view)
{
boolean isValid = ModelState.IsValid;
isValid &= IsAllowedAction(view, "CanEdit");
return isValid;
}
private Boolean IsAllowedAction(<#= Model.View #> view, string caller)
{
if (view.CreatedBy != HttpContext.Current.User.Identity.Name)
{
ModelState.AddModelError<<#= Model.View #>>(mod => mod.Name, Validations.EditOrDeleteAllowedToCreatorUser);
return false;
}
if (DateTime.Now.Subtract(view.CreationDate).TotalDays > 1)
{
ModelState.AddModelError<<#= Model.View #>>(mod => mod.Name, Validations.EditOrDeleteNotAllowed);
return false;
}
if (DateTime.Now.Subtract(view.CreationDate).TotalHours > 2 && caller == "CanEdit")
{
ModelState.AddModelError<<#= Model.View #>>(mod => mod.Name, Validations.EditIsNotAllowed);
return false;
}
if (DateTime.Now.Subtract(view.CreationDate).TotalHours > 1&& caller == "CanDelete")
{
ModelState.AddModelError<<#= Model.View #>>(mod => mod.Name, Validations.DeleteIsNotAllowed);
return false;
}
return true;
}
}
}
AF Matambo
|
|
|
|
|
1) Yes you would only need to update Validator.cs.t4 and ValidatorTests.cs.t4 file if you want to generate different validators.
2) Resources have to be created by hand in the Resources project.
modified 25-Mar-21 21:01pm.
|
|
|
|
|
Thank you so much, for your replay.
AF Matambo
|
|
|
|
|
1- I need to validate a Delete Action using a function as shown below, how can I implement it in already generated code in UnitOfWork Class methods for Delete Action, can it be automated for the next scaffolding process via T4 Templates?
2- where did I need to touch in Test project to continue passing all test?
public class RoleValidator : BaseValidator, IRoleValidator
{
public RoleValidator(IUnitOfWork unitOfWork)
: base(unitOfWork)
{
}
public Boolean CanCreate(RoleView view)
{
Boolean isValid = ModelState.IsValid;
isValid &= IsUniqueRole(view);
return isValid;
}
public bool CanDelete(RoleView view)
{
Boolean isValid = ModelState.IsValid;
isValid &= IsAllowedAction(view, "CanDelete");
return isValid;
}
public Boolean CanEdit(RoleView view)
{
Boolean isValid = ModelState.IsValid;
isValid &= IsUniqueRole(view);
isValid &= IsAllowedAction(view, "CanEdit");
return isValid;
}
private Boolean IsUniqueRole(RoleView view)
{
Boolean isUnique = !UnitOfWork
.Select<Role>()
.Any(role =>
role.Id != view.Id &&
role.Name.ToLower() == view.Name.ToLower());
if (!isUnique)
ModelState.AddModelError<RoleView>(role => role.Name, Validations.RoleNameIsAlreadyUsed);
return isUnique;
}
private Boolean IsAllowedAction(RoleView view, string caller)
{
if (view.CreatedBy != HttpContext.Current.User.Identity.Name)
{
ModelState.AddModelError<RoleView>(role => role.Name, Validations.RoleNameIsAlreadyUsed);
return false;
}
if (DateTime.Now.Subtract(view.CreationDate).TotalDays > 1)
{
ModelState.AddModelError<RoleView>(role => role.Name, Validations.RoleNameIsAlreadyUsed);
return false;
}
if (DateTime.Now.Subtract(view.CreationDate).TotalHours > 2 && caller == "CanEdit")
{
ModelState.AddModelError<RoleView>(role => role.Name, Validations.RoleNameIsAlreadyUsed);
return false;
}
if (DateTime.Now.Subtract(view.CreationDate).TotalHours > 1 && caller == "CanDelete")
{
ModelState.AddModelError<RoleView>(role => role.Name, Validations.RoleNameIsAlreadyUsed);
return false;
}
return true;
}
}
AF Matambo
modified 13-Jun-15 1:55am.
|
|
|
|
|
1) Yes you can, by changing Validator.cs.t4 and ValidatorTests.cs.t4 files accordingly.
2) In your case it would be RoleValidatorTests class.
modified 25-Mar-21 21:01pm.
|
|
|
|
|
Thank you so much, for your replay.
AF Matambo
|
|
|
|
|
What are good practices in model first approach for naming classes which have a data base schema name? For example HumanResources_Departments, is it mandatory to put the schema name, in the configuration class do I need to put the schima argument? Is there any performance penalties for suppressing the schema name or any malfunctioning derived from it.
internal class HumanResources_DepartmentConfiguration : EntityTypeConfiguration<HumanResources_Department>
{
public HumanResources_DepartmentConfiguration(string schema = "HumanResources")
{
ToTable(schema + ".Department");
HasKey(x => x.DepartmentId);
Property(x => x.DepartmentId).HasColumnName("DepartmentID").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.Name).HasColumnName("Name").IsRequired().HasMaxLength(50);
Property(x => x.GroupName).HasColumnName("GroupName").IsRequired().HasMaxLength(50);
Property(x => x.ModifiedDate).HasColumnName("ModifiedDate").IsRequired();
}
}
AF Matambo
|
|
|
|
|
Usually model classes are just short singular nouns, while table names are they plural forms (EF handles this automatically most of the time).
As for custom schema and table names, it can be defined on your model class like this.
[Table("Department", Schema = "HumanResources")]
public class Departments
{
}
Or you could change schema for all tables, if that's what you want, like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("HumanResources");
}
There aren't any performance penalties or malfunctioning by using different schemas.
modified 25-Mar-21 21:01pm.
|
|
|
|
|
Thank you so much, for your replay.
AF Matambo
|
|
|
|
|
For getting the current logged in user what is good practice,
HttpContext.Current.User.Identity.Name or
Thread.CurrentPrincipal.Identity.Name , can you explain to me why.
AF Matambo
|
|
|
|
|
HttpContext.Current.User.Identity.Name is the current logged in user in your web app. So this is the one which should be used.
Thread.CurrentPrincipal applies only when the <authentication mode="windows">. Normally this is being used with Windows based applications like WinForms, WPF, etc.
Other than that, you should avoid using static HttpContext.Current property, because it will not exist in the next major release of MVC.
modified 25-Mar-21 21:01pm.
|
|
|
|
|
Hello Muchiachio.
I'm a novice programmer but I have a nose to smell that this template was very well cooked and in a luxury oven and is a very good starting point and also an important source of learning. It is unique in its kind, especially because of the ease it provides when coming to renaming the application name. Again thank you very much Muchiachio for your generosity for sharing and supporting this template.
Now, given that we have not yet a step by step tutorial for the implementation of this starter Project, I want to contribute to create that tutorial that is why I believe that with your help Muchiachio and all they are interested in contributing, together we will create a tutorial of life cycle involved in the creation of an application using this template.
I propose that we use the method of questions and answers for that purpose, questions will be made intentionally from the point of view of a novice programmer to make them as useful as possible for those who have just started in the world of programming, and I'll compile all responses and with them create the tutorial, after that I will going to share that tutorial as a complementing part of the documentation of this template.
As such, we will start from the point where we ended when we have followed the instructions and guidelines of the recommended configurations in the article accompanying the template, which made that we have ended this step with a running and full operational multipage MVC application.
To make more interesting, the practical exercise of learning the implementation of this template, we will create a fully functional business application to manage the AdventureWorks database and deployment and localize it for 8 languages (English USA, Spanish, Portuguese, French, Italian, German and English UK and Lithuanian which are already implemented).
If possible, the application should have implemented the possibility of printing reports, make certain dashboard views of the AdventureWorks database, create an internal email for communication of incidents among users, etc.
So let me write down the basic Requirements of the application
1- Simple and attractive lending page (already implemented)
2- All user mast be logged in and have been assigned to any application role in order to taking any Action in the application (already implemented)
3- The user account should be created by a System Administrator or the Human resources manager who will assign the respective role to the User Account. (already implemented)
4- In the lending home page should be implemented the greeting message like “you are logged in as … or Well come …”
5- The site Map navigation should show the real point where we are in the application site map navigation, for example: Home -> Administration -> Accounts
6- After the user have ended his contract in the company the associated user account should be denied to access the application
7- For compliance with the laws and legal regulations all CRUD operations will be validated and authorized only to registered users in their role, no one is allowed to manipulate some ones else records.
a. The Edit and Delete action must be validated according to:
i. Edit and Delete are allowed only if the creator user is same to logged in user
ii. Edit and Delete are allowed if there is no more than one day from a created date time
iii. The edit action is allowed only if there is no more than 4 hour from a created date time
iv. The delete action can be accomplished only if there is no more than 1 hour from a created date time
8- The application should be localized in the following languages:
a. English UK (already implemented)
b. English USA
c. Spanish
d. Portuguese
e. French
f. Italian
g. German
h. Lithuanian (already implemented)
9- Should be implemented Dash boarding functionality for logging and others
10- Should be implemented Printing functionality
11- Should be implemented internal email for incidence communication between application user
AF Matambo
modified 13-Jun-15 0:18am.
|
|
|
|
|
Hi,
I actually gave this a thought after some previous comments here. And I don't actually like the idea. Because even now, developers mistake this template for a full blown framework (which would need it's own documentation and tutorials). But it's just a template written on MVC framework, there is nothing hidden or restricted under a license here. Thus writing tutorial or any other form of instructions on how to use this template would only repeat documentation which is already written in various sites like http://www.asp.net/.
Of course I'm not preventing you from doing something on your own
modified 25-Mar-21 21:01pm.
|
|
|
|
|
I understand that and I’m so sorry for misunderstanding generated but be strong and keep supporting the template because it is helpful for us.
Yes I’ll proceed as personal guide for my own reference in future projects.
Thank you very much.
AF Matambo
|
|
|
|
|
can't do update-dabase in VS2015
|
|
|
|
|
Sorry, but I will not be supporting VS2015 until it is fully released.
Making changes for unstable releases is too much of a hassle.
However, I did some search on this and it seems that EF and VS2015 just doesn't work now.
You can find people complaining about it in the comments section here.
modified 25-Mar-21 21:01pm.
|
|
|
|
|
How can this template handle the need to read legacy data ?
without breaking it's own elegance and rationale !
Step by step instructions needed if possible.
Thanks
|
|
|
|
|
I would hope that oracle data provider supports database first approach and if it does, you would just need to generate legacy context from the legacy database. If not, you will need to create a new context with model classes replicating your legacy database structure.
I did something like this few years ago and I had to map every table by hand
modified 25-Mar-21 21:01pm.
|
|
|
|
|