ASP.NET : Method not found when calling for parent class - asp.net-mvc

basically I'm getting an exception while im performing this:
var userDb = new UserData();
userDb.InsertData(DbName);
My InsertData function:
var userRepo = new UserRepository();
var users = new List<User>();
using (var db = userRepo.InitialDb(dbName))
{
userRepo.AddList(_users);
users = userRepo.GetAll();
}
and while I'm running InsertData function, i get this exception:
{"Method not found: 'LiteDB.LiteDatabase Db.Data.Repository.Repository`1.InitialDb(System.String)'."}
My UserRepository.cs
public class UserRepository : Repository<User>{}
While my Repository.cs:
public abstract class Repository<T> where T : class
{
protected LiteDatabase db;
public LiteDatabase InitialDb(string dbPath)
{
db = new LiteDatabase(dbPath);
return db;
}
}
So the question here is,
1. I don't know if i inherited my parent well.
2. If yes, why there is a method not found exception thrown?
Thanks in advance, let me know if i missed out anything in the question.

Related

ApplicationDbContext Object reference not set to an instance of an object

I am trying to seed data into my Sqlite Database with an ASP.Net Core MVC app. Everything works fine until the command:
context.SaveChanges()
When this is fired an "Object reference not set to an instance of an object" is thrown, despite already having Added to the context without issue beforehand. Here is the suspect code:
public class Seeder
{
private ApplicationDbContext context;
public Seeder(ApplicationDbContext _context)
{
context = _context;
}
//populate the database with the static items
public void SeedData()
{
//jump out if data already exists
if(context.HomeTypes.Count() != 0)
{
return;
}
//build the home types
HomeType basic = new HomeType
{
home_type_id = 0,
name = "Town House",
capacity = 2,
home_image_src = "changeThisLater"
};
context.HomeTypes.Add(basic);
context.SaveChanges();
}
}
Here is where the seeder class is called:
public static void Main(string[] args)
{
var host = BuildWebHost(args);
//seed the database when the app starts up
using(var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<ApplicationDbContext>();
Seeder seeder = new Seeder(context);
seeder.SeedData();
}catch(Exception e)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(e, "An error occured while seeding the db");
}
}
//run
host.Run();
}
Here is a photo of my error message:
Resolved!
The problem was with my ID's. In this seeder I set the value of home_type_id to 0. EF Core auto generates ID's so this was causing a problem and having my ID's be added as -2175267 (or something crazy like that).
The fix was simply to add:
//prevent auto generation of the id feilds
builder.Entity<Role>().Property(m => m.role_id).ValueGeneratedNever();
builder.Entity<HomeType>().Property(m => m.home_type_id).ValueGeneratedNever();
To my ApplicationDbContext in the OnModelCreating function, and it works groovy now

Autofac Automocking in ASP.NET MVC

