How to save to database Client IP Address of Visitors Machine in ASP.Net MVC? - asp.net-mvc

am trying to get IP Address of client Machine Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; it's working fine.
Get IP On page load
public ActionResult AddCompany()
{
get_IP();
return View();
}
get_IP code
public void get_IP()
{
string ipAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(ipAddress))
{
ipAddress = Request.ServerVariables["REMOTE_ADDR"];
}
ViewBag.IPAddress = ipAddress;
}
But when user register the form get IP address value also save in the data base..
Cs.html File
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header">Add Company</h1>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.IPAddress)
<div class="form-group">
#Html.LabelFor(model => model.CompanyName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CompanyName)
#Html.ValidationMessageFor(model => model.CompanyName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ShortName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ShortName)
#Html.ValidationMessageFor(model => model.ShortName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Email, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Country, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#*#Html.EditorFor(model => model.Country)*#
#Html.DropDownList("Country", null, "---Select Country----")
#Html.ValidationMessageFor(model => model.Country)
</div>
</div>
<div class="form-group">
<b>State: </b>
<select id="state"></select><br />
</div>
<div>
<b>City: </b>
<select id="city"></select><br />
</div>
<div class="form-group">
#Html.LabelFor(model => model.MobileNo, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MobileNo)
#Html.ValidationMessageFor(model => model.MobileNo)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
</div>
I create one #Html.HiddenFor(model => model.IPAddress) hidden filed value but it's not working ..
On page load IPAddress Value is showing .after i click to save button the Ip value is not saved to the database..
AddCompany
[HttpPost]
public ActionResult AddCompany(Company cmp)
{
using (DataContext entities = new DataContext())
{
entities.Company.Add(cmp);
entities.SaveChanges();
int id = cmp.CompanyID;
Session.Clear();
Response.Redirect("Index");
}
return View(cmp);
}
Any idea How to save client IP Adrress from the database..
Class File
[Table("MySecondMVCDemo")]
public class Company
{
[Key]
public int CompanyID { get; set; }
[Required(ErrorMessage = "Please Enter Company Name")]
[Display(Name = "CompanyName")]
public string CompanyName { get; set; }
[Required(ErrorMessage = "Please Enter Short Name")]
[Display(Name = "ShortName")]
public string ShortName { get; set; }
[Required(ErrorMessage = "Please Enter Email Address")]
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = "Please Enter Email Address")]
[Display(Name = "Country")]
public string Country { get; set; }
[Required(ErrorMessage = "Please Enter Mobile No")]
[Display(Name = "MobileNo")]
public string MobileNo { get; set; }
public Int32? IPAddress { get; set; }
}

I do not know about HiddenFor because I have not use it before.
How I hid fields before was like this:
#Html.TextBoxFor(model => model.IPAddress, new { #class = "sr-only", #type = "hidden" })
You can add the bootstrap class sr-only to make sure it is hidden.
Make sure you check your browser inspector to see whether the hidden field has a value.
If posted and is still not saving, then try to assign the IpAddress identity to the form field value before saving it like this:
cmp.IPAddress = Request.Form["IPAddress"];

Store IP address as a string instead of Int32
Please use code from here to get IP Address
http://tutorialgenius.blogspot.in/2010/09/aspnet-get-ipv4-address-even-if-user-is.html

Related

Display name of Identity User who created and last updated record when ID is saved

