I have an ASP.NET application I'm developing. In it is a CR report. When I first wrote the report, I had it hard coded to point to my development server (using MSSQL with Windows integrated login). So, when I moved my app to the production server, it of course failed.
I have been searching for an answer on how to connect it to DB listed in the Web.config, but haven't had any luck.
I saw one suggestion that I create a dataset in my project and tie in to that, but now it seems I can't use a parameter to filter the records.
I did see one other suggestion on how you can change the DB source on the fly, but that was designed for those who want to change the DB in mid session, rather than dependent on the machine, and seemed overkill.
Does anyone have a nice simple solution? I have been working on this problem for way too long and feel that I'm about to shoot my computer (that will teach it a lesson). :-(
public static class ReportDocumentExtensions
{
public static void SetConnectionInfo(this ReportDocument report, ReportContextArgs context)
{
SetConnectionInfo(report, context.UserId, context.Password, context.ServerName, context.DatabaseName);
}
public static void SetConnectionInfo(this ReportDocument report, string userId, string password, string serverName, string databaseName)
{
foreach (Table oTable in report.Database.Tables)
{
TableLogOnInfo oInfo = oTable.LogOnInfo;
ConnectionInfo oConnection = oTable.LogOnInfo.ConnectionInfo;
oConnection.UserID = userId;
oConnection.Password = password;
oConnection.ServerName = serverName;
oConnection.DatabaseName = databaseName;
oTable.ApplyLogOnInfo(oInfo);
}
}
}
public class ReportContextArgs
{
private string _userId;
private string _password;
private string _serverName;
private string _databaseName;
public string ServerName
{
get { return _serverName; }
set { _serverName = value; }
}
public string UserId
{
get { return _userId; }
set { _userId = value; }
}
public string Password
{
get { return _password; }
set { _password = value; }
}
public string DatabaseName
{
get { return _databaseName; }
set { _databaseName = value; }
}
}
Related
I'm currently stuck on accessing all of the 'UserName' values from my database.
I am doing this so I can compare the user input for a username to check if it has been used before (I don't want two instances of the same username). This is on a .cshtml.cs page.
I am already able to access the database through my program, as create commands have been tested and do work.
My program is on ASP.NET 6.0 Core Web App.
I am a student with basic knowledge on ASP.NET Core, and on how to solve this issue, therefore as much simplified explanation would be very appreciated.
Here is my code:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using AQA_A_Level_CS_NEA__Suvat_Solver_.Models;
using AQA_A_Level_CS_NEA__Suvat_Solver_.Data;
namespace AQA_A_Level_CS_NEA__Suvat_Solver_.Pages.UserLogin
{
[BindProperties(SupportsGet = true)]
public class RegisterPageModel : PageModel
{
public new TempUserLoginModel TempUser { get; set; }
public bool HasPassword { get; set; } = true;
public bool HasUsername { get; set; } = true;
public bool UniUsername { get; set; } = true;
public bool RegisterApproved { get; set; } = false;
public bool AQAPhys { get; set; } = false;
public bool AQAMaths { get; set; } = false;
public bool SubjectChosen { get; set; } = true;
private readonly ApplicationDbContext _context;
public RegisterPageModel(ApplicationDbContext context)
{
_context = context;
}
public List<User> UserList = new List<User>();
public void OnGet()
{
}
public IActionResult OnPost()
{
User User = new User();
HasPassword = true;
HasUsername = true;
UniUsername = true;
SubjectChosen = true;
UserList = _context.User.ToList();
if (!AQAMaths && !AQAPhys)
{
SubjectChosen = false;
}
if (string.IsNullOrWhiteSpace(TempUser.Password) || TempUser.Password.Length < 4)
{
HasPassword = false;
}
if (string.IsNullOrWhiteSpace(TempUser.Username) || TempUser.Username.Length < 4)
{
HasUsername = false;
}
if (TempUser.Username == //database UserName value here )
{
//Here would be where the Username is compared
//UniUsername = false;
}
if (!HasPassword || !HasUsername || !UniUsername || !SubjectChosen)
{
return RedirectToPage("/UserLogin/RegisterPage", new { HasPassword, HasUsername, UniUsername, SubjectChosen });
}
else
{
RegisterApproved = true;
User.UserName = TempUser.Username;
User.UserPass = TempUser.Password;
User.UserCorrectAnsw = 0;
User.UserTotalAnsw = 0;
_context.User.Add(User);
_context.SaveChanges();
return RedirectToPage("/UserLogin/LoginPage", new { RegisterApproved });
}
}
}
}
Many Thanks.
Probably the strongest method is to enforce the user name column to be unique at the database level using a Unique Constraint. That way if you try to add a user with a duplicate user name, the database will simply return an error.
This article shows how to create a Unique Constraint with Entity Framework
You can be sure that the database will not allow a user with a duplicate user name with this method. However, trying to add a duplicate user will create an error which you will have to either handle or prevent from occurring in the first place (which is what you are doing now)
So for the code you are using now, since you already have the users pulled from the database here:
UserList = _context.User.ToList();
We can use LINQ to check if any of the users Usernames in UserList matches the TempUser like this:
if (UserList.Any(x => x.Username == TempUser.Username))
{
//Here would be where the Username is compared
UniUsername = false;
}
Since you didn't share your User model, this assumes your User class has a property named Username.
Happy Coding
I have an SQLite database. I work with it using EclipseLink and JPA. In addition I have an entity class User:
import com.vaadin.server.VaadinService;
import java.io.Serializable;
import javax.persistence.*;
#Entity
public class User implements Serializable {
#Id #GeneratedValue
long id; // Unique identifier of the user in the DB
String username; // Unique name used for login
String password; // Password used for login
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public Long getId() {
return id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
In a registration form I create a user and then call an EntityManager to persist() the changes:
public int createUser(String username, String password, String password_confirmation) {
int regStatus = 0;
if(checkValidUsername(username)) {
if(checkValidPassword(password, password_confirmation)) {
EntityManager em = factory.createEntityManager();
try {
em.getTransaction().begin();
User user = new User(username, password);
em.persist(user);
em.getTransaction().commit();
}
catch(Exception e) {
System.out.println(e.getMessage());
regStatus = 3;
}
finally {
em.close();
}
}
else regStatus = 2; // Password mismatch
}
else regStatus = 1; // User with selected username already present in DB
return regStatus;
}
It works without any problems. I get each and every newly registered user in my USER table. However when I try to change the password it doesn't work. Here are the methods that are related to this procedure:
// Inside the controller for my settings view - here the user can change various things related to his/her profile
public void setCurrentUser() {
currentUser = UserController.findUserByName((String)VaadinSession.getCurrent().getAttribute("username")); // findUserByName() is a static method
}
// Inside the User controller I have multiple methods for common user-related queries; here I use the username that I have retrieved from the VaadinSession's attribute "username" to execute a query and get the User entity (I make sure that a user's name is unique so getting a single result here is not a problem)
public static User findUserByName(String username) {
if(username == null) return null;
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
User user = null;
try{
Query q = em.createQuery("SELECT u FROM User u WHERE u.username = :username");
q.setParameter("username", username);
user = (User)q.getSingleResult();
}
catch(Exception e){
System.err.println(e.getMessage());
}
finally {
em.close();
}
return user;
}
// Inside the controller fpr my settings view (where I change the password)
public int changePassword(String currentPassword, String newPassword, String newPasswordConfirmation) {
if(newPassword.isEmpty()) return 1;
if(!newPassword.equals(newPasswordConfirmation)) return 2; // Incorrect confirmation
if(!currentPassword.equals(currentUser.getPassword())) return 3; // Given current password doesn't match the one stored in the database for this user
int resStatus = 0;
EntityManager em = factory.createEntityManager();
try {
em.getTransaction().begin();
currentUser.setPassword(newPassword);
em.getTransaction().commit(); // NO ERRORS at all...
}
catch(Exception e) {
System.out.println(e.getMessage());
resStatus = 4; // Exception
}
finally {
em.close();
}
return resStatus;
}
I have also tried using EntityManager.find(...), which should return the same row from the USER table (and it does) but the result is again the same - transaction begins, finishes, entity manager closes but the table USER for the supposedly changed user is the same.
Any ideas? I have used the same routine in another project but for setting other things. The database there was PostreSQL and I haven't encountered such issues. Here with the SQLite database I get no errors but the commit fails somehow.
I just develop with hibernate etc. but it will be the same, because both implements JPA.
If you start a transaction JPA will remember all entities you load in this transaction and if you change something you will see the changes in db (after commit).
But in your transaction JPA don't recognize your entity and so the changes will not persists. Try to load the entity in the transaction. Like...
em.getTransaction().begin();
em.find(User.class, currentUser.getId()); //Reload the User from db, so it is attached to the session
currentUser.setPassword(newPassword);
em.getTransaction().commit();
More Information about the methods:
https://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#refresh(java.lang.Object)
https://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#merge(T)
http://www.objectdb.com/java/jpa/persistence/managed
there is my problem;
I need to use sqlite in my wp8.1 app, i have install the nugets, extensions etc.
I have to save a JSON string into my db.
I know that i have to create a class that i will use to create the table of my sqlite.
Next to that, i know that i have to do a create fct for the table, a insert fct to put my Json string into my table, and a read to get it back and to use that.
I have find tutorial etc and each time i am trying something, it does not work.
I am not a pro in c# and in windows phone 8.1, i am not pro in database. I am in front of a big wall since 3days.
Does anyone can help me plz?
Thank you verry much.
I have create a Json class for my table;
Here is the code:
namespace PhoneApp5.Model
{
public class Json
{
[PrimaryKey]
public string Key { get; set; } //Key for my table
public string String { get; set; } //value String Json for my table
}
}
And then i create some fontion to use the table:
private async void CreateTable() // create my table
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection("blog");
await conn.CreateTableAsync<Json>();
}
public async void InsertJson(Json json) // insert my Json into my table
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection("blog");
await conn.InsertAsync(json);
}
public async Task<Json> GetJson(string Key) // read my Json string from table
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection("blog");
var query = conn.Table<Json>().Where(x => x.Key == Key);
var result = await query.ToListAsync();
return result; // result here is not working because of convertion of System.Connection.Generic.List<PhoneApp5.Model.Json> into PhoneApp5.Model.Json
}
public async void UpdatePost(Json json) // fct update
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection("blog");
await conn.UpdateAsync(json);
}
public async void DeletePost(Json json) // fct delete
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection("blog");
await conn.DeleteAsync(json);
}
Then, i don't know what to do.
Thx you for helping
Currently we have a very strange issue on our production server. For a specific param in query string, we get the data for query string in other request. I'm trying to figure out if this behavior can be caused, by the way I use ConcurrentDictionary in IHttpHandler:
Below is pseudo code example:
public class MyHandler : IHttpHandler
{
private static ConcurrentDictionary<string, DataObject> _dataCache = new ConcurrentDictionary<string, DataObject>();
public virtual bool IsReusable
{
get { return true; }
}
public virtual void ProcessRequest(HttpContext context)
{
Func<DataObject> getDataMethod = () =>
{
return DataFactory.GetData(context.Request.QueryString["dataid"].ToLower());
}
string cacheKey = HttpUtility.UrlDecode(context.Request.QueryString["dataid"].ToLower());
DataObject infoItem = _dataCache .GetOrAdd(cacheKey, (key) => { return getDataMethod(); })
//Other processing code
}
}
So it happens that for "dataid=1" i get the data for "dataid=2"...
When getDataMethod is executed, can I be sure that it will access the relevant context?
I'm starting a web app that will be using asp.net membership services (with a sql server backend) to look after users and RavenDb for everything else.
I'm new to unit testing and would appreciate it if I can run past you what I've got so far with one example method.
This is HelixManager
public class HelixManager:IDisposable
{
private readonly IMembershipProvider _membership;
private readonly IRepository _repos;
public HelixManager()
{
_membership = new AspNetMembershipProvider();
_repos = new RavenRepository();
}
public HelixManager(IMembershipProvider membershipProvider, IRepository repos)
{
_membership = membershipProvider;
_repos = repos;
}
public User CreateAdmin(User newUser, string password)
{
if (String.IsNullOrEmpty(newUser.Email)) throw new ArgumentException("Email must be supplied");
if (String.IsNullOrEmpty(password)) throw new ArgumentException("Password must be supplied");
var memberId = _membership.CreateUser(newUser, password);
if (memberId != null)
{
_membership.AddToRole(newUser, "Admin");
newUser.Type = UserType.Admin;
newUser.MemberId = memberId;
_repos.Store<User>(newUser);
}
return newUser;
}
This is IMembershipProvider
public interface IMembershipProvider
{
string CreateUser(User newUser, string password);
void AddToRole(User user, string rolename);
}
and the implementation AspNetMembershipProvider
public class AspNetMembershipProvider : IMembershipProvider
{
public string CreateUser(User newUser, string password)
{
MembershipCreateStatus status;
MembershipUser memUser = System.Web.Security.Membership.CreateUser(newUser.Email, password, newUser.Email, "", "", true, out status);
return memUser.ProviderUserKey.ToString();
}
public void AddToRole(User user, string role)
{
Roles.AddUserToRole(user.Email, role);
}
}
This is IRepository
public interface IRepository
{
T Store<T>(T item);
}
and it's implementation
public class RavenRepository : IRepository
{
private readonly DocumentStore _store;
public RavenRepository()
{
_store = new DocumentStore { DefaultDatabase = "Helix", Url = "http://localhost:8080" };
_store.Initialize();
}
public T Store<T>(T item)
{
using (var session = _store.OpenSession())
{
session.Store(item);
session.SaveChanges();
}
return item;
}
}
In my test project, I have created fake implementations of both of these:
FakeMembershipProvider:
class FakeMembershipProvider : IMembershipProvider
{
public string CreateUser(User newUser, string password)
{
CreatedUser = true;
return newUser.Email == "email#example.com" ? Guid.NewGuid().ToString() : null;
}
public void AddToRole(User user, string rolename)
{
AddedToRole = true;
}
public bool AddedToRole;
public bool CreatedUser;
}
and FakeRepository:
public class FakeRepository : IRepository
{
public T Store<T>(T item)
{
StoreCalled = true;
return item;
}
public bool StoreCalled;
}
The tests are then approx as follows:
public class UserManagementTests
{
private readonly HelixManager _hm;
private readonly IMembershipProvider _fakeMembershipProvider;
private readonly IRepository _fakeRepository;
public UserManagementTests()
{
_fakeMembershipProvider = new FakeMembershipProvider();
_fakeRepository = new FakeRepository();
_hm = new HelixManager(_fakeMembershipProvider, _fakeRepository);
}
[TestMethod]
public void CreateAdminReturnsValidAdminUser()
{
var newUser = new User
{
AvatarName = "fred",
Email = "email#example.com",
Forename = "Fred",
Surname = "Jones"
};
_hm.CreateAdmin(newUser, "password");
Assert.IsNotNull(newUser.MemberId);
Assert.AreEqual(UserType.Admin, newUser.Type);
}
What am I asking is before I get any further down this line, is this the right way to be going about this? Or are there better ways of doing this?
I also plan to have an IntegrationTests project that will use a real db and a real RavenDb instance to test end to end.
Cheers,
Dave
I see nothing wrong with that approach. You could go the route of using a Mocking tool (Rhino Mocks, Moq, NSubstitute) to create your fakes instead of doing it by hand, but that is really a matter of personal preference and your personal comfort-level with the tools.
Your test is clearly structured, asserting based on state (which is a good thing), and your not trying to test too many things at once, which is a common mistake (even for those of us who have been doing this for a while).
If you haven't seen it yet, I can highly recommend Roy Osherove's Art of Unit Testing, which has a lot of very good information about unit testing, including things like keeping tests clean, how to deal with less-testable areas of code, etc.
I say keep truckin' :)
Your tests are look absolutely fine to me. Right approach (mocks) right way (AAA).
Go ahead :)
My problem is actually with this:
I'm starting a web app that will be
using asp.net membership services
(with a sql server backend) to look
after users and RavenDb for everything
else.
Why are you doing this?
It would be easier to make everything in RavenDB, and your unit testing issue would be as simple as new EmbeddableDocumentStore { RunInMemory = true }