So I'm trying to use Autofac Automocking in ASP.NET MVC 5, but for some reason I can't get it to work.
Here's the test so far:
using (var mock = AutoMock.GetLoose())
{
const string mainUserID = "MainUserID";
const string otherUserID = "OtherUserID";
ApplicationUser user = new ApplicationUser()
{
Id = mainUserID,
UserName = "TestUser"
};
var dataProvider = mock.Mock<IDataProtectionProvider>();
dataProvider.DefaultValue = DefaultValue.Mock;
var userManagerMock = mock.Mock<ApplicationUserManager>();
}
The test fails when mocking the ApplicationUserManager. The error is this:
Result StackTrace:
at Autofac.Extras.Moq.AutoMock.Mock[T](Parameter[] parameters)
at AwenterWeb_NUnit.AccountControllerTest.<Deactivate_User>d__0.MoveNext() in C:\Users\Fabis\Documents\Docs\Kvalifikācijas darbs 2015\AwenterWeb\AwenterWeb-NUnit\AccountControllerTest.cs:line 51
at NUnit.Framework.AsyncInvocationRegion.AsyncTaskInvocationRegion.WaitForPendingOperationsToComplete(Object invocationResult)
at NUnit.Core.NUnitAsyncTestMethod.RunTestMethod()
Result Message: System.InvalidCastException : Unable to cast object of type 'AwenterWeb.ApplicationUserManager' to type 'Moq.IMocked`1[AwenterWeb.ApplicationUserManager]'.
The same thing happens when trying to automock the ApplicationDbContext and it has a very simple constructor, so there shouldn't even be any issues with it.
I'm new to Mocking - what should I do in this scenario?
Edit: Also kind of an unrelated question, maybe you guys know - I've noticed that when creating a Moq for a DbSet using a list created previously in the test, I have to do this:
var dbSetMock = new Mock<IDbSet<DbEntity>>();
dbSetMock.Setup(m => m.Provider).Returns(data.Provider);
dbSetMock.Setup(m => m.Expression).Returns(data.Expression);
dbSetMock.Setup(m => m.ElementType).Returns(data.ElementType);
dbSetMock.Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
It seems really unintuitive. Is there a way to just tell the mock to take the list? So something like:
dbSetMock.Setup(m => m).Returns(data);
Or any other way to create a DbSet Moq from an existing list quickly without having to write those 4 extra lines?
If you look at ligne 73 of MoqRegistrationHandler.cs you can see that only interface is moqable using Autofac.Extras.Moq
var typedService = service as TypedService;
if (typedService == null ||
!typedService.ServiceType.IsInterface ||
typedService.ServiceType.IsGenericType && typedService.ServiceType.GetGenericTypeDefinition() == typeof(IEnumerable<>) ||
typedService.ServiceType.IsArray ||
typeof(IStartable).IsAssignableFrom(typedService.ServiceType))
return Enumerable.Empty<IComponentRegistration>();
var rb = RegistrationBuilder.ForDelegate((c, p) => CreateMock(c, typedService))
.As(service)
.InstancePerLifetimeScope();
You can change the code but it may be quite difficult to make it works with non parameter less dependency.
Can your dependencies be changed to use an interface instead of a concrete class ? if it is not possible and/or if it doesn't make sense, you can use the MockRepository to create your non parameter-less component and then inject it on the AutoMock class.
class Program
{
static void Main(string[] args)
{
using (var mock = AutoMock.GetLoose())
{
/// configure your non interface component with constructor parameters
/// if foo need more complex parameters you can get them
/// using mock.Mock<T>().Object
var fooMock = mock.MockRepository.Create<Foo>((String)null);
fooMock.SetupGet(f => f.Value).Returns("test");
// insert your instance into the container
mock.Provide<Foo>(fooMock.Object);
var bar = mock.Create<Bar>();
Console.WriteLine(bar.GetValue());
}
}
}
public class Foo
{
public Foo(String value)
{
this._value = value;
}
private readonly String _value;
public virtual String Value
{
get
{
return this._value;
}
}
}
public interface IBar
{
String GetValue();
}
public class Bar : IBar
{
public Bar(Foo foo)
{
this._foo = foo;
}
private readonly Foo _foo;
public String GetValue()
{
return this._foo.Value;
}
}
It is not a perfect solution but without big refactoring of the Autofac.Extras.Moq project I can't see any simpler way to do it.

Using statements in a web api

I found this code here
using (var objCtx = new SchoolDBEntities())
{
var schoolCourse = from cs in objCtx.Courses
where cs.CourseName == "Course1"
select cs;
Course mathCourse = schoolCourse.FirstOrDefault<Course>();
IList<Course> courseList = schoolCourse.ToList<Course>();
string courseName = mathCourse.CourseName;
}
And I am using it in a Get method of a web api. When i use a using statement I get the following error
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection
I I do not use it, then how would I dispose of the context object responsibly?
I use something like this to solve the problem without resorting to eager loading (in fact usually in a generic abstract base controller that I extend, but this example is simplified):
public class MyController : ApiController
{
private SchoolDBEntities _objCtx;
// Singleton ObjectContext
protected SchoolDBEntities objCtx
{
if(_objCtx == null) _objCtx = new SchoolDBEntities();
return _objCtx;
}
// Use singleton objCtx without using wrapper here, in Get() or other methods.
public String Get()
{
var schoolCourse = from cs in objCtx.Courses
where cs.CourseName == "Course1"
select cs;
Course mathCourse = schoolCourse.FirstOrDefault<Course>();
string courseName = mathCourse.CourseName;
return courseName
}
// ApiController implements IDisposable, so you can override Dispose to do clean-up here.
// This is not called until the controller is disposed, so you won't get the error you report.
protected override void Dispose(Boolean disposing)
{
if (_objCtx!= null)
{
_objCtx.Dispose();
_objCtx = null;
}
base.Dispose(disposing);
}
}

Moq Automapper service in testmethod returns null while mapping