I must not be searching with the correct phrases. This is a simple concept and I’ve done it in other languages and frameworks with ease.
I’m saving the UserID for the person who created the record and the UserID who last updated the record. Instead of displaying the UserID, I want to display the User.FirstName + ‘ ‘ + User.LastName.
The way I have it currently the LastEditBy and CreateBy is displayed on the page as blank.
Controller: I get the customer model and manually map the model to the customerViewModel then pass it to my partial view.
public ActionResult Edit(int customerId)
{
Customer customer = DbContext.Customers.FirstOrDefault(x => x.CustomerId == customerId);
CustomerViewModel customerViewModel = MapToViewModel(customer);
customerViewModel.UserSelectList = GetUserGroupList();
UserManager<ApplicationUser> _userManager = HttpContext.GetOwinContext().Get<ApplicationUserManager>();
var CreateByUser = _userManager.FindById(customerViewModel.CreateById);
var EditByUser = _userManager.FindById(customerViewModel.LastEditById);
customerViewModel.CreateBy = CreateByUser.FirstName + " " + CreateByUser.LastName;
customerViewModel.LastEditBy = EditByUser.FirstName + " " + EditByUser.LastName;
if (Request.IsAjaxRequest()) {
return PartialView("_CustomerEditPartial", customerViewModel);
}
return View("_CustomerEditPartial", customerViewModel);
}
The CustomerViewModel:
public class CustomerViewModel : DbContext{
public CustomerViewModel(): base("name=CustomerViewModel")
{
}
[Key]
public int CustomerId { get; set; }
[MaxLength(128), ForeignKey("ApplicationUser")]
public string UserId { get; set; }
public SelectList UserSelectList { get; set; }
#region additional Fields
// This overrides default conventions or data annotations
[Required(ErrorMessage = "Please enter your first name.")]
[StringLength(50)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Please enter your last name.")]
[StringLength(100)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime CreateDate { get; set; } = DateTime.Now;
public string CreateById { get; set; }
[NotMapped]
public string CreateBy { get; set; }
public string LastEditById { get; set; }
[NotMapped]
public string LastEditBy { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime LastEditDate { get; set; } = DateTime.Now;
public virtual ApplicationUser ApplicationUser { get; set; }
}
public class UserGroupList
{
public string Value { get; set; }
public string Text { get; set; }
}
My partial view page: _CustomerEditPartial.cshtml
#model WOA.ViewModels.CustomerViewModel
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" daa-dismiss="modal" aria-hidden="True">x</button>
<h4 class="modal-title">Edit Customer</h4>
</div>
#using (Ajax.BeginForm("Edit", "Customers", null, new AjaxOptions { HttpMethod = "Post", OnFailure = "OnFail" }, new { #class = "form-horizontal", role = "form" })) {
<div class="modal-body">
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.CustomerId)
<div class="form-group">
#Html.LabelFor(model => model.UserId, "UserId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.UserId, ViewData.Model.UserSelectList, "Select One", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.UserId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CreateDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CreateDate, new { #readonly = "readonly" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CreateBy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CreateBy, new { #readonly = "readonly" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastEditBy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.LastEditBy, new { #readonly = "readonly" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastEditDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.LastEditDate, new { #readonly = "readonly" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-primary" value="Save changes" />
</div>
</div>
</div>
<script type="text/javascript">
function OnSuccess() {
alert("success");
}
function OnFail() {
alert("fail");
}
function OnComplete() {
alert("Complete");
}
</script>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
I have updated my code, it is working now, however I do not believe it is the proper way to do this.
I believe I should be able to return the additional values I need via Linq on the initial call and not make two more trips to the database for the additional values.
I have not been able to figure out a way to make this work with Linq.
Thank you in advance for your time and effort.

modelstate.isvalid not getting all the errors

I have this model :
[Required(ErrorMessage = "Please provide a valid EmailAddress")]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = "Please provide a company name")]
[Display(Name = "Company")]
public string CompanyName { get; set; }
[Required(ErrorMessage = "Please provide a username")]
[Display(Name = "Username")]
public string UserName { get; set; }
[Required(ErrorMessage = "Please select at least one language")]
public int[] SelectedLanguages { get; set; }
[Required(ErrorMessage = "Please select at least one business unit")]
public int[] SelectedBusinessUnits { get; set; }
Now when I do a post from my form using this model and I don't provide any of the values, I only get errormessages for Email, Company and UserName.
I don't get messages for the SelectedLanguages or the SelectedBusinessUnits.
What am i doing wrong?
THis is the view
#using (Html.BeginForm("Register", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h4>Create a new account.</h4>
<hr />
#Html.ValidationSummary("", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.CompanyName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.CompanyName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.UserName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.UserName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Email, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#foreach (var la in Model.Languages)
{
<input type="checkbox"
name="SelectedLanguages" value="#la.Id" id="#la.Id" />
<label for="#la">#la.Title</label>
}
</div>
<div class="form-group">
#foreach (var bu in Model.BusinessUnits)
{
<input type="checkbox"
name="SelectedBusinessUnits" value="#bu.Id" id="#bu.Id" />
<label for="#bu.Id">#bu.Title</label>
}
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Register" />
</div>
</div>
}
I think you have to go the way of writing a custom validation routine accompanied with a ValidationAttribute. Don't think a simple "out-of-the-box" validator exists for checking if one or more values are present in an array.
Check out this SO post to point you in the right direction.
Basic setup:
public class ArrayContainsValueAttribute: ValidationAttribute
{
// your checks here (pseudo)
if(!array.Any())
return false;
return true;
}
[ArrayContainsValue(ErrorMessage = "Please select at least one business unit")]
public int[] SelectedBusinessUnits { get; set; }

