Saving to the database when the button in the view is clicked - c#

There are 2 models. The user is logging into the system. I want a value from the current model to be added to the logged in user's table when he clicks the button in the Forum View. Ogrenci Model enters the system. When the button is clicked, I want ProjectName to be added to the BekleyenProje column in the Ogrenci Model. How can I do that?
Model 1:
public class Ogrenci
{
public int OgrenciID { get; set; }
public int OgrenciNumarasi { get; set; }
public string Ad { get; set; }
public string Soyad { get; set; }
public string Bolum { get; set; }
public short Sinif { get; set; }
public string Yetenekler { get; set; }
public string Sifre { get; set; }
public string BekleyenProje { get; set; }
public string OnaylananProje { get; set; }
//FK
public List<Proje> Projeler { get; set; }
}
Model 2:
public class Proje
{
public int ProjeID { get; set; }
public string ProjeAdi { get; set; }
public string Aciklama { get; set; }
public DateTime EklenmeTarihi { get; set; }
//FK
public int OgrenciID { get; set; }
public Ogrenci Ogrenci { get; set; }
}
ForumController:
public class ForumController : Controller
{
private OgrenciContext db = new OgrenciContext();
// GET: Forum
public ActionResult Index()
{
//Include(o => o.Ogrenci) -- öğrenci bilgilerini dahil ediyoruz
return View(db.Projeler.Include(o => o.Ogrenci).ToList());
}
}
Forum Index View (The button I'm talking about is here):
#model IEnumerable<DonemProjesi.Models.Proje>
#{
ViewBag.Title = "Index";
}
<table class="table table-striped table-bordered table-hover table-condensed cols-3 custom_table">
<thead>
<tr>
<th scope="col">Proje</th>
<th scope="col">Etkileşimler</th>
<th scope="col">Yayınlanma Tarihi</th>
<th scope="col">Detay</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
<div>#Html.DisplayFor(modelItem => item.ProjeAdi)</div>
<small>#Html.DisplayFor(modelItem => item.Ogrenci.Ad)</small>
</td>
<td>
<ul class="activity_outer">
<li><strong>03</strong><span>Başvuranlar</span></li>
<li><strong>01</strong><span>Dahil olanlar</span></li>
</ul>
</td>
<td>
<div class="last_activity"><span class="time_ago">#Html.DisplayFor(modelItem => item.EklenmeTarihi)</span></div>
</td>
<td>
<button type="button" class="login-button">#Html.ActionLink("Proje Detayı", "Details", "Proje", new { id = item.ProjeID }, new { #class = "detayy" })</button>
<button type="button" class="login-button"></button> //BUTTON IS HERE
</td>
</tr>
}
</tbody>
Also, Controller for Login:
public class SecurityController : Controller
{
OgrenciContext db = new OgrenciContext();
// GET: Security
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(Ogrenci ogrenci)
{
var kullanici = db.Ogrenciler.FirstOrDefault(x=>x.OgrenciNumarasi == ogrenci.OgrenciNumarasi && x.Sifre == ogrenci.Sifre);
if (kullanici!=null)
{
FormsAuthentication.SetAuthCookie(kullanici.Ad, false);
Session.Add("OgrenciID", kullanici.OgrenciID); //kimlik doğrulamasu yapılan kullanıcının ID'si alınıyor
return RedirectToAction("Details","Ogrenci", new {#id=kullanici.OgrenciID });
}
else
{
ViewBag.Mesaj = "Geçersiz numara veya şifre girdiniz!";
return View();
}
}
}

It's better to use repository pattern, but a direct solution would be:
kullanici.BekleyenProje = Request["ProjectName"];
db.SaveChanges();
Also it depends on how many properties you want to pass. If it's only one, you can send it in the Request. Otherwise, you create a view model with the necessary members.
Make sure the button is submitting the form and ProjectName is a hidden field inside the form.

Related

The model item passed into the dictionary is of type 'System.Collections.Generic.List'1 requires a model item of type '.Generic.IEnumerable

I am trying to pull all the USERS created in the database(AspNetUsers) using Register form.
I have read several similar issues but can't fix this issue.Usually the reason for this error is when we try to pull a list from the controller but in view we do not specify IEnumerable at top.However I have added that as well , please see the code below. Million thanks for any help in advance.
#model IEnumerable<TimeSheet.ViewModel.UserViewModel>
#using TimeSheet.Models
#{
ViewBag.Title = "Index";
}
<h2>Manage User</h2>
<br/>
<table class="table table-condensed table-hover">
<tr class="table-header">
<th>
#Html.DisplayNameFor(m => m.Email)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(m => item.Email)
</td>
<td>
#Html.Partial("_TableButtonPartial", new IndividualButtonPartial { UserId = item.Id })
</td>
</tr>
}
</table>
UserController
public class UserController : Controller
{
TimeSheetEntities db = new TimeSheetEntities();
/* private ApplicationDbContext db;
public UserController()
{
db = ApplicationDbContext.Create();
}*/
// GET: User
public ActionResult Index()
{
return View(db.AspNetUsers.ToList());
//return View();
}
}
UserViewModel
namespace TimeSheet.ViewModel
{
public class UserViewModel
{
[Required]
public string Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string FullName { get { return this.FirstName + " " + this.LastName; } }
[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }
public string UserRole { get; set; }
public string Manager { get; set; }
}
}
Since your are using mostly email,the easiest way to fix would be to change a model class
#model List<AspNetUser>
or if you want to save some network traffic, you can go a long way
create this viewmodel
public class UserGridViewModel
{
public string Id { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
}
fix the action
public ActionResult Index()
{
var model= db.AspNetUsers.Select(i=> new UserGridViewModel {
Id=i.Id,
Email=i.Email
}).ToList();
return View(model);
}
and view
#model List<TimeSheet.ViewModel.UserGridViewModel>

HTML BeginCollectionItem returns NULL

HTML.BeginCollectionItem does not return values to the controller. It always return NULL in the controller. I am not sure if has got anything to do if there is a partial view within another partial view. Below is the snippet of the code/view.
ProductEditModel
public class ProductEditModel
{
// Product details displayed on edit form
public Product ProductModel { get; set; }
public IList<ProductAssetAudioEditModel> ProductAssetAudios { get; set;}
}
ProductAssetAudioEditModel
public class ProductAssetAudioEditModel
{
public int ProductId { get; set; }
public int? ProductAssetId { get; set; }
public virtual IList<ProductAssetResourceEditModel> ProductAssetResources { get; set; }
}
ProductAssetResourceEditModel
public class ProductAssetResourceEditModel
{
public int? ProductAssetResourceId { get; set; }
public int ProductAssetId { get; set; }
public int ResourceNumber { get; set; }
public int? ElectronicFileId { get; set; }
public ElectronicFile ElectronicFile { get; set; }
}
ProductEditView.cshtml
<div id="audio">
#foreach (ProductAssetAudioEditModel audio in Model.ProductAssetAudios)
{
Html.RenderPartial("_ProductAssetAudioRow", audio);
}
</div>
_ProductAssetAudioRow.cshtml
#using (Html.BeginCollectionItem("ProductAssetAudios"))
{
....
<tbody>
#foreach (var resource in Model.ProductAssetResources)
{
Html.RenderPartial("_ProductAssetAudioResource", resource);
}
</tbody>
.....
}
_ProductAssetAudioResource
#using (Html.BeginCollectionItem("ProductAssetResources"))
{
#Html.HiddenFor(m => Model.ProductAssetResourceId)
#Html.HiddenFor(m => Model.ProductAssetId)
<td>
#if (Model.ElectronicFileId.HasValue)
{
#Html.HiddenFor(model => model.ElectronicFileId)
#Html.ActionLink(Model.ElectronicFile.FileName, "Details", "File", new { id = Model.ElectronicFileId, area = "Edi" }, null);
}
</td>
<td>
#Html.EditorFor(c => Model.TrackTitle)
</td>
}
In the controller , ProductAssetResources is NULL even though edit page binds the properties correctly for editing.
I am not sure what I am missing here.
-Alan-

passing string to controller/action from view

I am trying to lower the role of a user by clicking a link in my view.
When I click the link, it doesn't go to the action, but it just gives 404 error and links the resource that is not found with the string I am trying to pass to the action( referred to as "stringparameter")
In this case, the link is /Admin/Disable/stringparameter
I think I am not using the correct overload, so could someone help me out?
Thanks
This is the action in the AdminController
[HttpPost]
public ActionResult Disable(string id)
{
Role rol = new UserRepository().GetRole("Disabled");
new UserRepository().UpdateUser(id,rol.RoleId);
return RedirectToAction("Users");
}
this is the viewmodel
public class UserSuperUserPM
{
public UserClass User { get; set; }
public List<UserClass> Users { get; set; }
public UserClass SuperUser { get; set; }
public List<UserClass> SuperUsers { get; set; }
public UserClass Disabled { get; set; }
public List<UserClass> Disableds { get; set; }
public UserClass Inactive { get; set; }
public List<UserClass> Inactives { get; set; }
}
this is the userclass
public class UserClass
{
public string UserId { get; set; }
public string Username { get; set; }
public string Role { get; set; }
}
and this is the view(1 of the 4 similar tables in the view)
#foreach (var item in Model.Users)
{
<tr>
<td class="col-md-4">
#Html.DisplayFor(modelItem => item.Username, Model.Users)
</td>
<td class="col-md-4">
#Html.DisplayFor(modelItem => item.Role, Model.Users)
</td>
<td calss="col-md-4">
--------Commented attempted links(none of them work correct)
#*#Html.ActionLink("Disable", "Disable", new { Controller = "Admin", action = "Disable", id = item.UserId })*#
#*Disable*#
#*#Html.ActionLink("Disable","Admin", new { id = item.UserId },null)*#
#*#Html.ActionLink("Disable", "Disable","Admin", item.UserId)*#
-------original attempted link
#Html.ActionLink("Disable", "Disable", new { id = item.UserId})
</td>
</tr>
}
It's because href attr in a a element just do GET dont POST, so to it works change the Action to :
[HttpGet]
public ActionResult Disable(string id)
{
Role rol = new UserRepository().GetRole("Disabled");
new UserRepository().UpdateUser(id,rol.RoleId);
return RedirectToAction("Users");
}
But I suggest to you do this with JS.
Just delete [HttpPost] it says that this controller only can be access by POST method an you are trying to access by GET, you should let it post and do the call with AJAx

How to display create form in an existing MVC 4 view and C#

I have view to display Restaurant. In this view at the bottom of the page, I want to display Comments form to add comments about that Restaurant.
Can someone please help me to do this using MVC 4 & C#.
My Models has the followign two tables:
/Classifieds TABLE
public class Classifieds
{
[Key]
public string C_Unique_Id { get; set; }
public string AdType { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
//ClassifiedsComments TABLE
public class ClassifiedsComments
{
[Key]
public string CCommentsUniqueId { get; set; }
public string CommentAuthor { get; set; }
public string Comment { get; set; }
[ForeignKey("Classifieds")]
public string C_Unique_Id { get; set; } //this is the foreign key of Classified record
public virtual Classifieds Classifieds { get; set; }
}
Classifieds Details view:
#model SomeIndianShit.Models.Classifieds
#{
ViewBag.Title = "Details";
}
<table class="recordDetailsDisplayTableStype">
<tr>
<td colspan="2" align="left">
#Html.DisplayFor(model => model.Description)
<br /><br />
</td>
</tr>
<tr>
<td>
Ad Type
</td>
<td align="left"> :
#Html.DisplayFor(model => model.AdType)
</td>
</tr>
SOME OTHER FIELDS DISPLAY HERE
</table>
//Here I want to display "ClassifiedsComments" form to add comments to above Classified.
//HOW can I display the ClassifiedsComments create.cshtml code here??
Try this:
With View:
#using (Html.BeginForm("Classifieds", "ClassifiedsDetails", FormMethod.Post))
and
#using (Html.BeginForm("ClassifiedsComments", "ClassifiedsDetails", FormMethod.Post))
And use 1 Model for this:
public class ClassifiedsDetails
{
public Classifieds Model1{ get; set; }
public ClassifiedsComments Model2{ get; set; }
}
Update:
public class ClassifiedsDetails
{
public ClassifiedsDetails()
{
Model1 = new Classifieds();
Model2 = new ClassifiedsComments();
}
public Classifieds Model1{ get; set; }
public ClassifiedsComments Model2{ get; set; }
}
public class Classifieds
{
public Classifieds()
{
C_Unique_Id = String.Emty;
AdType = String.Emty;
//---- Add default setting here------
}
[Key]
public string C_Unique_Id { get; set; }
public string AdType { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
Or display list of comments in View with Model:
public class ClassifiedsDetails
{
public ClassifiedsDetails()
{
Model1 = new Classifieds();
Model2 = new List<ClassifiedsComments>();
}
public Classifieds Model1{ get; set; }
public List<ClassifiedsComments> Model2{ get; set; }
}
View:
#model ClassifiedsDetails
#Html.LabelFor(model => model.Model1.Title)
#foreach (var items in Model.Model2)
{
#item. //fields
}
To display data in view create view model, but to post comment, dont use model:
public class ClassifiedsViewModel
{
public ClassifiedsViewModel()
{
Comments = new List<ClassifiedsComments>();
}
public Classifieds Classifieds { get; set; }
public List<ClassifiedsComments> Comments { get; set; }
}
Fill this view model, use in view to display details and comments like above you write.
if(Model != null && Model.Classifieds != null)
{
<table> ...display details.. </table>
}
if(Model != null && Model.Comments != null)
{
<table> ...display comments with foreach loop.. </table>
}
And at bottom, create comment post form
#using (Html.BeginForm("SaveComment", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
//set to which Classifieds will this comment posted
#Html.Hidden("C_Unique_Id", Model.Classifieds.C_Unique_Id)
<fieldset>
#Html.TextBox("Comment")
//other fields ....
<input type="submit" value="Save" />
</fieldset>
}
Edit2: View model creating:
public ActionResult Details(int id)
{
//add breakpoint here and follow any step.
ClassifiedsViewModel viewModel = new ClassifiedsViewModel();
viewModel.Classifieds = db.Classifieds.Find(id);
viewModel.Comments = db.LoadCommentsByClassifiedsId(id); //create db method
// or instead of this line use:
viewModel.Comments = db.ClassifiedsComments.Where(e => e.C_Unique_Id == id).ToList();
return(viewModel);
}
You can then add a ViewModel like this
public class ClassifiedsDetailViewModel
{
public ClassifiedsDetailViewModel()
{
ClassifiedsComments = new ClassifiedsComments();
}
public Classifieds Classifieds { get; set; }
public ClassifiedsComments ClassifiedsComments { get; set; }
}
Pass this view model to your view and then add #Html.Partial("_CreateClassifiedsCommentsFormPartial", Model.ClassifiedComments) below the table. And in your partial view, you can use Html.BeginForm or the Ajax.BeginForm.
See sample here

How to keep selected value after clicking submitbutton in asp.net mvc 3?

Hi; i have 2 dropdownlist. one is customers ddl another one is jobs. i want to keep alive selected value after any selection process. But i can not.
i want to keep selected value on ddl'selected item After click button. (i have been used 2 methods: dropdownlist and dropdownlistfor.) My favorite articles are http://stackoverflow.com/questions/6981698/how-to-keep-dropdownlist-selected-value-after-postback
and
http://stackoverflow.com/questions/4950798/how-to-post-the-selected-value-of-a-selectlist-to-the-controller-using-a-view-mo
ViewModel:
public class MyViewModel
{
public IEnumerable<string> Columns { get; set; }
public IEnumerable<dynamic> Values { get; set; }
public bool HasNext { get; set; }
public bool HasPrevious { get; set; }
public IEnumerable<CustomerModel> Customers { get; set; }
public IEnumerable<SelectListItem> Jobs { get; set; }
}
Cotroller:
public class JobController : Controller
{
public ActionResult Index(int? page)
{
var model = new MyViewModel();
model.Customers = CustomerOperation.GetCustomers().Items;
ViewData["Jobs"] = new SelectList(JobOperation.GetCustomersAssemblyList().Items, "scheduleId", "name", null);
return View(model);
}
View:
<table style="padding:25px; margin:10px 10px 10px 10px; width:800px" id="sample">
<tr>
<td>Customer Name: </td>
<td>
<%= Html.DropDownListFor(X=>X.Customers,new SelectList(Model.Customers,"Id","Name"),"** Please Select **", new { id = "ddlCustomers" })%>
</td>
<td>Job Name:</td>
<td>
<%= Html.DropDownList("Jobs", (IEnumerable<SelectListItem>)ViewData["Jobs"], "** Please Select **", new { id = "ddlJobs", disabled = "disabled" })%>
</td>
<td>
<input value="monitor" name="submitButton" type="submit" />
</td>
</tr>
</table>
Your model should be something like this
public class MyViewModel
{
public IEnumerable<string> Columns { get; set; }
public IEnumerable<dynamic> Values { get; set; }
public bool HasNext { get; set; }
public bool HasPrevious { get; set; }
public IEnumerable<CustomerModel> Customers { get; set; }
public IEnumerable<SelectListItem> Jobs { get; set; }
public CustomerModel Customer {get; set;}
}
In your view the code to add dropdown should be something like this
<%= Html.DropDownListFor(X=>X.Customer,Model.Customers) %>
Hope this helps.

Categories

Resources