No view updating after viewmodel been changed - asp.net-mvc-3

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

Related

How do you send data to controller with ajax.beginform?

This is my method on controller "sale"
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Models.account account)
{
Models.sale creaventa = new Models.sale();
//creaventa.account = cliente;
creaventa.createdon = DateTime.Now;
creaventa.idaccount = account.id;
creaventa.modifiedon = DateTime.Now;
creaventa.status = 0;
context.sales.Add(creaventa);
context.SaveChanges();
// return "venta creada";
return View();
}
and this is the partial view
#model List<modal3.Models.account>
#{
ViewBag.Title = "Create";
}
<select class="form-control" id="control1">
#{
foreach (var cliente in Model)
{
<option value="#cliente.id"> #cliente.name</option>
}
}
</select>
#*#using (Html.BeginForm("create", "sale", FormMethod.Post, new {id="my-form" }))
{
#Html.AntiForgeryToken()
<button type="submit" class="btn btn-default" value="Create" id="btncrear">
Iniciar Venta
</button>
}*#
#using (
Ajax.BeginForm("create","sale",new AjaxOptions()
{
HttpMethod ="Post",
InsertionMode = InsertionMode.Replace,
})
)
{
#Html.AntiForgeryToken()
<button type="submit" class="btn btn-default" value="Create" id="btncrear">
Iniciar Venta
</button>
}
This does enter to method with this does not send the model.
Then:
How to send a model?
How to send a lot of objects?
this is my model
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace modal3.Models
{
using System;
using System.Collections.Generic;
public partial class sale
{
public sale()
{
this.saledetails = new HashSet<saledetail>();
}
public int id { get; set; }
public Nullable<System.DateTime> createdon { get; set; }
public Nullable<System.DateTime> modifiedon { get; set; }
public Nullable<int> status { get; set; }
public Nullable<int> idaccount { get; set; }
public virtual account account { get; set; }
public virtual ICollection<saledetail> saledetails { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace modal3.Models
{
[MetadataType (typeof (sale_validation ))]
public partial class sale
{
}
public class sale_validation
{
//2015-06-17 22:07:26.353 2015-06-17 22:07:26.353 1 1
[Display (Name="")]
[HiddenInput (DisplayValue =false )]
public Nullable<System.DateTime> createdon { get; set; }
[Display(Name = "")]
[HiddenInput(DisplayValue = false)]
public Nullable<System.DateTime> modifiedon { get; set; }
[Display(Name = "")]
[HiddenInput(DisplayValue = false)]
public Nullable<int> status { get; set; }
public Nullable<int> idaccount { get; set; }
}
}
To make you understand how AJAX FORM works, I created below code -
Lets say our model -
public class Sale
{
public string SaleOwner { get; set; }
public virtual Account Account { get; set; }
}
public class Account
{
public string Name { get; set; }
}
I created two controller actions -
public ActionResult adatas()
{
return View();
}
[HttpPost]
public JsonResult Create(Sale s)
{
return Json("true");
}
The first controller action return following view -
#model WebApplication1.Controllers.Sale
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
#using (Ajax.BeginForm("Create", "Sale", new AjaxOptions()
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "done"
}))
{
#Html.TextBoxFor(m => m.SaleOwner)
#Html.TextBoxFor(m => m.Account.Name)
<input type="submit" value="click" />
}
<div id="done">
</div>
View Renders as follows -
Once we click on button, with breakpoints in the code -
Once AJAX POST happens, output would be -

Remote Validation in MVC3

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>

User Management in ASP.Net MVC 3

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

asp.net mvc 3 remote attribute passing 3 fields

I want to pass three field to my controller using RemoteAttribute. How can i do it?
public int ID1 { get; set; }
public int ID2 { get; set; }
[Remote("CheckTopicExists", "Groups", AdditionalFields = "ID1", ErrorMessage = " ")]
public string Topic { get; set; }
public ActionResult CheckTopicExists(string topic, int ID1,int ID2)
{
return Json(true, JsonRequestBehavior.AllowGet);
}
How can i pass three field to that function?
You could separate them by comma:
AdditionalFields = "ID1, ID2"
Full example:
Model:
public class MyViewModel
{
public int ID1 { get; set; }
public int ID2 { get; set; }
[Remote("CheckTopicExists", "Home", AdditionalFields = "ID1, ID2", ErrorMessage = " ")]
public string Topic { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel
{
ID1 = 1,
ID2 = 2,
Topic = "sample topic"
});
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
public ActionResult CheckTopicExists(MyViewModel model)
{
return Json(false, JsonRequestBehavior.AllowGet);
}
}
View:
#model MyViewModel
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.EditorFor(x => x.ID1)
#Html.EditorFor(x => x.ID2)
#Html.LabelFor(x => x.Topic)
#Html.EditorFor(x => x.Topic)
#Html.ValidationMessageFor(x => x.Topic)
<input type="submit" value="OK" />
}
Be aware of sending dates, sometimes controller receive date in a wrong format: was dd/mm/yyyy, receive mm/dd/yyyy
Instead of using
public ActionResult CheckTopicExists(MyViewModel model)
If you use
public ActionResult CheckTopicExists(FormCollection Collection)
then you can reuse the code for other classes as well

how to get to object in a model?

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

Resources