Database First EF6 add data to table with Custom ViewModel

I using MVC 5.1 and EF 6.1 database first model. I don't like the view that was created by the scaffolding as it uses all the database columns. On the create view I just want the user to input the required fields all other data can be added through editing the details view. I have created the a view model to use other than the .edmx generated one. The view works as expected but when the create action button is click the post operation dies with a "[NullReferenceException: Object reference not set to an instance of an object.]
Here is my view model
public class DesktopCreateViewModel
{
[Required]
[Display(Name = "Serial Number")]
[StringLength(30)]
public string SERIAL_NUMBER { get; set; }
public int Model_DesktopId { get; set; }
public int DeviceType_DesktopId { get; set; }
[Required]
[StringLength(50)]
public string MAC1 { get; set; }
[Display(Name = "Arrival Date")]
public DateTime ARRIVAL_DATE { get; set; }
[Timestamp]
[Display(Name = "Record Updated")]
public DateTime RECORD_UPDATED { get; set; }
public int LocationId { get; set; }
public int Location_CodeId { get; set; }
public int MemoryId { get; set; }
public int MonitorId { get; set; }
public int PlantId { get; set; }
public int DepartmentId { get; set; }
public int Operating_SystemId { get; set; }
[ForeignKey("DeparmentId")]
public virtual Department Department { get; set; }
[ForeignKey("DeviceType_DesktopId")]
public virtual DeviceType_Desktop DeviceType_Desktop { get; set; }
[ForeignKey("Location_CodeId")]
public virtual Location_Code Location_Code { get; set; }
[ForeignKey("LocationId")]
public virtual Location Location { get; set; }
[ForeignKey("MemoryId")]
public virtual Memory Memory { get; set; }
[ForeignKey("Model_DesktopId")]
public virtual Model_Desktop Model_Desktop { get; set; }
[ForeignKey("MonitorId")]
public virtual Monitor Monitor { get; set; }
[ForeignKey("Operating_SystemId")]
public virtual Operating_System Operating_System { get; set; }
[ForeignKey("PlantId")]
public virtual Plant Plant { get; set; }
public IEnumerable<DesktopCreateViewModel> Create_Desktop { get; set; }
public virtual ICollection<DesktopCreateViewModel> Desktops { get; set; }
Here is the portion of the controller that fails
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ICollection<DesktopCreateViewModel> desktop)
{
if (ModelState.IsValid)
{
foreach (var item in desktop)
{
db.Entry(desktop).State = EntityState.Added;
}
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "DEPARTMENT1", desktop.DepartmentId);
ViewBag.DeviceType_DesktopId = new SelectList(db.DeviceType_Desktop, "Id", "DEVICE_TYPE", desktop.DeviceType_DesktopId);
ViewBag.Location_CodeId = new SelectList(db.Location_Code, "Id", "LOCATION_CODE1", desktop.Location_CodeId);
ViewBag.LocationId = new SelectList(db.Locations, "Id", "LOCATION1", desktop.LocationId);
ViewBag.MemoryId = new SelectList(db.Memories, "Id", "MEMORY1", desktop.MemoryId);
ViewBag.Model_DesktopId = new SelectList(db.Model_Desktop, "Id", "MODEL", desktop.Model_DesktopId);
ViewBag.MonitorId = new SelectList(db.Monitors, "Id", "MONITOR1", desktop.MonitorId);
ViewBag.Operating_SystemId = new SelectList(db.Operating_System, "Id", "OS", desktop.Operating_SystemId);
ViewBag.PlantId = new SelectList(db.Plants, "Id", "PLANT1", desktop.PlantId);
return View(desktop);
}
This is the View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Desktop</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.SERIAL_NUMBER, new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.SERIAL_NUMBER)
#Html.ValidationMessageFor(model => model.SERIAL_NUMBER)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Model_DesktopId, "Model", new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("Model_DesktopId", String.Empty)
#Html.ValidationMessageFor(model => model.Model_DesktopId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DeviceType_DesktopId, "Device Type", new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("DeviceType_DesktopId", String.Empty)
#Html.ValidationMessageFor(model => model.DeviceType_DesktopId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MAC1, new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.MAC1)
#Html.ValidationMessageFor(model => model.MAC1)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ARRIVAL_DATE, new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.ARRIVAL_DATE)
#Html.ValidationMessageFor(model => model.ARRIVAL_DATE)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RECORD_UPDATED, new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.RECORD_UPDATED)
#Html.ValidationMessageFor(model => model.RECORD_UPDATED)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LocationId, "Location", new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("LocationId", String.Empty)
#Html.ValidationMessageFor(model => model.LocationId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Location_CodeId, "Location Code", new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("Location_CodeId", String.Empty)
#Html.ValidationMessageFor(model => model.Location_CodeId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MemoryId, "Memory", new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("MemoryId", String.Empty)
#Html.ValidationMessageFor(model => model.MemoryId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MonitorId, "Monitor", new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("MonitorId", String.Empty)
#Html.ValidationMessageFor(model => model.MonitorId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PlantId, "Plant", new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("PlantId", String.Empty)
#Html.ValidationMessageFor(model => model.PlantId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DepartmentId, "Department", new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("DepartmentId", String.Empty)
#Html.ValidationMessageFor(model => model.DepartmentId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Operating_SystemId, "Operating System", new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("Operating_SystemId", String.Empty)
#Html.ValidationMessageFor(model => model.Operating_SystemId)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-8 col-md-4">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
The action is expecting a collection of viewmodels (ICollection<DesktopCreateViewModel>), but the view only contains one. Try changing to:
public ActionResult Create(DesktopCreateViewModel desktop)

