I started to learn angularjs and trying to put together Angularjs+Breezejs+EntityFramework.
Here is my context cs file:
public class GrantsDbContext : DbContext {
public GrantsDbContext() {
Database.SetInitializer<GrantsDbContext>(new MigrateDatabaseToLatestVersion<GrantsDbContext, Configuration>());
}
public DbSet<OrgItem> OrgList;
}
OrgItem is just model-class (contained: ID, FullName, ShortName), and I set automigrate, and write default connection string in Web.config
That's breeze controller cs file:
[BreezeController]
public class DbController : ApiController {
private EFContextProvider<GrantsDbContext> _contextProvider = new EFContextProvider<GrantsDbContext>();
[HttpGet]
public String Metadata() {
return _contextProvider.Metadata();
}
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle) {
return _contextProvider.SaveChanges(saveBundle);
}
[HttpGet]
public IQueryable<OrgItem> OrgList() {
return _contextProvider.Context.OrgList;
}
}
Here is angular service, that created manager for breeze:
angular.module('app').factory("entityManagerFactory", ["breeze", emFactory]);
function emFactory(breeze) {
new breeze.ValidationOptions({ validateOnAttach: false }).setAsDefault();
var serviceName = "breeze/db";
var metadataStore = new breeze.MetadataStore();
var provider = {
newManager: newManager
};
return provider;
function newManager() {
var mgr = new breeze.EntityManager({
serviceName: serviceName,
metadataStore: metadataStore
});
return mgr;
}
}
That's my controller that called query:
angular.module("app")
.controller("OrgCtrl", ['entityManagerFactory', OrgCtrl]);
function OrgCtrl(entityManagerFactory) {
var vm = this;
vm.orgs = [];
var manager = entityManagerFactory.newManager();
var orgsQuery = new breeze.EntityQuery("OrgList").select("ID, FullName, ShortName");
manager.executeQuery(orgsQuery).then(succesCallback).catch(failCallback);
function succesCallback(data) {
vm.orgs = data.result;
}
function failCallback(error) {
console.log(error);
}
}
When I firstly started the app, database was created with one table '_MigrationHistory' and then I got the error: 'Error: cannot execute _executeQueryCore until metadataStore is populated.'
'localhost:49934/breeze/db/Metadata' is available (200 OK).
All libraries updated with nuget.
Help please to solve this problem!
Thanks!
Related
I'm building a desktop APP using windows forms that needs to be authenticated via a WebAPI using Token authentication.
The API is proved that work because a mobile APP is using it and also I can get results using POSTMAN
The problem is when I'm calling the Authentication method from the desktop App.
When I do the request, the API recieves it and it only goes until ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context), not reaching GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) in the Auth process.
Here is my CustomAuthProvider
public class CustomOAuthProvider : OAuthAuthorizationServerProvider
{
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
return Task.FromResult<object>(null);
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var allowedOrigin = "*";
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "El nombre de usuario o contraseƱa son incorrectos");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "JWT");
var ticket = new AuthenticationTicket(oAuthIdentity, null);
context.Validated(ticket);
}
}
Here is my Startup class
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
HttpConfiguration httpConfig = new HttpConfiguration();
ConfigureOAuthTokenGeneration(app);
ConfigureOAuthTokenConsumption(app);
ConfigureWebApi(httpConfig);
}
}
At the moment I'm trying two different ways to authenticate the APP.
First One:
public LoginResponseModel Authenticate(LoginRequestModel applicationUser)
{
using (var client = new WebClient())
{
try
{
client.Headers["Content-Type"] = "application/json";
var data = applicationUser.Serialize();
var response = client.UploadString(Context.ApiUrl + "Authenticate","POST", JsonConvert.SerializeObject(applicationUser));
var resultJson = JsonConvert.DeserializeObject<LoginResponseModel>(response);
return resultJson;
}
catch (Exception exception)
{
}
}
return null;
}
And second one:
public async Task<ApplicationUser> Authenticate(LoginRequestModel applicationUser)
{
var client = new HttpClient();
try
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var data = applicationUser.Serialize();
var response = await client.PostAsJsonAsync(Context.ApiUrl + "Authenticate",data );
// return null by default (test)
return null;
}
catch (Exception exception)
{
}
return null;
}
And this is the model I'm using for the request
public class LoginRequestModel
{
public string Grant_type { get; set; } = "Password";
public string UserName { get; set; }
public string Password { get; set; }
}
And this should be the response:
public class LoginResponseModel
{
public string Access_token { get; set; }
public string Token_type { get; set; }
public string Expires_in { get; set; }
}
Ah the moment both ways of calling the API only reach the initial verification of the owin process (ValidateClientAuthentication). What can be happening? How I can fix this? What I need to do to make the process go to GrantResourceOwnerCredentials?
thanks for the help
I solved my problem. The problem was that the form wasn't being filled and sent correctly.
private AuthToken GetAuthToken(LoginRequestModel applicationUser)
{
using (var client = new HttpClient())
{
var form = new Dictionary<string, string>
{
{"grant_type", "password"},
{"username", applicationUser.UserName},
{"password", applicationUser.Password},
};
try
{
var tokenResponse = client.PostAsync(Context.ApiUrl + "Authenticate", new FormUrlEncodedContent(form)).Result;
var token = tokenResponse.Content.ReadAsAsync<AuthToken>(new[] { new JsonMediaTypeFormatter() }).Result;
return token;
}
catch (Exception e)
{
Log4Net.log.Error("Error Getting Auth token", e);
return null;
}
}
}
I try to do some processing that take time, and suddenly the server returns me a timeOut exception.
Since my controller, I call the generate method that calls a service, and this service calls my class where there is the method that does the processing.
What is the solution in your opinion?
vm.afficher = function() {
vm.details = [];
var x = vm.applicationField;
if (x === undefined || x === null) {
x = 'off';
}
FacturationSvc.generate({
selectedDt : new Date(vm.selectedDt),
applicationField : x
}).$promise.then(function(resp) {
vm.details = JSON.parse(JSON.stringify(resp));
vm.table.check = true;
});
}
vm is the instance of the controller.
#RequestMapping("/facturations")
#Controller
public class FacturationController {
private FacturationSvc facturationSvc;
#Autowired
public FacturationController(FacturationSvc svc, UserSvc userSvc) {
super();
this.facturationSvc = svc;
}
#RequestMapping(value = "/generate/{selectedDt}/applicationName/{applicationField}", method = RequestMethod.GET)
#ResponseBody
public List<Facturation> generate(#PathVariable Date selectedDt,#PathVariable String applicationField) throws NoSuchFieldException{
return facturationSvc.facturer(selectedDt,applicationField);
}
}
When I call $http.get('/api/calendarevent/getall') in my Angular code, the breakpoints for the method in my API Controller that matches that route are not being hit. I don't know if that means the methods in the controller aren't being called or if it's bypassing the breakpoints set in the method. In the IE Developer tools, I receive a 500 error code. So the method is being found but I'm not sure if it's being executed since I would have received some kind of 400 error if it wasn't being found. Below, I've included the necessary code, can anyone see where I might be going wrong?
Angular Code:
function () {
var deferred = $q.defer();
$http.get('/api/calendarevent/getall').success(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}
Global.asax.cs:
protected void Application_Start(object sender, EventArgs e)
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "Default",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional });
}
APIController:
public class CalendarEventController : ApiController
{
[HttpGet]
[ActionName("all")]
public object GetAll()
{
using (var entity = new RPOEntities())
{
CalendarEventViewModel returnModel = new CalendarEventViewModel();
var events = entity.CalendarEvents.Where(e => !e.Deleted);
var eventList = events.ToList();
var calendarEvents = eventList.Select(e => new
{
id = e.CalendarEventId,
title = e.Title,
start = e.StartDate,
end = e.EndDate,
url = "details/" + e.CalendarEventId.ToString(),
contact = e.Contact,
location = e.Location,
property = e.AllProperties ? "All Properties" : e.Property != null ?
e.Property.PropertyName : "",
active = e.Active,
canEdit = Helper.IsRPOAdmin || Helper.IsCorporateAdmin || (e.PropertyStaffId.HasValue && e.PropertyStaffId.Value == Helper.CurrentUserId)
}).ToList();
return new {
events = calendarEvents,
color = "",
textColor = "" };
}
}
I'm trying to save new item to my database using Breeze and web api.
Here is my model:
public class MuscleGroup
{
#region Properties
public int MuscleGroupId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
#endregion
#region Navigational properties
public virtual ICollection<Muscle> Muscles { get; set; }
public virtual ICollection<Exercise> Exercises { get; set; }
#endregion
}
Here is my API:
[BreezeController]
public class MuscleGroupController : ApiController
{
private readonly EFContextProvider<MadBarzDatabaseContext> _contextProvider =
new EFContextProvider<MadBarzDatabaseContext>();
// GET api/<controller>
[HttpGet]
public IQueryable<MuscleGroup> Get()
{
return _contextProvider.Context.MuscleGroups;
}
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
}
Here are parts of my dataService.js:
app.angularModule.service('muscleGroupService', function(breeze, logger) {
breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);
var mbservice = new breeze.DataService({
serviceName: "http://localhost:23758/api/MuscleGroup",
hasServerMetadata: false,
});
var manager = new breeze.EntityManager({ dataService: mbservice });
manager.enableSaveQueuing(true);
var removeItem = breeze.core.arrayRemoveItem;
var items = [];
var muscleGroupService =
{
getAll: getAll,
getSucceeded: getSucceeded,
getFailed : getFailed,
addItem: addItem,
// deleteItem: deleteItem,
// updateItem : updateItem,
};
return muscleGroupService;
//#region addItem
function addItem(initialValues) {
var item = manager.createEntity("MuscleGroup", initialValues);
saveChanges().fail(addFailed);
items.push(item);
return item;
function addFailed() {
removeItem(items, item);
}
}
//#endregion
//#region SaveChanges
function saveChanges() {
return manager.saveChanges()
.then(saveSucceeded)
.fail(saveFailed);
}
function saveSucceeded(saveResult) {
logger.success("Saved :D");
logger.log(saveResult);
}
function saveFailed(error) {
logger.error(error);
logger.log(error);
}
//#endregion
}
Here is part of my controller:
$scope.addNewItem = function() {
var newItem = muscleGroupService.addItem({ Id: 42, Name: $scope.Name, Description: "ho", ImageUrl: "hey"});
$scope.items.push(newItem);
};
And this is error I get:
Error: Unable to locate a 'Type' by the name: 'MuscleGroup'. Be sure to execute a query or call fetchMetadata first.
at proto._getEntityType (http://localhost:7122/Scripts/breeze.debug.js:6056:19)
at proto.getEntityType (http://localhost:7122/Scripts/breeze.debug.js:6047:21)
at Object.addItem (http://localhost:7122/Scripts/app/AdminMuscleGroup/MuscleGroupService.js:61:45)
at Object.$scope.addNewItem (http://localhost:7122/Scripts/app/AdminMuscleGroup/MuscleGroupController.js:16:42)
at http://localhost:7122/Scripts/angular/angular.js:6365:19
at http://localhost:7122/Scripts/angular/angular.js:12987:13
at Object.Scope.$eval (http://localhost:7122/Scripts/angular/angular.js:8057:28)
at Object.Scope.$apply (http://localhost:7122/Scripts/angular/angular.js:8137:23)
at HTMLButtonElement.<anonymous> (http://localhost:7122/Scripts/angular/angular.js:12986:17)
at HTMLButtonElement.jQuery.event.dispatch (http://localhost:7122/Scripts/jquery-1.8.2.js:3063:9) angular.js:5754
I query All Muslce groups before I try to add antoher.
PW Kad is giving you the clues.
When you wrote hasServerMetadata: false, you told Breeze not to get metadata from the server; you told Breeze that you would provide the metadata on the client. You aren't providing metadata on the client.
You're controller doesn't have a Metadata endpoint ... and couldn't offer such an endpoint AND ALSO be structured as the controller-per-type API controller that you seem determined to devise.
You're deviating from the standard Breeze productivity path while pursuing controller-per-type. That's fine ... after you have a little experience, know what you're doing, and know why you're doing it. The hasServerMetadata flag is true by default for a reason; you can't just set it false and expect everything to work.
I suggest that you back up, follow the Breeze guidance, understand it, then depart from that guidance incrementally as you discover solid, business reasons for doing so.
Im trying to make an app that can dynamically load classes that implements an interface "IPlugin", i have:
var catalog = new AssemblyCatalog(typeof(Shell).Assembly);
var externalCatalog = new DirectoryCatalog(#".\Modules");
var container = new CompositionContainer(catalog);
var a = new AggregateCatalog(externalCatalog, catalog);
But when im trying to get the exports:
CompositionContainer __container = new CompositionContainer(a);
//get all the exports and load them into the appropriate list tagged with the importmany
__container.Compose(batch);
var yyyy = __container.GetExports<IModule>();
It doesnt find my "IPlugin" in the external assembly "Rejseplan".
Implementation of "Rejseplan" plugin:(the one that does not get loaded)
namespace Rejseplan
{
[ModuleExport(typeof(IPlugin), InitializationMode = InitializationMode.WhenAvailable)]
class RejseplanModule : IModule, IPlugin
{
private readonly IRegionViewRegistry regionViewRegistry;
[ImportingConstructor]
public RejseplanModule(IRegionViewRegistry registry)
{
this.regionViewRegistry = registry;
}
public void Initialize()
{
regionViewRegistry.RegisterViewWithRegion("MainRegion", typeof(Views.DepartureBoard));
}
string IPlugin.Name
{
get { throw new NotImplementedException(); }
}
string IPlugin.Version
{
get { throw new NotImplementedException(); }
}
string IPlugin.TabHeader
{
get { throw new NotImplementedException(); }
}
}
}
implmentation of "Test" plugin (the one that GETS loaded):
namespace HomeSystem
{
[Export(typeof(IPlugin))]
[ModuleExport(typeof(IModule), InitializationMode = InitializationMode.WhenAvailable)]
public class Test : IModule, IPlugin
{
public void Initialize()
{
}
public string Name
{
get { return "Test"; }
}
public string Version
{
get { return "Tis"; }
}
public string TabHeader
{
get { return "Tabt"; }
}
}
}
Hope you guys can helpCheers! :)
to be honest i dont really know what you wanna achieve :)
but if you want to see your RejseplanModule within your call:
__container.GetExports<IModule>();
you have to add the right Export attribute.
RejseplanModule is not MEF marked with Export of type IModule. can you check your code if its a typo or not? at least it should be the following (see the typeof(IModule))
EDIT:
external dll
[Export(typeof(IModule))]//<-- remove this if its handled by your custom ModulExport Attribute
[ModuleExport(typeof(IModule), InitializationMode = InitializationMode.WhenAvailable)]
class RejseplanModule : IModule, IPlugin
{...}
your main app(code from fhnaseer above)
var directoryPath = "path to dll folder";
var asmCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var directoryCatalog = new DirectoryCatalog(directoryPath, "*.dll");
var aggregateCatalog = new AggregateCatalog();
aggregateCatalog.Catalogs.Add(asmCatalog);
aggregateCatalog.Catalogs.Add(directoryCatalog);
var container = new CompositionContainer(aggregateCatalog);
var allIModulPlugins = container.GetExports<IModule>();
try to do this.
var directoryPath = "path to dll folder";
var asmCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var directoryCatalog = new DirectoryCatalog(directoryPath, "*.dll");
var aggregateCatalog = new AggregateCatalog();
aggregateCatalog.Catalogs.Add(asmCatalog);
aggregateCatalog.Catalogs.Add(directoryCatalog);
var container = new CompositionContainer(aggregateCatalog);
container.ComposeParts(this);