Why is my http post returning null from my view model - asp.net-mvc

This is my model:
public class Attribute
{
public string Key { get; set; }
public string Value{ get; set; }
}
I fill it in my GET create
public ActionResult Create()
{
var Attributes = new[]
{
new Attribute {Key = "Name" Value = "" },
new Attribute {Key = "Age" Value = "" },
};
return View(Attributes);
}
My View looks like this:
#model IEnumerable<Customers.ViewModels.Attribute>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
#foreach (var item in Model)
{
<div class="editor-label">
#Html.Label(item.Key)
</div>
<div class="editor-field">
#Html.EditorFor(m => item.Value)
#Html.ValidationMessageFor(m => item.Value)
</div>
}
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Then My Post Create looks like this:
[HttpPost]
public ActionResult Create(IEnumerable<Attribute> attributes)
{
}
but my IEnumerable<Attribute> attributes is null. Any suggestions?

You need to create a editor template for a Attribute and then pass the List<Attribute> model to it.
#Model Attribute
<div class="editor-label">
#Html.LabelFor(m => m.Key)
</div>
<div class="editor-field">
#Html.EditorFor(m => m.Value)
#Html.ValidationMessageFor(m => item.Value)
</div>
In your view use:
<fieldset>
#Html.EditorFor(m > m)
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
You need to do this because the foreach doesn't create the correct name for the elements.

Related

ASP.NET MVC: Values are null when they reach the Controller

So I have the following Controller:
[HttpPost]
public ActionResult CreateSupport(CreateSupport model)
{
if (ModelState.IsValid && (model.Description != null))
{
model.CreatedById = UserId;
model.ModifiedById = UserId;
}
return View(model);
}
I have the following view:
#using (Html.BeginForm("CreateSupport", "Support", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend></legend>
<div class="editor-label">
#Html.LabelFor(model => model.Subject, new Dictionary<string, object>() { { "class", "req" } })
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Subject)
#Html.ValidationMessageFor(model => model.Subject)
</div>
<div class="support-form-left">
<div class="editor-label">
#Html.LabelFor(model => model.BrowserInfo, new Dictionary<string, object>() { { "class", "req" } })
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.BrowserInfo)
#Html.ValidationMessageFor(model => model.BrowserInfo)
</div>
</div>
<div class="support-form-right">
<div class="editor-label">
#Html.LabelFor(model => model.DatabaseVersion, new Dictionary<string, object>() { { "class", "req" } })
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.DatabaseVersion)
#Html.ValidationMessageFor(model => model.DatabaseVersion)
</div>
</div>
<div class="clearFloat"></div>
<div class="editor-label">
#Html.LabelFor(model => model.Description, new Dictionary<string, object>() { { "class", "req" } })
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
<div class="actionButtons">
<button id="btnCancel" class="myButtonCancel">Cancel</button>
<input type="submit" value="Submit" class="myButton" />
</div>
#if (ViewBag.SuccessMessage != null)
{
<div>
<label style="color: red;">#ViewBag.SuccessMessage</label>
</div>
}
</fieldset>
}
Here's the Model:
public class CreateSupport : SupportTicket
{
public CreateSupport()
{
ProductList = new List<Product>();
ProductVersionsList = new List<ProductVersion>();
EnviromentList = new List<InstallationEnvironment>();
content = new Content();
}
[Required]
[UIHint("tinymce_jquery_full"), AllowHtml]
public string Description { get; set; }
[Required]
[DisplayName("Browser version Info.")]
public string BrowserInfo { get; set; }
[Required]
[DisplayName("Database Version")]
public string DatabaseVersion { get; set; }
public Content content { get; set; }
}
The problem is that the values that reach the Controller are NULL even if you enter some value in them.
You should check your browser's developer tools to see if the form is properly posting its values. If it isn't, you should do two things:
A) Disabled javascript to see if there is a script that is interfering with the POST (typically either by disabling or clearing fields)
B) Ensuring your markup is valid using the W3C markup validation service
For input fields use
#Html.EditorFor(x => x.Subject)
For display fields use
#Html.DisplayFor(x => x.Subject)

pass value of List

