Model does not contain a definition for 'input' - c#

I am trying to take what a user inputs in a textbox from the view and add it to a String in the model. Errors I am getting are:
'System.Collections.Generic.IEnumerable' does not contain a definition for 'input'
and
no extension method 'input' accepting a first argument of type 'System.Collections.Generic.IEnumerable' could be found (are you missing a using directive or an assembly reference?)
Inside my View:
#using (Html.BeginForm("Summary", "inquire", FormMethod.Post))
{
#Html.TextBoxFor(model => model.input)
Model:
namespace myProj.Models
{
public class myModel
{
[RegularExpression("([1-9][0-9]*)")]
[StringLength(9, MinimumLength = 3)]
public string input { get; set;}
..
Controller:
public ActionResult Summary(String input)
{
..
if (Request.HttpMethod.ToLower().Equals("get"))
{
return View();
}
else
{
..
return View(model);
}
}
Issue I am having in the view with the TextBoxFor line in my view, if I put #model myProj.Models.myModel at the top I can get it to work, however I need to use #model IEnumerable when I want to use foreach and display the data I get from this input to a table.
I feel it's something simple I am missing, but i fail to see it.

If you're wanting to use multiple instances of your model, you're going to have to iterate them in your view, something like this:
#model List<myProj.Models.myModel>
Then do:
for (int i = 0; i < Model.Count(); i++)
{
#Html.TextBoxFor(m => m[i].input)
}
We'll need to change your ActionResult to handle multiple models though
Note, you don't have to check the request type if it's a HttpGet, let's split it out into two methods
[HttpGet]
public ActionResult Summary()
{
return View(new List<myProj.Models.myModel>());
}
[HttpPost]
public ActionResult Summary(List<myProj.Models.myModel> input)
{
return View(input);
}

Related

MVC ViewModels - Can't access objects/variable passed from controller to View

I am trying to pass ModelView variables from controller to views but unfortunately views not allowing me to access variables. I mention code below.
Here is the ViewModel:
public class AuctionViewModels
{
public List<Auction> AllAuction { get; set; }
public List<Auction> PromotedAuction { get; set; }
}
Here is the Controller action that passes the data to the View:
public ActionResult Index()
{
AuctionViewModels vmodel = new AuctionViewModels();
vmodel.AllAuction = service.GetAllAuction(); //If we need to send more then 1 model to views
vmodel.PromotedAuction = service.GetPromotedAuction();
return View(vmodel);
}
Here is view:
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
#foreach (var auction in Model.AllAuction )
{
<img class="card-img-top" src="http://placehold.it/700x400" alt="">
}
Here is Error:
CS1061: 'List<AuctionViewModels>' does not contain a definition for
'AllAuction' and no extension method 'AllAuction' accepting a first
argument of type 'List<AuctionViewModels>' could be found (are you missing
a using directive or an assembly reference?)
Can anyone tell me what actually i am doing wrong?
Change
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
To
#model DealDouble.Web.ViewModels.AuctionViewModels
Then you'll be able to do foreach(var auction in Model.AllAuction)
you have error in line:
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
you pass (as a model) Class, not list. List does not contain such property as AllAuction. try to replace this line with this one:
#model DealDouble.Web.ViewModels.AuctionViewModels
It should just be
#model DealDouble.Web.ViewModels.AuctionViewModels
You're only passing in one instance of this object, and then iterating over the AllAuction property.
You're instantiating a single object containing two fields both of which are lists:
AuctionViewModels vmodel = new AuctionViewModels();
vmodel.AllAuction = service.GetAllAuction(); /
vmodel.PromotedAuction = service.GetPromotedAuction();
But treating it as if it were a list in the view
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
You need to change the above to:
#model DealDouble.Web.ViewModels.AuctionViewModels
You can then iterate over the two fields
#foreach (var auction in Model.AllAuction ){}
#foreach (var auction in Model.PromotedAuction ){}

pass key value pair to controller

I've seen a couple possible solutions but they look very messy to me. Does anyone have a simple solution for this?
Model:
public class MyClass
{
public KeyValuePair<int,string> Field { get; set; }
}
Get method in controller:
public ActionResult Index()
{
var model = new MyClass();
model.Field = new KeyValuePair<int, string>(1, "test");
return View(model);
}
View:
#model WebApplication1.Models.MyClass
#using (Html.BeginForm("MyMethod", "Home", FormMethod.Post))
{
#Html.Hidden("Field", Model.Field);
<input type="submit" value="Submit" />
}
Post method in controller:
public ActionResult MyMethod(MyClass input)
{
var x = input.Field;
....
}
The Key Value pair is not passed with this method as it just comes up empty. What would be the easiest way of getting 'Field' passed to the controller?
Replace following line and try it.let me know any problem.
#Html.Hidden("Field", Model.Field);
TO
#Html.HiddenFor(m => m.Field);
If memory serves correctly, it has a Key and Value property, which like any other object would be bound like:
#Html.HiddenFor(m => m.Field.Key)
#Html.HiddenFor(m => m.Field.Value)
One input field can't represent the key and value in this way, unless you look at using a Custom Model Binder to manage the value posted back, and a Display/Editor template to render the input in a way the model binder will understand.
Following Brians answer, I've had to accept I must do it like this:
Class:
public class MyClass
{
public KeyValuePair<int,string> Field { get; set; }
public string FieldKey { get; set; }
public string FieldValue { get; set; }
}
View:
#Html.Hidden("FieldKey",Model.Field.Key)
#Html.Hidden("FieldValue", Model.Field.Value)
It will get messy as I have many of these kvp's I'd like to pass back to the controller, but I guess it's the only uncomplicated way. It's not the first time I've wished it was possible to pass objects to a controller, and I'm sure it won't be the last. Maybe we'll get the happy news in a dotnet update one day that we can do things like this more easily.

MVC4 cshtml page function call

I need to display a value in an editable textbox on my mvc page when it first loads if it exists. I've got a function that will take care of getting the value that I need, but I need to pass in parameters from the current model to get what I need from the database.
The problem I'm having is getting this value into the textbox. What I tried was
cshtml:
#Html.TextBoxFor(model => model.AdjustedLiabilityAmount, new { #Value=OBS_LIB.BLL.JeopardyAssessment.JeopardyAssessment.GetLatestAdjustedLiabilityAmount(Model.DOTNumber, Model.LiabilityAmount))}
I get a red squiggly that "The name 'Value' does not exist in the current context"
So I tried a different technique I read about which was like this.
Controller:
public ActionResult Index()
{
ViewBag.AdjustedValue = OBS_LIB.BLL.JeopardyAssessment.JeopardyAssessment.GetLatestAdjustedLiabilityAmount(Model.DOTNumber, Model.LiabilityAmount);
cshtml:
#Html.TextBoxFor(model => model.AdjustedLiabilityAmount, new { #Value=ViewBag.AdjustedValue)}
This time I'm getting the red squiggly "The name 'Model' does not exist in the current context."
I'm sure I'm just missing something basic here as I'm new to MVC.
Any help is much appreciated.
Entire ActionResult Index:
public ActionResult Index()
{
ViewBag.AdjustedValue = OBS_LIB.BLL.JeopardyAssessment.JeopardyAssessment.GetLatestAdjustedLiabilityAmount(Model.DOTNumber, Model.LiabilityAmount);
var Report = new OBS_LIB.DTO.JeopardyAssessmentReport();
Report.Stage = 1;
Report.Status = "Active";
Report.ReportItems = OBS_LIB.BLL.JeopardyAssessment.JeopardyAssessment.GetJAReportItems(Report.Stage, Report.Status);
return View(Report);
}
You want to do something like this:
Class:
public class ModelClassHere {
public float Liability {get;set;}
}
Controller:
public ActionResult Index(ModelClassHere model) {
model.Liability = 10.00;
return View(model); // pass model to the view
}
View:
#Html.TextBoxFor(x => x.Liability) // 'x' can be anything
EDIT*
If you already have a model and need to pass one simple value:
Controller:
public ActionResult Index(ModelClassHere model, string otherValue) {
model.Liability = 10.00;
ViewBag.Liability = model.Liability;
return View(model); // pass model to the view
}
View:
<input type="text" id="otherValue" name="otherValue" value="#ViewBag.Liability.ToString()" />
You can use
#Html.TextBox("AdjustedLiabilityAmount", (Decimal)ViewBag.AdjustedValue)}
Or
#Html.TextBox("AdjustedLiabilityAmount", Model.AdjustedLiabilityAmount == null ? (Decimal)ViewBag.AdjustedValue : Model.AdjustedLiabilityAmount)}
In decimal type you put your the type that you need.
You need to pass your model in the
Controller
return view(myModelName);
make sure you have access to it in your controller.
also your view has to reference the model in the #model line at the top.
Finally to call the model it would be
view:
Model.myModelName

MVC HttpPost strongly typed Model null

View Model looks like this:
public class AsmenysInfoViewModel2
{
public asmenys_info Asmenys_info { get; set; }
public List<miestai> Miestai { get; set; }
public string Test { get; set; }
}
And there are two actions. Get and Post.
public ActionResult Index(long? id)
{
var model = new AsmenysInfoViewModel2();
model.Test = "Test";
model.Asmenys_info = BllFactory.DalFactory.AsmenysInfoDal.GetById(id.Value);
return View(model);
}
[HttpPost]
public ActionResult Index(AsmenysInfoViewModel2 asmenys_info)
{
var model = asmenys_info;
return View(model);
}
And my view looks like this:
#model MODELS.AsmenysInfoViewModel2
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm("Index", "AsmenysInfo", FormMethod.Post))
{
#Html.ValidationSummary()
#Html.TextBoxFor(m => m.Asmenys_info.adresas)
<input type="submit" value="Išsaugoti" />
}
Doesn't matter if I use EditorFor or TextBoxFor - result is same. My model property "Asmenys_info" on posting is always null. If my class AsmenysInfoViewModel2 would not contain asmenys_info type property and would contain only "string, int etc" (no strongly typed) - it would work.
My question is :
How to post View Model which has strongly typed property which on posting would not be null?
Your model has a property named Asmenys_info and the parameter in your POST method is also named asmenys_info. Internally the DefaultModelBinder reads the values of the form data which includes a value for Asmenys_info and attempts to set property Asmenys_info to that value but it fails because there is no conversion from a string to a complex object.
Change the name of the parameter to anything other than a name of a property in your model and it will bind fine, for example
[HttpPost]
public ActionResult Index(AsmenysInfoViewModel2 model)
Change the below line with another object name
public ActionResult Index(AsmenysInfoViewModel2 asmenys_info)
in above method use any other name of object instead of asmenys_info.
because while mvc framework map your model with object there is confution in asmenys_info and Asmenys_info property of AsmenysInfoViewModel2 class.

How does my view know what type of data is being returned using MVC?

So I created a project to test DI in MVC 4. Yeah, that was the easy part. I have a controller that looks like this.
public class CompanyManagementController : Controller
{
private ICompanyService companyService;
public CompanyManagementController(ICompanyService companyService)
{
this.companyService = companyService;
}
public ActionResult Index()
{
return View(companyService.GetCurrentCompanies());
}
}
What I can't figure out is how to tell the view Index.cshtml that I have this List that I am returning to it. When I have just a POCO it's easy. I did this
[HttpGet]
public ActionResult Create()
{
var company = new Company();
return View(company);
}
[HttpPost]
public ActionResult Create(Company company)
{
using(var context = new InventoryContext())
{
context.Companies.Add(company);
context.SaveChanges();
}
return View("Create");
}
That was super easy because I just said
#model MvcInventoryManager.Models.Company
in the Create.cshtml file.
Any hints? What I want to do is be able to loop through the list of companies that get returned.
Thanks!
What is the return type of companyService.GetCurrentCompanies()? That would be the type you'd want to use for binding the Model in the view. For example, if the type is IEnumerable<Company> then in your view you would declare this:
#model IEnumerable<MvcInventoryManager.Models.Company>
That way the type of the Model property would match what's being passed to the view and you could loop through the Model:
foreach (var company in Model)
after declaring your model in the view just loop through it like so:
#foreach (var company in Model)
{
Html.DisplayFor(modelItem => company.companyID)
Html.DisplayFor(modelItem => company.CompanyName)
}

Categories

Resources