i have a project using ASP.Net MVC 3, and now i want to make user management.
i want to make it like this one : http://mrgsp.md:8080/awesome/user
how to make that user management ?
thanks a lot
I created a Model which references the MembershipUser but also allows for creating and editing users.
namespace MyProject.Models
{
public class AccountUser
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public virtual Guid UserId { get; set; }
[Display(Name="User Name")]
public virtual string UserName { get; set; }
[Display(Name = "E-mail")]
public virtual string Email { get; set; }
public virtual string Password { get; set; }
[Display(Name = "Approved")]
public virtual bool IsApproved { get; set; }
/* contructors based on string GUID or actual */
public AccountUser() { }
public AccountUser(string UID)
{
UserId = new Guid(UID);
Initialize();
}
public AccountUser(Guid UID)
{
UserId = UID;
Initialize();
}
/* loads Membership User into model to access other properties */
public virtual MembershipUser User
{
get
{
// note that I don't have a test for null in here,
// but should in a real case.
return Membership.GetUser(UserId);
}
}
/* do this once when opening a user instead of every time you access one of these three *
* as well as allow override when editing / creating */
private void Initialize()
{
UserName = User.UserName;
Email = User.Email;
IsApproved = User.IsApproved;
}
}
}
With this built, I created a Controller with my default data Context to allow it to create scaffolding for me. Then I removed the Context from the Controller.
namespace MyProject.Controllers
{
[Authorize]
public class AccountUserController : Controller
{
public ViewResult Index()
{
var memberList = Membership.GetAllUsers();
var model = new List<AccountUser>();
foreach (MembershipUser user in memberList)
{
model.Add(new AccountUser(user.ProviderUserKey.ToString()));
}
return View(model);
}
public ViewResult Details(Guid id)
{
AccountUser accountuser = new AccountUser(id);
return View(accountuser);
}
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(AccountUser myUser)
{
if (ModelState.IsValid)
{
Membership.CreateUser(myUser.UserName, myUser.Password, myUser.Email);
return RedirectToAction("Index");
}
return View(myUser);
}
public ActionResult Edit(Guid id)
{
AccountUser accountuser = new AccountUser(id);
return View(accountuser);
}
[HttpPost]
public ActionResult Edit(AccountUser accountuser)
{
if (ModelState.IsValid)
{
return RedirectToAction("Index");
}
return View(accountuser);
}
public ActionResult Delete(Guid id)
{
AccountUser accountuser = new AccountUser(id);
return View(accountuser);
}
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(Guid id)
{
AccountUser accountuser = new AccountUser(id);
Membership.DeleteUser(accountuser.User.UserName);
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
//db.Dispose();
base.Dispose(disposing);
}
}
}
The Views should all be pretty straight forward, but here's one for consistency
#model MyProject.Models.AccountUser
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>AccountUser</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
It was definitely a little tricky overall, mostly with getting the Model correct to allow you to read in from Membership as well as get a reasonable set of Views created. I actually did most of them by hand, but this will save you some time. Note that I omitted editing Password or Roles, but if you get this far, you shouldn't be too far off.
The following links were helpful:
Alternative User management in ASP.NET MVC
http://joymonscode.blogspot.com/2012/01/creating-simple-aspnet-mvc-3-razor.html
Create a new project mvc3 and download the awesome project from the Package Manager:
PM> Install-Package MvcProjectAwesome
Related
The Remote attribute is not firing to the controller on validation. Does anyone have a clue why not?
I have the following class:
public class XUser{
[Required]
[Range(0, 100, ErrorMessage = "This is an incorrect ID")] //Just a test
public int ID { get; set; }
[Required]
[Remote("CheckUsername", "Home")]
public string Name { get; set; }
[Required]
[RegularExpression(#"[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}", ErrorMessage ="This is not an email adres!")]
public string Email { get; set; }
}
The following Controller:
[HttpGet]
public IActionResult Edit(Int64 id) {
return View(users.Where(u => u.ID == id).SingleOrDefault());
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(XUser user) {
if (ModelState.IsValid) {
return RedirectToAction("Index");
} else {
return View(user);
}
}
[HttpGet]
public JsonResult CheckUsername(string Name) {
return Json(false);
}
And last but not least, the following view:
#model XUser
#using (Html.BeginForm("Edit", "Home", FormMethod.Post)) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.EditorFor(Model => Model.ID) #Html.ValidationMessageFor(Model => Model.ID)
#Html.EditorFor(Model => Model.Name) #Html.ValidationMessageFor(Model => Model.Name)
#Html.EditorFor(Model => Model.Email) #Html.ValidationMessageFor(Model => Model.Email)
<input type="submit" value="Save" />
}
In my _Layout I have the following scripts included:
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
I also tried the following:
//Class
[Required]
[Remote("CheckUsername", "Home", HttpMethod = "POST")]
public string Name { get; set; }
//Controller
[HttpPost]
[AllowAnonymous]
public JsonResult CheckUsername(string Name) {
return Json(false);
}
I will answer my own question for further reference, if anyone else will come along the same problem. I could've seen it in the solution explorer, but some things you just overlook and can save a lot of time!
With Fiddler I saw that the JQuery files were not found. The paths did not match anymore with MVC 4.0 / 5.0 paths.
They have been moved from:
~/Scripts/jquery.validate.min.js
~/Scripts/jquery.validate.unobtrusive.min.js
To:
~/lib/jquery-validation/dist/jquery.validate.js
~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js
Further; AllowAnonymous is not obligated to have as an attribute with Remote[] (For neither HttpPost or HttpGet).
I am performing Remote Validation in ASP.NET MVC3,but its not working means it not calling the action as I am seeing in Chrome java script Console.Here is my Code:
Model:
public class Genre
{
public int GenreId { get; set; }
[Remote("GenreNameExist","Genre",ErrorMessage="Genre name already Exists!!!")]
public string Name { get; set; }
public String Description { get; set; }
public List<Album> Albums { get; set; }
}
Controller:
public ActionResult GenreNameExist(Genre genre)
{
var gen = db.Genres.Where(x=>x.Name==genre.Name).FirstOrDefault();
if (gen == null)
{
return Json(true, JsonRequestBehavior.AllowGet);
}
else {
return Json(string.Format("{0} is not available.", Name), JsonRequestBehavior.AllowGet);
}
}
and View:
#Html.ValidationSummary(true);
<div class="editor-label">
#Html.LabelFor(x => x.Name)
</div>
<div class="editor-field">
#Html.TextBoxFor(x => x.Name)
#Html.ValidationMessageFor(x=>x.Name)
</div>
Thanks in Advance!!!
You need to add:
var gen = db.Genres.Where(x=>x.Name==Name).FirstOrDefault();
so it will execute.
In the controller pass the class Genre so it maps to that class and then add if(ModelState.IsValid) so it'll perform validation against that class. Or add a ViewModel class.
Update:
Do you have the scripts in the right order?
<script src="/Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
can't find whats wrong and can't find answer anywhere. My problem is my view not updated after view model have bean changed
ViewModel:
public class OrderView
{
public Customer Customer { get; set; }
public Order Order { get; set; }
}
public class Order
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
public List<string> DomenNames { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Telephone { get; set; }
public string Email { get; set; }
}
Controller:
private OrderView ov;
public ActionResult Index()
{
return View(ov);
}
[HttpPost]
public ActionResult Index(OrderView model, FormCollection collection) {
return View("done");
}
public ActionResult BlankEditorRow(OrderView model) {
ov = model;
ov.Order.DomenNames.Add("");
return View("Index",ov) ;
}
View:
#using (Html.BeginForm("Index","Order",FormMethod.Post, new {id = "createOrder"})) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Order</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Order.DomenNames)
</div>
#for(int i = 0; i < Model.Order.DomenNames.Count; i++) {
<div>
#Html.EditorFor(item => item.Order.DomenNames[i])
</div>
}
<button type="button" id="b1" onclick="setallert()" >Click me</button>
...
and script:
<script type="text/javascript">
function setallert() {
$.ajax({
url: "Order/BlankEditorRow",
data: $('#createOrder').serialize(),
cache: false,
success: function (data) {
...?
}
});
};
</script>
it goes fine to pass model to controller and while debugging through view I can see that model is changed, but in some case it nothing happen in view. It looks like old model is in place.
I have solved my problem. I post my solution in case some one need it:
Controller:
public ActionResult BlankEditorRow(OrderView model) {
model.Order.DomenNames.Add("");
return PartialView("Index", model) ;
}
View:
<div class="editor-label">
#Html.LabelFor(model => model.Order.DomenNames)
</div>
<div id="tt">
#{Html.RenderPartial("OrderDN", this.Model);}
</div>
<button type="button" id="addBtn">Click me</button>
Script:
$("#addBtn").click(function () {
$.get('#Url.Action("BlankEditorRow", "Order")', $('#createOrder').serialize(), function (res) {
document.getElementById("tt").innerHTML = res;
});
})
I hope it will be useful to someone
I can't find a sample with this simple problem.
I have 2 tables Books and Authors with a foreign key on AuthorID.
I need to be able to add a book with an author and that author to be inserted with the foreign key relation.
Is it possible from an create view and controller in MVC?
These are models:
namespace CiksAyna.Data.Model
{
[TableName("tbl_book")]
[PrimaryKey("book_id", autoIncrement = true)]
public class Book
{
[Column("book_id")]
public int BookId { get; set; }
[Column("author_id")]
public int AuthorId { get; set; }
}
}
namespace CiksAyna.Data.Model
{
[TableName("tbl_author")]
[PrimaryKey("author_id", autoIncrement = true)]
public class Author
{
[Column("author_id")]
public int AuthorId { get; set; }
[Column("author_name")]
public int AuthorName { get; set; }
}
}
In view page
#model CiksAyna.Data.Model.Book
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Books</legend>
<div class="editor-field">
#Html.DropDownListFor(model => model.AuthorId, new SelectList(ViewBag.Authors, "AuthorId", "AuthorName"))
#Html.ValidationMessageFor(model => model.AuthorId)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
In controller
public ActionResult Create()
{
ViewBag.Authors = GetAllAuthors();
return View();
}
public List<Author> GetAllAuthors()
{
return Db.From("tbl_author").ToList<Author>();
}
i have a model SiteMapModel that have a object VirtualFolderModel inside him.
public class SiteMapModel
{
public SiteMapModel(DataRow data)
{
SMF_ID = Convert.ToInt32(data["SMF_ID"]);
SMF_VF_ID = Convert.ToInt32(data["SMF_VF_ID"]);
VirtualFolder = new VirtualFolderModel(data);
}
public VirtualFolderModel VirtualFolder;
public int SMF_ID { get; set; }
public int SMF_VF_ID { get; set; }
}
public class VirtualFolderModel
{
public VirtualFolderModel(DataRow data)
{
VF_ID = Convert.ToInt32(data["VF_ID"]);
}
public int VF_ID { get; set; }
}
in my controller i pass the model to a view.
public ActionResult Edit(int id)
{
SiteMapData smd = new SiteMapData();
SiteMapModel smm = new SiteMapModel(smd.GetFolderData((int)id, 15));
return View(smm);
}
how to use it in my view?
<div>
<span class="editor-label">
#Html.Label("Title")
</span>
#Html.TextBox("SMF_Name")
#Html.ValidationMessage("SMF_Name")
<span class="editor-label">
#Html.Label("VF_ID")
</span>
#Html.TextBox("VF_ID")
#Html.ValidationMessage("VF_ID")
<input type="submit" value="Save" />
</div>
the #Html.TextBox("VF_ID") don't work
At the top of your view add this:
#ModelType SitemapModel
Edit: For C# please use:
#model SitemapModel
Doing that will simply tell your view what kind of model is given at runtime. In this case, it's an object of type SitemapModel.
In your view you can reference to it to model.SMF_ID