Editing User Profile Data in SimpleMembership - asp.net-mvc-4

I am using SimpleMembership in an MVC4 web app. I can't figure out how to edit the profile information. I thought I could do it just as you do any other table.
[HttpPost]
public ActionResult EditUser(UserProfile user)
{
if (ModelState.IsValid)
{
udb.Entry(user).State = EntityState.Modified;
udb.SaveChanges();
return RedirectToAction("Index");
}
But I get an error saying entity state does not exist in the current context. My context is defined as follows at the top of the controller.
private UsersContext udb = new UsersContext();
I can find plenty of references on access profile data but nothing for editing the data. How can I save the edited UserProfile data back to the db?
EDIT: I was able to resolve the entityState error -- I had to include system.data and system.data.entity. However now when I run I get an error on edit which says unexpected number of rows modified (0). and points to the udb.SaveChanges() line. Still can't figure out how to modify UserProfile data elements.

Simple answer. I needed to set all the fields for the Model in my view. I was only allowing the user to change 4 out of the 6 so two were not being set.
I thought when you pass the model to the view, the view would pass the same field values onto the action if they were not set in the view. For example: if I set FirstName in the view but not UserName the original UserName that was sent to the view would be passed to the Model. That appears not to be the case. For all the items in the model I did not allow them to change in the view I had to set hidden fields to set the fields so a complete model was sent.
It may be better to set individual fields but I am not sure how to do that yet and that was not the question.

Related

Saving user ID with Entity Framework

I'm using entity framework v6.2.0 and ASP Net MVC to create a web page to access a database and edit the entries. The overwhelming majority of the code is the basic framework provided for me. The database is connected successfully and entries can be viewed, edited, and deleted. Additionally I have implemented some rudimentary paging, searching, and sorting as instructions are provided by microsoft on how to implement those. The last thing I need to do before the site is truly functional is to pull the userID from the users login and save that as the EnteredBy field before saving any changes or new entries to the table.
if (ModelState.IsValid)
{
string currentUserId = User.Identity.GetUserId();
yasukosKitchen.EnteredBy = currentUserId;
db.YasukosKitchens.Add(yasukosKitchen);
db.SaveChanges();
return RedirectToAction("Index");
}
This code seems very simple, and I added using Microsoft.AspNet.Identity; so it compiles fine. However when I attempt to test this code the EnteredBy field is left blank or null.
My search for information turned up a post suggesting the use of the following line of code.
ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId);
However when I attempt to add that I get an error, the ApplicationUser cannot be found and Users does not exist in this context. The fix for this is probably staring me in the face but my lack of experience and comprehension is killing me.
As suggested: My question is, how do I get and/or correctly add the UserId to my database entry?
If your Database Context has an entry to your YasukosKitchen table; usually something like this,
public virtual DbSet<YasukosKitchen> YasukosKitchens {get; set;}
and YasukosKitchen table has a column 'EnteredBy' (string 128 length), then you can post the value for the logged in user's Id straight from the View.
Add this to the very beginning of the Create view.
#using Microsoft.AspNet.Identity
#using Microsoft.AspNet.Identity.EntityFramework
At the end of the form just before the submit button, add this code.
#Html.HiddenFor(model => model.EnteredBy, new { #Value = User.Identity.GetUserId() })
I'm not sure what is the functionality of 'Users' table.

Preserving the value of ViewData MVC 4