I'm building a website in MVC 4 & using Automapper to map from domain objects to Viewmodel objects. I have injected Automapper as stated here http://rical.blogspot.in/2012/06/mocking-automapper-in-unit-testing.html
and it's working fine inside action methods while debugging, but during unit testing the action method when I inject automapper service I find that service.map is returning null. But while debugging the mapping is fine. I'm not being able to find the reason, trying for over 4 hrs. I have a domain class called Interview & its corrosponding viewmodel as InterviewModel. I have initialized mapping as CreateMap(); in automapper profile config, that has been called from global startup method. Below is the controller & action...
public class NewsAndViewsController : Controller
{
private IInterviewRepository repository;
private IMappingService mappingService;
public NewsAndViewsController(IInterviewRepository productRepository, IMappingService autoMapperMappingService)
{
repository = productRepository;
mappingService = autoMapperMappingService;
}
[HttpPost, ValidateAntiForgeryToken]
[UserId]
public ActionResult Edit(InterviewModel interView, string userId)
{
if (ModelState.IsValid)
{
var interView1 = mappingService.Map<InterviewModel, Interview>(interView);
**// THE ABOVE LINE RETURNING NULL WHILE RUNNING THE BELOW TEST, BUT NOT DURING DEBUGGING**
repository.SaveInterview(interView1);
TempData["message"] = string.Format("{0} has been saved", interView.Interviewee);
return RedirectToAction("Create");
}
return View(interView);
}
}
[TestMethod]
public void AddInterview()
{
// Arrange
var interviewRepository = new Mock<IInterviewRepository>();
var mappingService = new Mock<IMappingService>();
var im = new InterviewModel { Interviewee="sanjay", Interviewer="sanjay", Content="abc" };
mappingService.Setup(m => m.Map<Interview, InterviewModel>(It.IsAny<Interview>())).Returns(im);
var controller = new NewsAndViewsController(interviewRepository.Object, mappingService.Object);
// Act
var result = controller.Edit(im, "2") as ViewResult;
// Assert - check the method result type
Assert.IsNotInstanceOfType(result, typeof(ViewResult));
}
In your test you've got your Interview and InterviewModel classes crossed up in the mappingService.Setup() call (as an aside, I think you could use better naming conventions, or don't use var, to keep your objects clear - "im", "interview" and "interview1" don't make it easy to follow which is the model and which is the view object).
Try this:
[TestMethod]
public void AddInterview()
{
// Arrange
var interviewRepository = new Mock<IInterviewRepository>();
var mappingService = new Mock<IMappingService>();
var interview = new Interview();
var im = new InterviewModel { Interviewee="sanjay", Interviewer="sanjay", Content="abc" };
mappingService.Setup(m => m.Map<InterviewModel, Interview>(im).Returns(interview);
var controller = new NewsAndViewsController(interviewRepository.Object, mappingService.Object);
// Act
var result = controller.Edit(im, "2") as ViewResult;
// Assert - check the method result type
Assert.IsNotInstanceOfType(result, typeof(ViewResult));
}

MongoDB custom serializer implementation

I am new to MongoDB, and am trying to get the C# driver to work serializing F# classes. I have it working with the class automapper using mutable F# fields & a parameterless constructor, but really I need to retain immutability, so I started looking at implementing an IBsonSerializer to perform custom serialization. I haven't found any documentation for writing one of these so have just tried to infer from the driver source code.
I have run into a problem whereby when the Deserialize method is called on the serializer, the CurrentBsonType is set to EndOfDocument rather than the start as I am expecting. I wrote the equivalent in C# just to make sure it wasn't some F# weirdness, but the problem persists. The serialization part seems to work fine and is queryable from the shell. Here is the sample code:
class Calendar {
public string Id { get; private set; }
public DateTime[] Holidays { get; private set; }
public Calendar(string id, DateTime[] holidays) {
Id = id;
Holidays = holidays;
}
}
class CalendarSerializer : BsonBaseSerializer {
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) {
var calendar = (Calendar) value;
bsonWriter.WriteStartDocument();
bsonWriter.WriteString("_id", calendar.Id);
bsonWriter.WriteName("holidays");
var ser = new ArraySerializer<DateTime>();
ser.Serialize(bsonWriter, typeof(DateTime[]), calendar.Holidays, null);
bsonWriter.WriteEndDocument();
}
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) {
if (nominalType != typeof(Calendar) || actualType != typeof(Calendar))
throw new BsonSerializationException();
if (bsonReader.CurrentBsonType != BsonType.Document)
throw new FileFormatException();
bsonReader.ReadStartDocument();
var id = bsonReader.ReadString("_id");
var ser = new ArraySerializer<DateTime>();
var holidays = (DateTime[])ser.Deserialize(bsonReader, typeof(DateTime[]), null);
bsonReader.ReadEndDocument();
return new Calendar(id, holidays);
}
public override bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator) {
var calendar = (Calendar) document;
id = calendar.Id;
idNominalType = typeof (string);
idGenerator = new StringObjectIdGenerator();
return true;
}
public override void SetDocumentId(object document, object id) {
throw new NotImplementedException("SetDocumentId is not implemented");
}
}
This blows up with FileFormatException in Deserialize when the CurrentBsonType is not Document. I am using the latest version 1.4 of the driver source.
I figured this out in the end. I should have used bsonReader.GetCurrentBsonType() instead of bsonReader.CurrentBsonType. This reads the BsonType in from the buffer rather than just looking at the last thing there. I also fixed a subsequent bug derserializing. The updated method looks like this:
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) {
if (nominalType != typeof(Calendar) || actualType != typeof(Calendar))
throw new BsonSerializationException();
if (bsonReader.GetCurrentBsonType() != BsonType.Document)
throw new FileFormatException();
bsonReader.ReadStartDocument();
var id = bsonReader.ReadString("_id");
bsonReader.ReadName();
var ser = new ArraySerializer<DateTime>();
var holidays = (DateTime[])ser.Deserialize(bsonReader, typeof(DateTime[]), null);
bsonReader.ReadEndDocument();
return new Calendar(id, holidays);
}

Resources