How do I pass a ViewModel to an Edit Action in ASP.NET MVC 5

I'm learning about using ViewModels to pass information from the view to the controller and vice versa. I have my create action, view, and viewmodel working perfectly but I'm having trouble with the edit one. I get the error:
The model item passed into the dictionary is of type 'CatVM.Models.Cat', but this dictionary requires a model item of type 'CatVM.Models.EditCatViewModel'.
Here is my code:
Controller Method
// GET: /Cats/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Cat cat = unitOfWork.CatRepository.GetByID(id);
if (cat == null)
{
return HttpNotFound();
}
return View(cat);
}
View
#model CatVM.Models.EditCatViewModel
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Cat</h4>
<hr />
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Color, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Color)
#Html.ValidationMessageFor(model => model.Color)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FurLength, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FurLength)
#Html.ValidationMessageFor(model => model.FurLength)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Size, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Size)
#Html.ValidationMessageFor(model => model.Size)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
EditCatViewModel
public class EditCatViewModel
{
public int ID { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[StringLength(50)]
public string Color { get; set; }
[Required]
[StringLength(50)]
[Display(Name = "Fur Type")]
public string FurLength { get; set; }
[StringLength(50)]
public string Size { get; set; }
}
}
That's because the item you receive from CatRepository.GetByID(id); is of type Cat, not EditCatViewModel.
You can bypass this by constructing a new viewmodel from this object:
Cat cat = unitOfWork.CatRepository.GetByID(id);
var viewModel = new EditCatViewModel {
Name = cat.Name,
Color = cat.Color,
FurLength = cat.FurLength,
Size = cat.Size
};
return View(viewModel);
Alternatively you could construct implicit or explicit casting methods or use a mapping tool like AutoMapper.
Your return view should be of type CatVM.Models.EditCatViewModel now your returning a Cat
return View(cat);
transform your model in a view model and pass this object back to the view

ASP.NET MVC5 - Image upload to SQL Server 2008R2 Standard

