when I try to add in my model some note appear Exception
Here is my CompetitionRepository where I implement method
public void AddCompetition(Competition competition)
{
if (competition.ID == 0)
_context.Competitions.Add(competition);
else
_context.Entry(competition).State = EntityState.Modified;
_context.SaveChanges();
}
Controller
[HttpPost]
public ActionResult AdminPCreate(string compName, int quantity, DateTime starTime)
{
if(ModelState.IsValid)
_dataManager.Competitions.AddCompetition(
new Competition
{
ID = 1,
Quantity = quantity,
StartTime = starTime,
});
return View("Competitions",GetCompetitions());
}
And cshtml Page, maybe I'm doing something wrong
#using (Html.BeginForm("AdminPCreate", "Home"))
{
#Html.TextBox("compName",null ,new {#placeholder = "Competition Name"})
#Html.TextBox("quantity", null, new {#placeholder = "Amount players"})
#Html.TextBox("starTime", null, new {#placeholder = "Enter beginnig of the match like dd\\mm\\yyyy"})
<input type="submit" value="Create" class="btn btn-success"/>
I also tried using a lot of solutions including here on that site, such as that
because when i try to use that (ObjectStateManager.GetObjectStateEntry(entity)`
because my field methods have type different from object
public void AddCompetition(Competition competition)
In the method AdminPCreate of your controller, you have new Competition { ID = 1, [..] }.
That ID valueof 1 makes your repository think it's an existing item, so Entity Framework tries to update the Competition record where ID = 1. That doesn't exist, so your database returns "0 rows affected" and the error is thrown.
I suspect that when you set the ID to 0 instead of 1 in your controller it'll work.
Related
after I read data from my database, I try to show those datas in Html.Helper checkbox and I do that. But later when I try to get checked values back to the controller, model always returns null. Here's my controller part:
[HttpGet]
public ActionResult NewClient()
{
HizmetModel hizmetModel = new HizmetModel();
hizmetModel.hizmet = db.Hizmet.ToList<Hizmet>();
return View(hizmetModel);
}
[HttpPost]
public ActionResult NewClientPost(string name, string lastname, string telephone, string plate, HizmetModel hizmet)
{
Musteri musteri = new Musteri();
if (!db.Musteri.Where(x => x.plaka == plate).Any())
{
musteri.isim = name;
musteri.soyisim = lastname;
musteri.telefon = telephone;
musteri.plaka = plate;
db.Musteri.Add(musteri);
db.SaveChanges();
}
Islem islem = new Islem();
IslemHizmet islemhizmet = new IslemHizmet();
islem.giristarihi = DateTime.Now;
islem.plaka = plate;
var selectedHizmet = hizmet.hizmet.Where(x => x.isChecked == true).ToList<Hizmet>();
db.Islem.Add(islem);
db.SaveChanges();
var onprocessplate = db.Islem.Where(x => x.plaka == plate).FirstOrDefault();
foreach (var item in selectedHizmet)
{
islemhizmet.islem_id = onprocessplate.islem_id;
islemhizmet.hizmet_id = item.hizmet_id;
db.IslemHizmet.Add(islemhizmet);
db.SaveChanges();
islemhizmet = new IslemHizmet();
}
TempData["Success"] = "Müşteri başarıyla eklendi...";
return RedirectToAction("CurrentClients", "Admin");
}
This is my model for the list:
public class HizmetModel
{
public List<Hizmet> hizmet { get; set; }
}
I use this model in the cshtml file:
#model otoyikama.Models.Model.HizmetModel
And this is the loop for displaying checkboxes
#for (int i = 0; i < Model.hizmet.Count; i++)
{
<li>
<label>#Model.hizmet[i].hizmetisim</label>
#Html.CheckBoxFor(m => m.hizmet[i].isChecked)
#Html.HiddenFor(m => m.hizmet[i].hizmet_id)
#Html.HiddenFor(m => m.hizmet[i].hizmetisim)
</li>
}
I couldn't figure what's the problem here, my get action works fine, I can see all the data from database but I can't pass them back to controller.
As a first think , u need to create a object in your controller parameters such as like List<int> serviceIDs or List<Service> services so you can keep more data than one.
The html part:
#foreach(item in Model.Service)
{
<label>#item.ServiceName</label><br>
<input type="checkbox" name="services" value="#item.ServiceID">
<input type="hidden" name="services" value="#item.ServiceName">
}
The backend part:
[HttpPost]
public ActionResult NewClientPost(string name, string lastname, string telephone, string plate, List<Service> services)
{
}
when u do in that way, u will able to hold more services than to one and i think u can pass them the controller more easly.
when i face with that stuation, im taking those services ID's and calling them on the controller side like bellow;
The html part:
#foreach(item in Model.Service)
{
<label>#item.ServiceName</label><br>
<input type="checkbox" name="serviceIDs" value="#item.ServiceID">
}
The backend part:
[HttpPost]
public ActionResult NewClientPost(string name, string lastname, string telephone, string plate, List<int> serviceIDs)
{
List<Service> services= new List<Service>();
foreach(var item in serviceIDs)
{
var service=db.Service.Where(x => x.ServiceID == item).Any()
if(service.Count!=0)
{
services.Add(service);
}
}
}
At the moment I'm trying to insert a value from two dropdown lists. The users aren't allowed to select both dropdown lists at the same time. One at a time.
I have tried different options now, so now I will show you what I have.
The user can select a value from two dropdown lists, when they have selected the radio button they want.
View
In this view, the user can select a value from one of the two dropdown lists.
<div id="Man">
#Html.DropDownList("SeriesID_Man", null, "Vælg serie / årgang", new { #class = "form-control", id = "ddlMan", string.Empty })
</div>
<div id="Women" style="display:none;">
#Html.DropDownList("SeriesID_Women", null, "Vælg serie / årgang", new { #class = "form-control", id = "ddlWomen", string.Empty })
</div>
Controller
In the HttpPost ActionResult method I try to save the selected values
[Route("opret-spiller")]
public ActionResult CreatePlayer()
{
ViewBag.ClubListID = new SelectList(db.ClubLists, "ClubListID", "ClubName");
ViewBag.PositionID = new SelectList(db.Positions, "PositionID", "PositionName", "PositionCategory", 0);
ViewBag.SeriesID_Man = new SelectList(db.Seriess.Where(x => x.GenderID == 0), "SeriesID", "SeriesName", "SeriesCategory", 0);
ViewBag.SeriesID_Women = new SelectList(db.Seriess.Where(x => x.GenderID == 1), "SeriesID", "SeriesName", "SeriesCategory", 0);
return View();
}
[Route("opret-spiller")]
[ValidateInput(false)]
[HttpPost]
public ActionResult CreatePlayer(PlayerProfileViewModel viewModel, Player player)
{
ViewBag.ClubListID = new SelectList(db.ClubLists, "ClubListID", "ClubName", player.ClubListID).SelectedValue;
ViewBag.PositionID = new SelectList(db.Positions, "PositionID", "PositionName", "PositionCategory", player.PositionID).SelectedValue;
ViewBag.SeriesID_Man = new SelectList(db.Seriess.Where(x => x.GenderID == 0), "SeriesID", "SeriesName", "SeriesCategory", 0).SelectedValue;
ViewBag.SeriesID_Women = new SelectList(db.Seriess.Where(x => x.GenderID == 1), "SeriesID", "SeriesName", "SeriesCategory", 0).SelectedValue;
Session["viewModel"] = viewModel;
Session["player"] = player;
return RedirectToAction("ChoosePlayerAbonnement");
}
Model
In my model class have I created two fields, that is not mapped to the database, the idea here was to save one of the selected values, from the dropdown lists in the view.
[NotMapped]
public int? SeriesID_Man { get; set; }
[NotMapped]
public int? SeriesID_Women { get; set; }
Repossitory
In the repo, I try to insert the value from SeriesID_Man, and SeriesID_Women into database.
SeriesID_Man = player.SeriesID,
SeriesID_Women = player.SeriesID,
I'm just getting started with MVC5 (from WebForms), and dropdownlist bindings are giving me some fits.
I'd like to get this working using a GET request back to the page, with a selected value parameter. I'm hopeful that I can specify the route arguments in the form itself, so I'd like to reference the DDL's SelectedValue.
<p>
#using (Html.BeginForm("Index", "Profile", FormMethod.Get, new { id = WHATDOIPUTHERE} )) {
#Html.AntiForgeryToken()
#Html.DropDownList("ApplicationID", new SelectList(ViewBag.ApplicationList, "ApplicationID", "ApplicationName", ViewBag.SelectedApplicationId), new {onchange = "this.form.submit();"})
}
</p>
I can make it work with a POST form, but that requires a second controller method so I end up with
public ActionResult Index(long? id) {
ConfigManager config = new ConfigManager();
//handle application. default to the first application returned if none is supplied.
ViewBag.ApplicationList = config.GetApplications().ToList();
if (id != null) {
ViewBag.SelectedApplicationId = (long)id;
}
else {
ViewBag.SelectedApplicationId = ViewBag.ApplicationList[0].ApplicationID; //just a safe default, if no param provided.
}
//handle profile list.
List<ProfileViewModel> ps = new List<ProfileViewModel>();
ps = (from p in config.GetProfilesByApp((long)ViewBag.SelectedApplicationId) select new ProfileViewModel(p)).ToList();
return View(ps);
}
//POST: Profile
//read the form post result, and recall Index, passing in the ID.
[HttpPost]
public ActionResult index(FormCollection collection) {
return RedirectToAction("Index", "Profile", new {id = collection["ApplicationId"]});
}
It would be really nice to get rid of the POST method, since this View only ever lists child entities.
What do you think?
You can update your GET action method parameter name to be same as your dropdown name.
I also made some small changes to avoid possible null reference exceptions.
public ActionResult Index(long? ApplicationID) {
var config = new ConfigManager();
var applicationList = config.GetApplications().ToList();
ViewBag.ApplicationList = applicationList ;
if (ApplicationID!= null) {
ViewBag.SelectedApplicationId = ApplicationID.Value;
}
else
{
if(applicationList.Any())
{
ViewBag.SelectedApplicationId = applicationList[0].ApplicationID;
}
}
var ps = new List<ProfileViewModel>();
ps = (from p in config.GetProfilesByApp((long)ViewBag.SelectedApplicationId)
select new ProfileViewModel(p)).ToList();
return View(ps);
}
This is My View
#using(#Html.BeginForm("CrmBlogGroupType","knowledge",FormMethod.Get)){
#Html.TextBox("search")
#Html.Hidden("type", (string)ViewBag.type)
#Html.DropDownList("PageSize",
new List<SelectListItem>()
{
new SelectListItem ()
{
Text="--Select Page Size--" ,Value="10",Selected=true
},
new SelectListItem ()
{
Text="View 20 records" ,Value="20"
},
new SelectListItem ()
{
Text="View 50 records" ,Value="50"
},
new SelectListItem ()
{
Text="View 100 records" ,Value="100"
},
})
<input type="submit" value="search" id="Searchbtn" />
<br />
#Html.CheckBox("Name")<text>Author Name</text>
#Html.CheckBox("AuthorTitle")<text>Title</text>
#Html.CheckBox("Description")<text>Description</text>
}
Here is the PagedList Code
#Html.PagedListPager(Model, page => Url.Action("CrmBlogGroupType",
new {page,Name=Request.QueryString["Name"].ToLower().Contains("true"),
AuthorTitle=Request.QueryString["AuthorTitle"].ToLower().Contains("true"),
Description=Request.QueryString["Description"].ToLower().Contains("true"), search=Request.QueryString["search"],PageSize=Request.QueryString["PageSize"],type=Request.QueryStrin g["type"]}),new PagedListRenderOptions()
{
DisplayLinkToFirstPage=true,DisplayLinkToLastPage=true,DisplayPageCountAndCurrentLocation=true,Displa yItemSliceAndTotal=true
,DisplayEllipsesWhenNotShowingAllPageNumbers=true,MaximumPageNumbersToDisplay=10
})
Controller Code
public ActionResult CrmBlogGroupType(int? page, bool? Name, bool? AuthorTitle, bool?Description, string search, int? PageSize, string type)
{
if (type==null)
{
//setting the Value in the initial call
//If the SP has changed then make the type parameter as the INT
type = "A";
}
IEnumerable<Usp_getBlogSetPosts_Result> _objBlogSet = _dataLayer.GetBlogSet(type).ToList().ToPagedList(page ?? 1, PageSize ?? 10);
return View(_objBlogSet);
}
Getting an ERROR :
Object reference not set to an instance of an object.
Line 202: #if (ViewBag.Search!=null && ViewBag.Search!=string.Empty)
Line 203:{
Line 204:#Html.PagedListPager(Model, page => Url.Action("CrmBlogGroupType", new { page,
Line 205:Name=Request.QueryString["Name"].ToLower().Contains("true"),AuthorTitle=Request.QueryString["Auth orTitle"].ToLower().Contains("true"),
Line 206:Description=Request.QueryString["Description"].ToLower().Contains("true"),
I've gone through some links by which i could make up the code like this, at last got stuck here
Any help on this is highly appreciated..
Use the ViewBag for passing the various parameters to the PagedListPager. Calculate the values in the controller and don't have complex logic in a view. Pulling parameters from querystring, when the controller has strongly typed values for those, is an unnecessary duplication of effort.
public ActionResult CrmBlogGroupType(int? page, bool? Name, bool? AuthorTitle, bool?Description, string search, int? PageSize, string type)
{
// Get the current values (or defaults == false) for the sorting
ViewBag.Name = Name.GetValueOrDefault();
ViewBag.AuthorTitle = AuthorTitle.GetValueOrDefault();
ViewBag.Description= Description.GetValueOrDefault();
and use them in the view like this:
#Html.PagedListPager(Model, page => Url.Action("CrmBlogGroupType",
new {page, Name=ViewBag.Name, AuthorTitle=ViewBag.AuthorTitle, Description=ViewBag.Description
etc
Update: 10,000 records is currently slow
From the comments below the current paging is slow. That is because the ToList() in the following line causes all records to be returned before any paging is applied to the LINQ query.
IEnumerable<Usp_getBlogSetPosts_Result> _objBlogSet =
_dataLayer.GetBlogSet(type)
.ToList() // <<<< THIS IS THE CULPRIT
.ToPagedList(page ?? 1, PageSize ?? 10);
ToPagedList is designed to work an an IQueryable so that when it adds Skip(n) and Take(n) to the query it will efficiently return just the page worth of records. Simply remove the ToList():
IEnumerable<Usp_getBlogSetPosts_Result> _objBlogSet =
_dataLayer.GetBlogSet(type)
.ToPagedList(page ?? 1, PageSize ?? 10);
I'm facing problems with a MVC5 Razor web application. I have an authentication page (cshtml) that has an Id and password helper controls:
#model NetInfinity.Middleware.VistaModelos.LoginVistaModelo
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<h1>#Login.Acceso</h1>
<p>
#Html.TextBoxFor(c => c.Id, new { #placeholder = #Login.Usuario, autofocus = "", autocomplete = "off", maxlength = "15", size = "15" })
</p>
<p class="p1">
#Html.PasswordFor(c => c.Clave, new { #placeholder = #Login.Contraseña, maxlength = "20", size = "20" })
#Html.ActionLink(".", "Cambiopwd", null, new { #class = "login-cambiarpwd", id = "Cambiopwd" })
</p>
<p class="login-recordarpwd">#Html.ActionLink(#Login.RecordarPwd, "Recordatoriopwd")</p>
<button type="button" class="login-submit" id="login-submit">#Login.LoginSubmit</button>
}
And the respective Model:
public class LoginVistaModelo
{
public string Id
{
get;
set;
}
[DataType(DataType.Password)]
public string Clave
{
get;
set;
}
public string MensajeError
{
get;
set;
}
}
And Controller Action that validates user is:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginVistaModelo vmUsuario)
{
if (ModelState.IsValid)
{
EntidadesBD backend;
var cache = MemoryCache.Default;
backend = (EntidadesBD)cache.Get("backend");
if (backend == null)
{
backend = new EntidadesBD();
var politica = new CacheItemPolicy { Priority = CacheItemPriority.NotRemovable };
cache.Set("backend", backend, politica);
}
Usuario usuario = vmUsuario.ValidaUsuario();
if (usuario == null)
{
vmUsuario.MensajeError = "error2";
vmUsuario.Id = vmUsuario.Clave = String.Empty; // <--- This not works
ModelState.Clear(); // <-- This not works
}
else
{
}
}
return View(vmUsuario);
}
When Login Action is triggered to validate user and password and error is thrown, I need to clear TextBoxFor value and PasswordFor value, and to achieve this I set model properties Id and Clave to string.empty in Controller, however when page (cshtml) is rendered again, controls keep old values ignoring model changes, not even if ModelState.Clear(). I've heard that HtmlHelpers controls (like .TextBoxFor() etc.) don't bind to model values on Postback, but rather get their value directly out of the POST buffer from ModelState. Please, ¿How can I do to update controls value when they are changed in Model properties?
Thanks
try making the value of model null before returning it to view,
like vmUsuario.id = null, vmUsuario.clave= null ; and thn return the empty model to view
A better approach for this type of problem would be to redirect the user, rather than returning the view. Otherwise you run into the problem that if they press F5 it reposts the data. So simply redirect the user, and use TempData to include your error message. In your Get method, check if TempData contains an error message and display it if it does.