i try to show my data using viewmodel, but i have error like this
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[XNet.Repository.Model.FacilityViewModel]', but this dictionary requires a model item of type 'XNet.Repository.Model.FacilityViewModel'.
how i can solve my problem??
this my code
my service
public List<FacilityViewModel> GetViewHotel(int HotelID)
{
List<Hotel> Hotels = (from d in _HotelRepository.All()
where d.HotelID == HotelID
select d).ToList();
List<FacilityViewModel> facilityViewModel = new List<FacilityViewModel>();
foreach (Hotel hotel in Hotels)
{
facilityViewModel.Add(new FacilityViewModel
{
HotelID = HotelID,
HotelName = hotel.HotelName,
Address1 = hotel.Address1,
Address2 = hotel.Address2,
HotelDescription = hotel.HotelDescription,
HotelInformation = hotel.HotelInformation,
});
}
return facilityViewModel;
}
my controller
public ActionResult Index()
{
//var x = _hotelService.GetByID(_HotelID);
List<FacilityViewModel> facilityViewModel = _viewService.GetViewHotel(_HotelID);
return View(facilityViewModel);
}
my viewmodel
public class FacilityViewModel
{
public int HotelID { get; set; }
public string HotelName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string HotelDescription { get; set; }
public string HotelInformation { get; set; }
}
my view
#model XNet.Repository.Model.FacilityViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<fieldset>
<legend></legend>
<div class="display-label">
#Html.Label("Hotel ID")
</div>
<div class="display-field">
#Html.DisplayFor(model => model.HotelID)
</div>
<br />
<div class="display-label">
#Html.Label("Hotel Name")
</div>
<div class="display-field">
#Html.DisplayFor(model => model.HotelName)
</div>
<br />
<div class="display-label">
#Html.Label("Address 1")
</div>
<div class="display-field">
#Html.DisplayFor(model => model.Address1)
</div>
<br />
<div class="display-label">
#Html.Label("Address 2")
</div>
<div class="display-field">
#Html.DisplayFor(model => model.Address2)
</div>
<br />
<div class="display-label">
#Html.Label("Hotel Description")
</div>
<div class="display-field">
#Html.DisplayFor(model => model.HotelDescription)
</div>
<br />
<div class="display-label">
#Html.Label("Hotel Information")
</div>
<div class="display-field">
#Html.DisplayFor(model => model.HotelInformation)
</div>
<br />
<br />
</fieldset>
<br />
<input style="width:100px;" type="button" title="EditHotelDetail" value="EditDetails" onclick="location.href='#Url.Action("Edit", "Hotel", new { HotelID = Model.HotelID})'" />
The error message says it all.
Your view has the model typed as just the instance of FacilityViewModel while you are returning a List of FacilityViewModel from the action
In your view:
#model XNet.Repository.Model.FacilityViewModel
In your action:
List<FacilityViewModel> facilityViewModel = _viewService.GetViewHotel(_HotelID);
return View(facilityViewModel); //<-- This is a list.
Either
return View(facilityViewModel.First()) //just an example to show a single instance.
or
Modify the code to handle a list in the view.
Your declaring you model for the View as:
#model XNet.Repository.Model.FacilityViewModel
Instead of:
#model List<XNet.Repository.Model.FacilityViewModel>
In your controller's action you are returning a List to the View.
Either modify the model to take a List<FacilityViewMOdel> in the View or return a single FacilityViewModel to the View.
return View(facilityViewModel.FirstOrDefault());

HttpPostedFileBase not binding to model

here is my ViewModel
public class FaultTypeViewModel
{
[HiddenInput(DisplayValue = false)]
public int TypeID { get; set; }
[Required(ErrorMessageResourceType = typeof(AdministrationStrings), ErrorMessageResourceName = "FaultTypeNameRequired")]
[Display(ResourceType = typeof(AdministrationStrings), Name = "FaultTypeName")]
public string TypeName { get; set; }
[Display(ResourceType = typeof(AdministrationStrings), Name = "FaultTypeDescription")]
[DataType(DataType.MultilineText)]
public string TypeDescription { get; set; }
[Display(ResourceType = typeof(AdministrationStrings), Name = "FaultTypeImageFile")]
public HttpPostedFileBase TypeImageFile { get; set; }
[HiddenInput(DisplayValue = false)]
public string TypeImageURL { get; set; }
}
Notice I have a "TypeImageFile" HttpPostedFileBase
I would expect that the model binder would bond that property from the form to the model passes to the controller bu I just keep receiving null.
here is the relevant code in the View:
#using (Html.BeginForm("AddFaultType","Administration", FormMethod.Post))
{
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×</button>
<h3 id="myModalLabel">#SharedStrings.Add #SharedStrings.FaultType</h3>
</div>
<div class="modal-body">
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.TypeName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TypeName)
#Html.ValidationMessageFor(model => model.TypeName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.TypeDescription)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TypeDescription)
#Html.ValidationMessageFor(model => model.TypeDescription)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.TypeImageFile)
</div>
<div class="editor-field">
<input type="file" name="TypeImageFile" id="TypeImageFile" />
</div>
</div>
<div class="modal-footer">
<input type="submit" value="#SharedStrings.Add" class="btn btn-primary" />
#Html.ActionLink(SharedStrings.Cancel, "Index", "Administration", null, new { Class = "btn", data_dismiss = "modal", aria_hidden = "true" })
</div>
}
and here is the controller:
[HttpPost]
public ActionResult AddFaultType(FaultTypeViewModel i_FaultToAdd)
{
var fileName = Path.GetFileName(i_FaultToAdd.TypeImageFile.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
i_FaultToAdd.TypeImageFile.SaveAs(path);
return RedirectToAction("Index");
}
Make sure you've set the enctype attribute on your form to multipart/form-data on your form if you want to be able to upload files:
#using (Html.BeginForm("AddFaultType", "Administration", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
}
Completing Darin's answer:
Make sure you've set the enctype attribute on your form to multipart/form-data on your form if you want to be able to upload files:
#using (Html.BeginForm("AddFaultType", "Administration", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
}
To ensure your <input> is transmitted to the controller as part of the model use the Html Helpers for Id and name like below:
<input type="file" id="#Html.IdFor(x=>x.HttpPostedFileBase)" name="#Html.NameFor(x=>x.HttpPostedFileBase)" accept=".csv,.txt"/>
Works in MVC5 sorry I cant find any reference to which helpers are available in MVC3