I am working on MVC 4 where i have "ActionResult" method which is of login page, username and password are entered in textbox, based on the username(which is billnumber) after login it should pull the data of that respective billnumber(username), so currently everything is working fine, I am able to get the username from one view and send it to another for further verification, I have stored "username" and "usertypeID" in Viewdata and that value is passed to next view, but the data on ViewData will not stand for longer time, and even if we try to refresh the page multiple times(10 to 20 times), below are the code which i Have used to store and to access
this is where i store the value
public ActionResult ValidateLogIn(FormCollection postedFormData)
{
// codes
TempData["UsrName"] = LoginViewModel.LoginDataModel.UserName;
// codes
}
public ActionResult LandingPage()
{
ViewData["message"] = TempData["UsrName"].ToString();
ViewData["person"] =Convert.ToInt32(TempData["UserTypeID"]);
TempData.Keep();
PatientDetailsViewModel PatientDetailsViewModel = new PatientDetailsViewModel();
String PatID = Convert.ToString(ViewData["message"].ToString());
int PersonType = Convert.ToInt32(ViewData["person"]);
PatientUnderDoctorDetailsViewModel = PatientUnderDoctorDataAccessService.PatientUnderDocLogInEnquiry(PatID);
}
this is where i store it on viewdata
ViewData["message"] = TempData["UsrName"].ToString();
ViewData["person"] =Convert.ToInt32(TempData["UserTypeID"]);
TempData.Keep();
AND HERE IS WHERE I GET VALUES FROM VIEWDATA
String PatID = Convert.ToString(ViewData["message"].ToString());
int PersonType = Convert.ToInt32(ViewData["person"]);
I am passing PatID and PersonType as parameter to next method,
at beginning I wasn't using TempData.keep(); so when I refresh the page atleast once used to get error, tried searching and found TempData but i believe it is not much efficient for longer time, if I left application idle for 5 mins and then refreshes the page once , it generates error message since tempdata is empty(null)
WHAT I NEED
let me know is there any mistake i have done, or is there any better way to fix this issue, where data can be stored in variable until I quit the application
I hope this link will help you State Management In MVC
Don't use Temp data for this. it will be lost when the app pool refreshes or if you use another process (web garden).
User.Identity.Name will return the name of a validated user.
If you are passing data around you should be using Models and not ViewData or TempData or ViewBag.

MVC 4 System.NullReferenceException: Object reference not set to an instance of an object

This is where I'm getting my error.
#foreach(var entry in ViewBag.Entries){...}
I stepped through the program after entering values into a form.
The Entries are hitting the dB and in my controller it showed that the linq code hit the DB but when I returned the view, the object wasn't found?
here is the code in my controller
public ActionResult Index()
{
var mostRecentEntries =
(from entry in _db.Entries
orderby entry.DateAdded descending
select entry).Take(20);
return View();
}
If it'll help you this is coming straight out of a book ASP.net mvc 4 in Action by the Manning company around page 34.
As the error is trying to tell you, ViewBag.Entries is null.
If you want to use something in ViewBag, you need to put it there in the controller.

How to use a Model object across a number of Controllers?

SCENARIO: After the user has successfully logged in, I want to create an Account object (Account class is a part of my model) and fetch and store the user's information in it. I want this Account object to be accessible to all my controllers (HomeController, AccountController etc) and also, I want the ability to edit its content from inside any controller. (1) How can I achieve this scenario? (2) How can I pass a model object from one controller to another?
I intend to keep it till the user logs out
Then you can use session. But I suggest not saving a lot of information. So for example you have this model or entity:
public class AccountModel {
public int Id {get;set;}
public string Username {get;set;}
// and a whole lot more of properties
}
I suggest you just store an identifier field, either the Id or the Username. Then when another request comes in and you need to either validate the request or update that same model, you can:
Fetch the data again for that user and all relevant information
Update the necessary fields
Save it in your database
So you would do something like:
// to save it in a session after logging in
Session["current_user_id"] = id_variable;
// to retrieve it from session after another request comes in
var id = (int)Session["current_user_id"];
// fetch from your database
// do the necessary update
// persist the changes
(1) How can I achieve this scenario?
You could retrieve the Account model from your datastore when you need to access it.
(2) How can I pass a model object from one controller to another?
See (1). Since you are retrieving it from the data store you don't need to be passing it around.

MVC 4 Lookup UserName Based on UserId

I'm using the MVC 4 template with VS 2012. I have enabled a comments section which stores the logged in user's UserId to a table. When I display the comments I want to display the user's user name and email from the UserProfiles table.
I've tried the following code:
public static string GetUserName(int userId)
{
using (var db = new UsersContext())
{
return db.UserProfiles.Single(x => x.UserId == userId).UserName;
}
}
But I get an exception:
The model backing the 'UsersContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
Any suggestions?
The exception is pretty descriptive. Your model does not reflect what your database look like. I recommend you to read this about code first migrations, basically what migrations mean is that you update your database to match your models, its done with one line of command in VS.
Hope this helps
Also I would recommend you to use .Find() or .First() instead of .Single()