I have some difficulties with editing data. I have some property - ISBN. I put it to have a unique value. When I create new data it's ok but when I try to edit, it wrights that is already in use. What can I do?
Class Books:
[Remote("IsISBNExists", "Book", ErrorMessage = "ISBN number is already in use")]
public string ISBN { get; set; }
BookController:
public JsonResult IsISBNExists(string Isbn) {
return Json(!bookContext.Books.Any(x => x.ISBN == Isbn), JsonRequestBehavior.AllowGet);
}
You can include the ID of the record you are editing and use that to determine if the ISBN is in use..
Just add your Book ID field in the AdditionalFields parameter to include it in the validation request.
[Remote("IsISBNExists", "Book", AdditionalFields = "BookID", ErrorMessage = "ISBN number is already in use")]
public string ISBN { get; set; }
then use that field in your validation
public JsonResult IsISBNExists(string Isbn, int BookID) {
return Json(!bookContext.Books.Any(x => x.BookID != BookID && x.ISBN == Isbn), JsonRequestBehavior.AllowGet);
}
Related
I have trying to pass a query string parameter to my JsonResult action in the controller. I keep getting the following error:
Value cannot be null.
Parameter name: String
I need the task_id from this url:
TaskIn?task_id=33
In my view I have tried (fails with same error):
#model TaskingSystem.Models.AcceptTasksViewModel
#{string task_id = #Request.QueryString["task_id"];}
#Html.HiddenFor(m => m.task_id)
In controller:
public JsonResult TasksExist(string email, string task_id)
{
int tasks_id = int.Parse("task_id");
return Json(db.Tasks_Validate.Any(e => e.Email == email && e.task_id == tasks_id), JsonRequestBehavior.AllowGet);
}
My model:
public class AcceptTasksViewModel{
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email:")]
//Using Remote validation attribute
[Remote("TasksExist", "Task_Results", ErrorMessage = "Email does not exists in database. Please try a different email address.")]
public string email { get; set; }
public int task_id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
I have also tried just passing straight into the action using this but it still fails.
int tasks_id = int.Parse(Request.Params["task_id"]);
To pass the task_id along with the email to your TasksExist(string email, string task_id) method, you have to mention task_id in AdditionalFields property of Remote attribute as follows:
[Remote("TasksExist", "Task_Results",AdditionalFields = "task_id" ErrorMessage = "Email does not exists in database. Please try a different email address.")]
public string email { get; set; }
this is my entity:
public partial class Student
{
public string Code { get; set; }
public int Year { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
}
Config:
HasKey(e => new { e.Code, e.Year});
Property(b => b.Code).HasColumnName("CODE").IsUnicode(false).HasMaxLength(20).IsRequired();
Property(b => b.Year).HasColumnName("YEAR").IsRequired();
Property(b => b.Name).HasColumnName("NAME").IsUnicode(false).HasMaxLength(50);
Property(b => b.Gender).HasColumnName("GENDER").IsUnicode(false).HasMaxLength(2).IsRequired();
The gender field also has the required option.
In my update I only want to update the name field:
var student = new Student
{
Code = "WRK",
Year = 2018,
Name = "Test Name"
};
_context.Student.Attach(student);
_context.Entry(student).Property(x => x.Name).IsModified = true;
_context.SaveChanges();
On SaveChanges it gives a DbEntityValidationException, saying the gender field is required. Although I don't want to update it, but keep the existing value from the database.
Is there a proper solution without first querying the database to get the existing value for that gender field?
Thanks.
I use solution like this:
Public Overrides Function SaveChanges() As Integer
For Each changedEntity In Me.ChangeTracker.Entries
Select Case changedEntity.State
Case EntityState.Modified
Select Case If(changedEntity.Entity.GetType.Namespace = "System.Data.Entity.DynamicProxies", changedEntity.Entity.GetType.BaseType, changedEntity.Entity.GetType)
Case GetType(Student)
changedEntity.Property("Gender").IsModified = False
End Select
Next
Return MyBase.SaveChanges()
End Function
I have made a remote validation in my project, to avoid duplicate entries in DB. My model class is like this
public class Supplier
{
public int SupplierId { get; set; }
public string SupplierName { get; set; }
[Required, DisplayName("Supplier Code")]
[Remote("ViCodeExists", "Supplier", "Vi Code is already exists.", AdditionalFields = "SupplierId")]
public string SupplierCode { get; set; }
}
And inside my SupplierController I have the function like this
public JsonResult ViCodeExists(string SupplierCode, int SupplierId = 0)
{
var user = _db.Suppliers.Where(x => x.SupplierCode == SupplierCode.Trim() && x.SupplierId != SupplierId);
return !user.Any() ?
Json(true, JsonRequestBehavior.AllowGet) :
Json(string.Format("{0} is already exists.", SupplierCode),
JsonRequestBehavior.AllowGet);
}
In my create View
#Html.TextBoxFor(model => model.SupplierCode)
#Html.ValidationMessageFor(model => model.SupplierCode)
Everything looks okay to me, but this validation does not works. I have tried adding breakpoint inside controller, But it never get hit. Can any one point out What I am doing wrong here?
Note: I have same type of validation in some other controllers in the
same project and they all work well. Issue is with this one only.
You using the overload of RemoteAttribute that accepts 3 string parameters where the 3rd parameter is the area name (not an error message).
Change the attribute to
[Remote("ViCodeExists", "Supplier", ErrorMessage = "Vi Code is already exists.", AdditionalFields = "SupplierId")]
public string SupplierCode { get; set; }
Note your overriding the error message in the methods return statement anyway, so you can probably omit it and just use
[Remote("ViCodeExists", "Supplier", AdditionalFields = "SupplierId")]
public string SupplierCode { get; set; }
I've created an MVC project using entity framework code first. My model is simply a form that gathers information.
public class Application
{
public int Id { get; set; }
public string FirstName { get; set; }
public string MiddleInitial { get; set; }
public string LastName { get; set; }
public int SSN { get; set; }
public DateTime DOB { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State {get; set; }
public string Zip { get; set; }
public int HomePhone { get; set; }
public int BusinessPhone { get; set; }
public int MobilePhone { get; set; }
}
My goal is to create a drop down list with all of the states, but I'm finding this to be very difficult given that I've already created the database via scaffolding with views and controllers. Is there a simple way to do this and tie it in with the existing database? I've searched for almost the entire day with no luck. An overview/explanation of what to include for the model/controller/view would be amazing!
Update: I've created a new model named "State" with properties "Id" and "StateName" and have created some states in the database. In my "Application" controller inside the Create action method I have:
Controller
public ActionResult Create()
{
ApplicationDbContext db = new ApplicationDbContext();
this.ViewData["Id"] = new SelectList(db.States.ToList(), "Id", "StateName");
return View();
}
View
#Html.DropDownList("Id")
Now the problem is I'm getting this error " There is no ViewData item of type 'IEnumerable' that has the key 'Id'." Would really appreciate help!
Its quite simple. Add an IEnumerable<SelectListItem> property to your model(Here I suggest you make a ViewModel that can have the exact same properties as Application with the below code included as a property). Then you just need to build the list and send it to your view
public IEnumerable<SelectListItem> States{ get; set; }
I will assume you want to retrieve the State values from the db. Here is how you will do it:
private IEnumerable<SelectListItem> GetAllStates()
{
IEnumerable<SelectListItem> list = from s in db.Applications
select new SelectListItem
{
Selected = false,
Text = s.State,
Value = s.State
};
return list;
}
Or this...
private IEnumerable<SelectListItem> GetAllStates()
{
IEnumerable<SelectListItem> list = db.Applications.Select(s => new SelectListItem
{
Selected = false,
Text = s.State,
Value = s.State
});
return list;
}
Then do something like this in your action:
var app = new Application
{
States = GetAllStates()
};
return View(app);
Then finally, use Razor on the view to display the Dropdown list like this
#Html.DropDownListFor(m => m.State, Model.States, "--Select a State--")
The 1st parameter is the property of the model to update, the 2nd is the list of data, and 3rd is the default message that will be displayed
Hope this helps.
Create a data layer that retrieves a list of what you want. Then use EF to get all the states.
//assuming you have a table of states..
var states = db.States();
The states table should be a Unique list of states.
var selectList = new List<SelectListItem>();
foreach(var thing in states){
//if you got everything, thus the ID field for the value...
selectList.Add(new SelectListItem {Text =thing.State, Selected = false, Value = thing.ID);
}
Make sure in your Viewmodel class that selectlist is a public property.....and set to what you did above. You also need to provied a string for the view selection post back.
StatesSelectList = selectList;
public IEnumberable<SelectListItem> StatesSelectList {get;set;}
public string SelectedState {get;set;}
In your view, do this:
#Html.DropDownListFor(p=>Model.SelectedState, Model.StatesSelectList)
Very simple Code step by step
1) In Entity Framework Class
var productsList = (from product in dbContext.Products
select new ProductDTO
{
ProductId = product.ProductId,
ProductName = product.ProductName,
}).ToList();
2) In Controller
ViewBag.productsList = new EntityFrameWorkClass().GetBusinessSubCategoriesListForDD();
3) In View
#Html.DropDownList("Product_ProductId", new SelectList(ViewBag.productsList, "ProductId", "ProductName"), new { #class = "form-control" })
OR
#Html.DropDownListFor(m=>m.Product_ProductId, new SelectList(ViewBag.productsList , "ProductId", "ProductName"), new { #class = "form-control" })
I assume there is a States model that has a Id and a StateName property.
Change to the list to ViewData["State"] to ensure easy binding on POST.
Id is the value that will be sent in the POST data ie.. State = Id. The StateName is what will be displayed in the Select list. So for your model this is not correct as State is a string. So needs to be
this.ViewData["State"] = new SelectList(db.States.ToList(), "StateName", "StateName");
Then in your view
#Html.DropDownList("State")
I've literally just started learning MVC.
I have created a simple model:
public class StaffMember
{
public Guid StaffMemberId { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string Team { get; set; }
public virtual ICollection<Observation> Observations { get; set; }
}
Now I have decided that I want to include a drop down list of all StaffMembers on the create page for the observation records. I manage to do that with the following code:
#Html.DropDownListFor(o => o.StaffMemberId,
new SelectList(Model.StaffMembers,
"StaffMemberId",
"Forename",
Model.StaffMemberId),
"-- Select Staff Member --")
This works perfectly, although, you'll notice that I can only include a single field, "Forename".
I want the drop down list to show the staff member's full name. I tried concatenating the fields manually i.e. "Forename" + " " + "Surname" but that threw and exception about there being no such field as "Forename" + " " + "Surname".
My question is this - is it possible to add to my model some sort of property that is simply based on the value of two existing properties. Something like:
public class StaffMember
{
private string _fullName;
public Guid StaffMemberId { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string Team { get; set; }
public virtual ICollection<Observation> Observations { get; set; }
public string FullName
{
get
{
return _fullName;
}
set
{
value = this.Forename + " " + this.Surname;
_fullName = value;
}
}
}
I tried the above, but when populating my database (I'm using entity model code first), that field always has a value of null, even though the field shows the correct value when debugging.
I'm using the following to auto populate the db with some test data:
var staff = new List<StaffMember>
{
new StaffMember
{
Forename = "Bob",
Surname = "Hope",
StaffMemberId = Guid.NewGuid(),
Team = "Test"
},
new StaffMember
{
Forename = "Stan",
Surname = "Laurel",
StaffMemberId = Guid.NewGuid(),
Team = "Test"
}
};
staff.ForEach(s => context.StaffMembers.Add(s));
context.SaveChanges();
Any pointers would be really useful here, especially if I am approaching this in completely the wrong way!
Yes, you're really close with the FullName property.
public class StaffMember
{
public string FullName
{
get
{
return this.Forename + " " + this.Surname;
}
}
}
No need for a private _fullName since you only need to get the values of Forename and Surname. And you don't need a set since you won't set a value back to this model using FullName
You can make this change in your Repository where you add Staff_Member
public void AddStaff(Staff_Member sm)
{
String fullName = sm.Forename.ToString()+" "+sm.Surname.ToString();
sm.FullName = fullName;
_context.Staff_Member.Add(sm);
}
However, you need to have set method for FullName as well in your Staff_Member model.