MVC3 - How to add dropdown to a form (Post) populated with different entity

Hi I am working in a MVC 3 application. I have a Create Form with following code.
#model Xrm.Student
#{
ViewBag.Title = "Create Student Record";
}
#using (Html.BeginForm("Create", "Student", FormMethod.Post))
{
<div class="editor-label">
#Html.LabelFor(model => #Model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => #Model.FirstName)
#Html.ValidationMessageFor(model => #Model.FirstName)
</div>
<div>
<input id="Submit1" type="submit" value="Submit" />
</div>
}
I want to add a new drop down under Firsname field which should be populated with pubjects. Subject is different Entity. I could be very easy, but I am newbie with MVC so I just stuck here. Can anyone please suggest me the way to achieve it.
Thanks and Regards
I would define a view model:
public class MyViewModel
{
public Student Student { get; set; }
[DisplayName("Subject")]
[Required]
public string SubjectId { get; set; }
public IEnumerable<Subject> Subjects { get; set; }
}
and then have your controller populate and pass this view model to the view:
public ActionResult Create()
{
var model = new MyViewModel();
model.Student = new Student();
model.Subjects = db.Subjects;
return View(model);
}
and finally have your view strongly typed to the view model:
#model MyViewModel
#{
ViewBag.Title = "Create Student Record";
}
#using (Html.BeginForm())
{
<div class="editor-label">
#Html.LabelFor(x => x.Student.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(x => x.Student.FirstName)
#Html.ValidationMessageFor(x => x.Student.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(x => x.SubjectId)
</div>
<div class="editor-field">
#Html.DropDownListFor(
x => x.SubjectId,
new SelectList(Model.Subjects, "Id", "Name"),
"-- Subject --"
)
#Html.ValidationMessageFor(x => x.SubjectId)
</div>
<div>
<input type="submit" value="Submit" />
</div>
}
The "Id" and "Name" values I used for the SelectList must obviously be existing properties on your Subject class that you want to be used as respectively binding the id and the text of each option of the dropdown.

MVC 3 dropdown list not getting any values

I have a dropdownlist in an MVC 3 create page, however I am not getting any values when I POST the page. My code is as follows :-
View :-
#using (Html.BeginForm("Create", "League", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
League
<div class="editor-label">
#Html.LabelFor(model => model.League.fk_CountryID, "Country")
</div>
<div class="editor-field">
#Html.DropDownList("fk_CountryID", "--Select One--") *
#Html.ValidationMessageFor(model => model.League.fk_CountryID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.League.LeagueName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.League.LeagueName)
#Html.ValidationMessageFor(model => model.League.LeagueName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.League.Image)
</div>
<div class="editor-field">
Upload File: <input type="file" name="Image" />
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Controller :-
[HttpPost]
public ActionResult Create([Bind(Exclude = "Image")]Country country, HttpPostedFileBase Image, League league)
{
if (ModelState.IsValid)
{
model.League = league;
try
{
foreach (string file in Request.Files)
{
HttpPostedFileBase fileUploaded = Request.Files[file];
if (fileUploaded.ContentLength > 0)
{
byte[] imageSize = new byte[fileUploaded.ContentLength];
fileUploaded.InputStream.Read(imageSize, 0, (int)fileUploaded.ContentLength);
model.League.Image = imageSize;
}
}
db.Leagues.AddObject(model.League);
db.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception e)
{
ModelState.AddModelError("uploadError", e);
}
}
What am I doing wrong? Cannot get the dropdownlist value in the controller.
Thanks for your help and time
Ok fixed it by adding a SelectList in my ViewModel as follows :-
//Countries dropdown List
public SelectList CountryList { get; set; }
public string SelectedCountry { get; set; }
public LeagueData PopulateCountriesDDL(string selected, Country country)
{
var typeList = new SelectList(db.Countries.ToList(), "CountryID", "CountryName", selected);
LeagueData model = new LeagueData { CountryList = typeList, Country = country, SelectedCountry = selected };
return model;
}

Resources