I am semi-new to ASP.NET MVC, I have used it in the past but not to the extent of what I have been planning to use it for and to learn from for some projects I am working on. I know this question has been asked a lot over the internet and there are many solutions so I will try and keep this as specific as possible regarding uploading images and storing them in a SQL Server database.
I am currently using .NET 4.5 with MVC5 (VS 2013) to do all my coding.
To begin I found a great tutorial that got me up and running with being able to upload images to my SQL Server 2008 database: http://www.mikesdotnetting.com/Article/125/ASP.NET-MVC-Uploading-and-Downloading-Files
Everything works great after I figured out how the functions worked from the site, but the issue I am having is that I have multiple text fields that I want to include data from into the SQL Server database along with including an image upload feature that I created based off the tutorial I found online.
The first part of my code is the Models (BeerList.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
namespace YBPP_Production.Models
{
public class BeerList
{
public int ID { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
[Required(ErrorMessage = "Company is required.")]
public string Company { get; set; }
[Required(ErrorMessage = "Type is required.")]
public string Type { get; set; }
[Required(ErrorMessage = "City is required.")]
public string City { get; set; }
[Required(ErrorMessage = "State is required.")]
public string State { get; set; }
[Required(ErrorMessage = "Country is required")]
public string Country { get; set; }
public string ABV { get; set; }
public string IBU { get; set; }
}
public class Info : DbContext
{
public DbSet<DBName> MoreDB { get; set; }
}
}
The string listed there are the text fields I am trying to pull into my database and I can do that but when I try to mix in the image upload feature either the text will upload or the image will upload depending on how I do the calls.
The Controllers section of my code (BeerListController.cs)
// GET: /BeerList/Create
public ActionResult Create()
{
return View();
}
// POST: /BeerList/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,Name,Company,Type,City,State,Country,ABV,IBU")] BeerList beerlist)
{
if (ModelState.IsValid)
{
db.BeerListDB.Add(beerlist);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(beerlist);
}
public ActionResult FileUpload(HttpPostedFileBase file)
{
//Begin the Image Uploading Process
foreach (string upload in Request.Files)
{
if (!Request.Files[upload].HasFile()) continue;
string mimeType = Request.Files[upload].ContentType;
Stream fileStream = Request.Files[upload].InputStream;
string fileName = Path.GetFileName(Request.Files[upload].FileName);
int fileLength = Request.Files[upload].ContentLength;
byte[] fileData = new byte[fileLength];
fileStream.Read(fileData, 0, fileLength);
const string connect = #"Server=localhost;database=<database-name>;uid=<username-here>;pwd=<there-a-passwordhere>";
using (var conn = new SqlConnection(connect))
{
var qry = "INSERT INTO BeerLists (FileContent, mimeType, FileName) VALUES (#FileContent, #mimeType, #FileName)";
var cmd = new SqlCommand(qry, conn);
cmd.Parameters.AddWithValue("#FileContent", fileData);
cmd.Parameters.AddWithValue("#MimeType", mimeType);
cmd.Parameters.AddWithValue("#FileName", fileName);
conn.Open();
cmd.ExecuteNonQuery();
}
}
return View();
}
The view part of my code (Create.cshtml)
#model YBPP_Production.Models.BeerList
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype="multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>BeerList</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Company, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Company)
#Html.ValidationMessageFor(model => model.Company)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Type, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Type)
#Html.ValidationMessageFor(model => model.Type)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.City, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.City)
#Html.ValidationMessageFor(model => model.City)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.State, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.State)
#Html.ValidationMessageFor(model => model.State)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Country, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Country)
#Html.ValidationMessageFor(model => model.Country)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ABV, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ABV)
#Html.ValidationMessageFor(model => model.ABV)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IBU, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.IBU)
#Html.ValidationMessageFor(model => model.IBU)
</div>
</div>
<div class="form-group">
<p class="control-label col-md-2">Image Upload:</p>
<div class="col-md-10">
<input type="file" id="ImageUpload" name="ImageUpload" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" name="Submit" id="Submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
So what I am looking to hopefully get help with is being able to merge the function of Create and FileUpload into one function so that the form will take both the text in the text-fields and the image that gets uploaded with it. I have read a bunch of other people's posts and code and they all seem to have their own way to doing things but everyone example never includes text-fields or any other form functions just the basic image upload.
Thank you very very much in advance for any direction/suggestions/help to this issue.
You can create model that contains HttpPostedFileBase, then save your entire form with selected file.
Model:
public class BeerListModel
{
public int ID { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
[Required]
public HttpPostedFileBase file { get; set; }
}
View:
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="form-group">
<p class="control-label col-md-2">Image Upload:</p>
<input type="file" id="file" name="file" />
</div>
<div class="form-group">
<input type="submit" name="Submit" id="Submit" value="Create" class="btn btn-default" />
</div>
</div>
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(BeerListModel model)
{
if (ModelState.IsValid)
{
//your logic
}
return View("Create");
}
#Szakus' answer is the overall direction you want to go with respect to uploading a file, however when you asked, " I am still a bit confused as to what I should put as far as my logic for the Controller" you inadvertently got to the root of your problem.
I would strongly recommend you do some research into separation of concerns. Putting raw SQL code in your controller is not a great idea and will open your application to a host of the other issues.
I know this doesn't really answer your question but having been where you are now I can tell you that the old adage, "an ounce of prevention is worth a pound of cure" will save you major headaches down the road.
If you want to see an example of a really good .net MVC project that you can use as sort of a template in building your skills I would recommend the open source shopping cart nopCommerce.

Resources