I am uploading a file in MVC3 my csHtml page is
<div class="editor-label">
#Html.LabelFor(model => model.Resume)
</div>
<div class="editor-field">
<input type="file" name="Resume" id="Resume" />
#* #Html.EditorFor(model => model.ImageData)*#
#Html.ValidationMessageFor(model => model.Resume)
</div>
My Post Method is
[HttpPost]
public ActionResult SignUp(UserView user)
{
try
{
if (ModelState.IsValid)
{
UserManager userManager = new UserManager();
if (!userManager.IsUserLoginIDExist(user.LoginID))
{
// Request.Params["Resume"];
userManager.Add(user,Request.Files["Resume"]);
FormsAuthentication.SetAuthCookie(user.FirstName, false);
return RedirectToAction("Welcome", "Home");
}
}
}
catch
{
return View(user);
}
return View(user);
}
and my Model is
public class UserView
{
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[Display(Name = "Contact Number")]
public string ContactNumber { get; set; }
[Required]
[Display(Name = "Login ID")]
public string LoginID { get; set; }
[Required]
[Display(Name = "Password")]
public string Password { get; set; }
[Required]
[Display(Name = "Resume")]
public string Resume { get; set; }
}
}
I am getting user.Resume's value as full path(C:\test.png) on some machine and on some machine i am getting just name of the file(test.png). Please help me to deal with this miscellaneous issue
You aren't actually saving the file there at the moment. Perhaps you know this and have left the code out for brevity, but ASP.Net's built-in file handling gives you everything you need.
This question gives you all the info you need: File Upload Asp.net Mvc3.0
Related
I am using code-first with EF. Validation seems to be failing on a dropdown list with the error System.NullReferenceException: Object reference not set to an instance of an object. This happens when I save a record and I intentionally leave controls empty to test the validation. It happens even if the dropdown list itself has a selection.
here is part of my view:
<div class="editor">
#Html.LabelFor(model => model.EmployeeID)
#Html.DropDownListFor(model => model.EmployeeID, new SelectList(Model.Employees, "Value", "Text"))
#Html.ValidationMessageFor(model => model.EmployeeID)
</div>
If I use a textbox validation works:
<div class="editor">
#Html.LabelFor(model => model.EmployeeID)
#Html.TextBoxFor(model => model.EmployeeID, new { style = "width: 250px;" })
#Html.ValidationMessageFor(model => model.EmployeeID)
</div>
here are my Create controller actions:
public ActionResult Create()
{
var e = iEmployeeRepository.GetAll();
var visitorLogViewModel = new VisitorLogViewModel
{
Employees = e.Select(x => new SelectListItem
{
Value = x.EmployeeID,
Text = x.EmployeeName
})
};
return View(visitorLogViewModel);
}
//
// POST: /VisitorLogs/Create
[HttpPost]
public ActionResult Create(VisitorLog visitorlog)
{
if (ModelState.IsValid) {
iVisitorlogRepository.Add(visitorlog);
iVisitorlogRepository.Save();
return RedirectToAction("Search");
} else {
return View();
}
}
And my viewmodel:
public class VisitorLogViewModel
{
public int Id { get; set; }
[Display(Name = "Visitor Name")]
public string VisitorName { get; set; }
[Display(Name = "Company Name")]
public string CompanyName { get; set; }
[Required(ErrorMessage = "Employee ID is required.")]
[Display(Name = "GB Employee")]
public string EmployeeID { get; set; }
[Display(Name = "Visit Reason")]
public string VisitReason { get; set; }
[Display(Name = "Time In")]
public DateTime TimeIn { get; set; }
[Display(Name = "Time Out")]
public DateTime TimeOut { get; set; }
[Display(Name = "GB Employee")]
public string EmployeeName { get; set; }
public IEnumerable Employees { get; set; }
public VisitorLog VisitorLog { get; set; }
}
And my partial model for validation:
[MetadataType(typeof(VisitorLogMetaData))]
public partial class VisitorLog
{
}
public class VisitorLogMetaData
{
[Required(ErrorMessage = "Visitor name is required.")]
[MaxLength(128)]
public string VisitorName { get; set; }
[Required(ErrorMessage = "Company name is required.")]
[MaxLength(128)]
public string CompanyName { get; set; }
[Required(ErrorMessage = "GB Employee is required.")]
[MaxLength(128)]
public string EmployeeID { get; set; }
[Required(ErrorMessage = "Visit reason is required.")]
[MaxLength(254)]
public string VisitReason { get; set; }
[Required(ErrorMessage = "Time in is required.")]
public DateTime TimeIn { get; set; }
[Required(ErrorMessage = "Time out reason is required.")]
public DateTime TimeOut { get; set; }
}
And finally my model:
public partial class VisitorLog
{
public int Id { get; set; }
public string VisitorName { get; set; }
public DateTime TimeIn { get; set; }
public DateTime TimeOut { get; set; }
public string CompanyName { get; set; }
public string EmployeeID { get; set; }
public string VisitReason { get; set; }
// Navigation properties
[ForeignKey("EmployeeID")]
public virtual Employee Employee { get; set; }
}
I read there was a bug in MVC razor regarding the DropDownListFor but I don't know if that applies in my situation. I have tried some of the solutions and they didn't work for me. I am using 4.5 framework.
Thanks.
Edit:
One thing I noticed, when I submit the page and the error stops on the dropdown element:
#Html.DropDownListFor(model => model.EmployeeID, new SelectList(Model.Employees, "Value", "Text"))
the Model in Model.Employees is null, like it is loosing its binding when the page is submited.
Ok, I did some fundemental changes to my classes. First, I changed the post method in my controller. Previously I was passing the model to the post, now I am passing the view model and mapping it to the model before saving via my repository:
//
// POST: /VisitorLogs/Create
[HttpPost]
public ActionResult Create(VisitorLogViewModel visitorLogViewModel)
{
var e = iEmployeeRepository.GetAll();
VisitorLog visitorLog = new VisitorLog();
visitorLog.Id = visitorLogViewModel.Id;
visitorLog.VisitorName = visitorLogViewModel.VisitorName;
visitorLog.CompanyName = visitorLogViewModel.CompanyName;
visitorLog.EmployeeID = visitorLogViewModel.EmployeeID;
visitorLog.TimeIn = visitorLogViewModel.TimeIn;
visitorLog.TimeOut = visitorLogViewModel.TimeOut;
visitorLog.VisitReason = visitorLogViewModel.VisitReason;
visitorLogViewModel.Employees = new SelectList(e, "EmployeeID", "EmployeeName");
if (ModelState.IsValid)
{
iVisitorlogRepository.Add(visitorLog);
iVisitorlogRepository.Save();
return RedirectToAction("Search");
} else {
return View(visitorLogViewModel);
}
}
Next, I had to add the "required" attribute (validation) to the viewmodel:
public class VisitorLogViewModel
{
public int Id { get; set; }
[Required(ErrorMessage = "Visitor name is required.")]
[MaxLength(128)]
[Display(Name = "Visitor Name")]
public string VisitorName { get; set; }
[Required(ErrorMessage = "Company name is required.")]
[MaxLength(128)]
[Display(Name = "Company Name")]
public string CompanyName { get; set; }
[Required(ErrorMessage = "GB Employee is required.")]
[MaxLength(16)]
[Display(Name = "GB Employee")]
public string EmployeeID { get; set; }
[Required(ErrorMessage = "Visit Reason is required.")]
[MaxLength(254)]
[Display(Name = "Visit Reason")]
public string VisitReason { get; set; }
[Display(Name = "Time In")]
public DateTime TimeIn { get; set; }
[Display(Name = "Time Out")]
public DateTime TimeOut { get; set; }
[Display(Name = "GB Employee")]
public string EmployeeName { get; set; }
public SelectList Employees { get; set; }
}
Not sure if that is the most effcient method but everything works now. If someone sees something wrong with this method let me know.
I'm having an issue where the model is valid when it creates the HttpGet page, but invalid (some properties are null) on the HttpPost.
Here is my call to open the page:
var quote = new Quote
{
Agency = assignedAgency,
Insured = insured,
RiskAddress = insured.Address
};
db.Quotes.Add(quote);
db.SaveChanges();
return RedirectToAction("Edit", "Quote", quote.QuoteID);
And the HttpGet ActionResult - At this point, the model is valid. Insured and Agency properties are populated and have their respective Address properties populated as well.
[HttpGet]
public ActionResult Edit(int quoteID)
{
var model = db.Quotes.Find(quoteID);
return View(model);
}
And the HttpPort ActionResult - At the entry of this method, the Insured, Agency and their respective Address properties are null, causing an invalid Model state.
[HttpPost]
public ActionResult Edit(Quote model)
{
if (ModelState.IsValid)
{
if (model.SubCosts > 0)
{
model.InsuredSubs = true;
model.SubClassCode = "95626 - Subcontractor - TEST CLASS";
model.SubClassExposure = model.SubCosts;
}
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Edit", new { quoteID = model.QuoteID });
}
return View(model);
}
And the HTML:
#model DomaniOnline.Models.DomaniData.Quote
#{
ViewBag.Title = "Classification";
}
<h2>General Liability Classification</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
#Html.HiddenFor(model => model.QuoteID)
#Html.HiddenFor(model => model.Insured)
#Html.HiddenFor(model => model.Insured.Address)
#Html.HiddenFor(model => model.RiskAddress)
#Html.HiddenFor(model => model.Agency)
#Html.HiddenFor(model => model.Agency.Address)
.
.
.
.
<p>
#Html.ActionLink("Back to Insured Info", "Edit", "Insured", new { insuredID = Model.Insured.InsuredID }, null)
<input type="submit" value="Save & Continue" />
</p>
</fieldset>
}
I'd like to point out that the "Back to Insured Info" ActionLink at the bottom of the page works just fine and is able to supply the correct model.Insured.InsuredID. But for some reason, when submitting the form to the HttpPost, any property that is of a custom datatype is null. the Html.HiddenFor<> were added as a test while trying to get this to work.
edit: Classes:
public class Quote
{
public virtual int QuoteID { get; set; }
public virtual Address RiskAddress { get; set; }
public virtual Agency Agency { get; set; }
public virtual Insured Insured { get; set; }
public virtual DateTime PropEffDate { get; set; }
public virtual bool InsuredSubs { get; set; }
public virtual int SubCosts { get; set; }
.
.
.
}
public class Address
{
[Required]
public virtual string StreetAddress { get; set; }
[Required]
public virtual string City { get; set; }
[Required]
public virtual string State { get; set; }
[Required]
public virtual string ZipCode { get; set; }
}
public class Insured
{
public virtual int InsuredID { get; set; }
[Required]
public virtual string Name { get; set; }
[Required]
public virtual Address Address { get; set; }
public virtual string DBA { get; set; }
[Required]
public virtual string BusinessType { get; set; }
public virtual string Phone { get; set; }
}
Your problem is that your using HiddenFor on complex types. This only knows how to render simple types.
I would suggest either only persisting the ID's of those objects or using the Html.Serialize helper function from the MVC Futures project to serialize your account and insured objects, then deserialize them in your controller.
http://weblogs.asp.net/shijuvarghese/archive/2010/03/06/persisting-model-state-in-asp-net-mvc-using-html-serialize.aspx
Persisting the ID's should just be the InsuredID, from which you can re-get the Insured and it's address on postback. The same with Agency.
How make a dropdownlist? [Edited - almost working code]
View:
<div class="editor-label">
Firma
<div class="editor-field">
#Html.DropDownListFor(x => x.ID_firma, Model.firmaList)
#Html.ValidationMessageFor(model => model.nazwa)
</div>
Model:
public class produktModel
{
[Required(ErrorMessage="Proszę podać nazwę.")]
public string nazwa { get; set; }
[Required(ErrorMessage = "Proszę podać ilść produktu.")]
public decimal ilosc { get; set; }
[Required(ErrorMessage = "Proszę podać jednostkę produktu (np. kg, l, szt.).")]
public string jednostka { get; set; }
[Required(ErrorMessage = "Proszę podać cenę produktu.")]
public decimal cena { get; set; }
public string ID_firma { get; set; }
public IEnumerable<SelectListItem> firmaList { get; set; }
}
Controller:
public ActionResult dodaj()
{
var firma = baza.Firmas;
var model = new produktModel
{
firmaList = firma.AsEnumerable().Select(x => new SelectListItem
{
Value = x.ID_firma.ToString(),
Text = x.nazwa
})
};
return View(model);
}
[HttpPost]
public ActionResult dodaj(produktModel model)
{
Produkt prod = new Produkt();
prod.nazwa = model.nazwa;
prod.ilosc = model.ilosc;
prod.jednostka = model.jednostka;
prod.cena = model.cena;
prod.ID_firma = model.ID_firma;
baza.Produkts.InsertOnSubmit(prod);
baza.SubmitChanges();
return RedirectToAction("zarzadzaj_produktami", "Produkt");
}
It almost work...
I have only one problem (I hope)...
Value is string, and I save his value to database... (I don't now how to write it...)
prod.ID_firma = model.ID_firma;
prod.ID_firma is int. model.ID_firma is this value which is string. So I have an error:
Error 1 Cannot implicitly convert type 'string' to 'int?'
change your model a bit, i have assumed the column names change them according to your code
public class produktModel
{
[Required]
public string name { get; set; }
public decimal price { get; set; }
[Required]
public int companyID {get; set;}
public List<Company> compList {get; set;}
}
public class Company{
public int CompanyID {get;set;}
public string CompanyName {get;set;}
}
ActionResult should look like
public ActionResult add()
{
produktModel model = new produktModel();
model.compList= (from b in base.Companies
select new Company{
CompanyID = b.CompanyID,
CompanyName = b.CompanyName
}).ToList();
return View(model);
}
in your (strongly typed) view
#model produktModel
....
<div class="editor-label">
Company
<div class="editor-field">
#Html.DropDownListFor(model => model.companyID,
new SelectListItem(model.compList,
"CompanyID ",
"CompanyName "))
#Html.ValidationMessageFor(model => model.company_name)
</div>
...
Your question isn't clear enough.
Any way you can use the telerik combox\dropdown list or the default mvc dropdown list. you can find a lot of examples on google for that.
With Telerik write something like this:
#(Html.Telerik().ComboBox()
.Name("ComboBox")
.BindTo(new SelectList("CompanyID", "CompanyName")))
see this Telerik demo for more information.
I have 2 classes: User and Role, an user has a role
public class User : IPrincipal
{
public int UserId { get; set; }
[Required]
[Display(Name = "User name")]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Display(Name = "Created date")]
public DateTime CreatedDate { get; set; }
[Required]
[Display(Name = "Password question")]
public string PasswordQuestion { get; set; }
[Required]
[Display(Name = "Password anwser")]
public string PasswordAnswer { get; set; }
[Display(Name = "Active")]
public bool IsApproved { get; set; }
[Display(Name = "Last login date")]
public DateTime LastLoginDate { get; set; }
[Display(Name = "Last password changed date")]
public DateTime LastPasswordChangedDate { get; set; }
[Display(Name = "Last activity date")]
public DateTime LastActivityDate { get; set; }
public virtual Role Role { get; set; }
public virtual IIdentity Identity { get; set; }
public virtual bool IsInRole(string role)
{
if (Role.Name.ToLower() == role.ToLower())
{
return true;
}
return false;
}
}
public class Role
{
public int RoleId { get; set; }
[Required]
[Display(Name = "Role name")]
public string Name { get; set; }
}
I created UserController with read/write entity, in Create method, I created ViewBag.Role contains list of role
public ActionResult Create()
{
ViewBag.Role = new SelectList(db.Roles, "RoleId", "Name");
return View();
}
In create view:
<div class="editor-label">
#Html.LabelFor(model => model.Role)
</div>
<div class="editor-field">
#Html.DropDownList("Role")
#Html.ValidationMessageFor(model => model.Role.RoleId) #* I don't know this is correct? *#
</div>
In create view with HttpPost attribute, when user choose one role, and submit, I can't get a value of role.
Anyone who know the way to add role into user by select dropdownlist? I means, when I drop down list role and select item in there, and submit, I add one user row into table
Thank you
You can expose the RoleId foreign key by adding it as a property of User.
Then your view would look like
<div class="editor-field">
#Html.DropDownListFor(model => model.RoleId, (SelectList)ViewBag.Role)
#Html.ValidationMessageFor(model => model.RoleId)
</div>
I hope someone can help with this one. I have three Model classes like this:
public class Provider
{
public Guid ProviderId { get; set; }
public string Name { get; set; }
public Guid LocationId { get; set; }
public virtual Location Location { get; set; }
}
public class Location
{
public Guid LocationId { get; set; }
public string NameOrCode { get; set; }
public string Description { get; set; }
public string StreetNumber { get; set; }
public string StreetAddress1 { get; set; }
public string StreetAddress2 { get; set; }
public string City { get; set; }
public int? StateId { get; set; }
public string Zip { get; set; }
public string ContactPhone { get; set; }
public virtual State State { get; set; }
}
public class State
{
public int StateId { get; set; }
public string Name { get; set; }
public string Abbreviation { get; set; }
}
As you can see, a Provider has a Location (separate class for reuse elsewhere), and a Location has a State (which is null until selected).
My Controller looks like this for my Create methods:
public class ProviderController : BaseController
{
private SetupContext db = new SetupContext();
// other CRUD methods ...
//
// GET: /Provider/Create
public ActionResult Create()
{
Location location = new Location()
{
LocationId = Guid.NewGuid(),
NameOrCode = Resources.BillingLocation,
Description = Resources.BillingLocationDescription
};
Provider provider = new Provider()
{
ProviderId = Guid.NewGuid(),
LocationId = location.LocationId,
Location = location
};
ViewBag.StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
return View(provider);
}
//
// POST: /Provider/Create
[HttpPost]
public ActionResult Create(Provider provider)
{
if (ModelState.IsValid)
{
db.Locations.Add(provider.Location);
db.Providers.Add(provider);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
return View(provider);
}
// other CRUD methods ...
}
Finally, my View looks like this:
<div class="editor-label">
#Html.LabelFor(model => model.Location.StateId, #Resources.Location_State_Display_Name)
</div>
<div class="editor-field">
#Html.DropDownList("StateId", #Resources.ChooseFromSelectPrompt)
#Html.ValidationMessageFor(model => model.Location.StateId)
</div>
My problem is that the state the user selects in the DropDownList never gets set on my Model on the Create POST. I have similar code in my Edit View and the state is populated correctly in that View (that is, the state associated with an existing Provider.Location shows selected in the DropDownList for the user to edit if desire), but in both the Create and the Edit Views the selection made by the user is never registered in my Model (specifically the Provider.Location.StateId) coming in from the POST.
Looking at the HTML produced I see this:
<div class="editor-label">
<label for="Location_StateId">State/Territory</label>
</div>
<div class="editor-field">
<select id="StateId" name="StateId"><option value="">[Choose]</option>
<option value="1">Alabama</option>
<option value="2">Alaska</option>
<!-- more options ... -->
</select>
<span class="field-validation-valid" data-valmsg-for="Location.StateId" data-valmsg-replace="true"></span>
</div>
I suspect I need to somehow convey the Location.StateId relationship instead of just StateId as I see above but I can't figure out the correct syntax to do that. I've tried changing my ViewBag dynamic property to Location_StateId like this:
ViewBag.Location_StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
And the DropDownList in my View like this:
#Html.DropDownList("Location_StateId", #Resources.ChooseFromSelectPrompt)
I figured then perhaps that notation would work because the label beside my DropDownList was rendered as:
<div class="editor-label">
<label for="Location_StateId">State/Territory</label>
</div>
This attempt did not work. Can you help me out?
Thanks in advance.
#Html.DropDownList("Location.StateId", #Resources.ChooseFromSelectPrompt)
Also the following line doesn't do anything useful:
ViewBag.StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
You are assigning a SelectList to something that is supposed to be a scalar property. You probably wanted to pass the collection as ViewBag:
ViewBag.States = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
and then in the view:
#Html.DropDownList("Location.StateId", (SelectList)ViewBag.States)