I have the following code in controller and razor view.
When Upload() is called I want to return another view with the model as the parameter so it's accessible within the view.
But I keep getting "Object reference not set to an instance of an object" on #Model.PhoneNumber
Another question is that does the model has to be strongly typed? It seems when I pass in new { PhoneNumber = "123456" } the property can't be accessed from view either.
[HttpGet]
[Route("{code}/CertificateValidation")]
public ActionResult CertificateValidation()
{
return View();
}
[HttpPost]
public ActionResult Upload(FormCollection file)
{
return View("CertificateValidation", new IndexViewModel { PhoneNumber = "123456" });
}
View:
model WebApplicationMVC.Models.IndexViewModel
<p>#Model.PhoneNumber </p>
Problem is with your get Method.
Your following method does not return any model. So Model is null so it gives error.
[HttpGet]
[Route("{code}/CertificateValidation")]
public ActionResult CertificateValidation()
{
var model = new IndexViewModel();
return View(model);
}
The way you are returning the view with the model is correct and should not have any issue.
return View("CertificateValidation", new IndexViewModel { PhoneNumber = "123456" });
That said, most probably your actual code would not be like this and might be fetching data from some source like a database probable, which could be returning null which you can investigate by debugging or writing null checks.
For the second answer, if you are specifying the type of the model in the view with the #model directive, you have to provide an instance of this type in the return View() method call. Alternatively you can use the #model dynamic which would allow you to pass anything as the model. See this link
Related
I have this controller like so:
public class PreviewController : Controller
{
// GET: Preview
public ActionResult Index()
{
string name = Request.Form["name"];
string rendering = Request.Form["rendering"];
var information = new InformationClass();
information.name = name;
information.rendering = rendering;
return View(information);
}
}
and in the view, I am trying to the information.name like so:
#ViewBag.information.name
I also tried just:
#information.name
but got the same error for both:
Cannot perform runtime binding on a null reference
What am I doing wrong?
You must use #Model.name in view. Not #ViewBag.information.name. Also in top of your view you must define something like this:
#model Mynamespace.InformationClass
And it would be better to use MVC's model binding feature. Therefore change your action method like this:
public class PreviewController : Controller
{
[HttpPost] // it seems you are using post method
public ActionResult Index(string name, string rendering)
{
var information = new InformationClass();
information.name = name;
information.rendering = rendering;
return View(information);
}
}
In the view just type
#Model.name
Since InformationClass is your model you just call its properties from the view using #Model
You need to set ViewBag.InformationName in your action:
ViewBag.InformationName = name;
And then in your view you could reference it:
#ViewBag.InformationName
Or if you're trying to work with the model data in the view, you'd reference it through this:
#Model.name
Please add that sample to your view file
#model Your.Namespace.InformationClass
That line is responsible for defining your model type. And after that you can just use:
#Model.name;
I'm developing a Web Application by using ASP.Net MVC 5. My model is something similar to:
Person
- int ID
- string FullName
- int PersonTypeId
PersonType
- Id
- Name
- Description
I'm working on the "create new Person" page. I have created a ViewModel with the following structure:
public class SampleAddViewModel
{
public Person person;
public SelectList personTypes; // Used to populate the DropDown element.
}
My controller's GET method (to simply display the page):
// GET: Add new person
public ActionResult Add()
{
SampleAddViewModel savm = new SampleAddViewModel();
AddPersonViewModel.personTypes = new SelectList(PersonTypesEntity.GetAll(), "Id", "Name");
return View(savm);
}
In my controller's POST method (to store the created person) I would expect to just receive the Person model, and not the entire ViewModel. But on the View page I think it is only possible to declare an #model razon line, which I think it must be #model SampleAddViewModel ...
Would it be possible to, in the POST Add entry, have something similar to the following:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Add([Bind(Include = "ID, Name, PersonTypeId")] Person person)
{
if (ModelState.IsValid)
{
db.Add(person);
db.SaveChanges();
return RedirectToAction("Index");
}
x <- //Should I re-create the ViewModel in here?
return View(x);
}
Which would be the best way to address the problem? I'm also trying to avoid using ViewBag. Maybe the best way in fact is to re-send the entire ViewModel.
If you have any errors on the server side on the POST method then yes, you'd want to send the ViewModel back to the view.
Since you are only sending a Person instance into the controller action and your View is expecting an instance of SampleAddViewModel, you should create an instance of one of these and pass it to the View; After all, you're going to need to repopulate the personTypes dropdown with data again.
I have an action defined like this:
public ActionResult TempOutput(string model)
{
return View(model);
}
And also, I have its view defined like this:
#model String
#{
ViewBag.Title = "TempOutput";
}
<h2>TempOutput</h2>
<p>#Model</p>
Then, at one place, I have a return statement like this:
return RedirectToAction("TempOutput", "SEO", new { model = "Tester text" });
And the point is that when I get to my TempOutput view I get an error message saying "The view 'Tester text' or its master was not found or no view engine supports the searched locations.". But I jsut want to print the value of the string inside my view. How can I achieve it?
You are calling different override of View than you want:
View(string viewName);
You want to call View(string viewName, string masterName, object model) like following:
return View(null, null, model);
You can also specify explicit value (i.e. "TempOutput") for view name.
Alternatively you can force selecting View(object model) override by casting "model" to object:
return View((object)model);
Or, you can overload it using Named Arguments
return View(model: model)
If I remember correctly if you have to use the RedirectToAction you can pass model data like this:
TempData["model"] = "Tester text";
return RedirectToAction("TempOutput", "SEO");
More information about TempData found here.
I am trying to pass an value from my view to my controller:
public ActionResult Create(int id)
{
ViewBag.ConferenceRegesterId = id;
return View();
}
As you can see in create action i save my id in viewbag .i need this id in post back so i have this code for postback :
[HttpPost]
public ActionResult Creat(MvcConference.Models.Details1 ObjDetails)
{
dbcontext.Details1.Add(ObjDetails);
dbcontext.SaveChanges();
List<MvcConference.Models.Details1> lstuser = dbcontext.Details1.ToList();
return View("Index");
}
I use this code to assign my viewbag value to my model item in my create view
#Html.HiddenFor(model => model.ConferenceRegesterId=ViewBag.ConferenceRegesterId)
but finally after executing i got this error :
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS1963: An expression tree may not contain a dynamic operation
I will be apprciate for any help
Best regards
You can't just assign the value for a model's property in a view (through viewbag) like the way you're currently doing, because you're not creating an instance of the class. Please note that only value bound to the input elements are posted back to the controller.
Slightly change the way your program currently behaves. Your create action in the controller will crate an instance for your viewmodel and initialize the required members (ConferenceRegesterId). This model will be strongly bound to the create view.
public ActionResult Create(int id)
{
MvcConference.Models.Details1 viewmodel = new MvcConference.Models.Details1();
viewmodel.ConferenceRegesterId = id;
return View(viewmodel);
}
Your create view
#model MvcConference.Models.Details1
#using (Html.BeginForm())
{
......
#Html.HiddenFor(model => model.ConferenceRegesterId)
}
Now your ObjDetails in POST action can access the value of ConferenceRegesterId you passed through the hiddenfield input element.
You don't need any model. That's simple problem. When you use a ViewBag you must convert that object to static object on your Razor View.
Like that;
#{
string varName = ViewBag.varName;
}
And you will not see again that;
Compiler Error Message: CS1963: An expression tree may not contain a dynamic operation
This question is related to another I ask recently, it can be found here for some background information.
Here is the code in the Edit ActionResult:
public virtual ActionResult Edit(int id)
{
///Set data for DropDownLists.
ViewData["MethodList"] = tr.ListMethods();
ViewData["GenderList"] = tr.ListGenders();
ViewData["FocusAreaList"] = tr.ListFocusAreas();
ViewData["SiteList"] = tr.ListSites();
ViewData["TypeList"] = tr.ListTalkbackTypes();
ViewData["CategoryList"] = tr.ListCategories();
return View(tr.GetTalkback(id));
}
I add lists to the ViewData to use in the dropdownlists, these are all IEnumerable and are all returning values.
GetTalkback() returns an Entity framework object of type Talkback which is generated from the Talkback table.
The DropDownListFor code is:
<%: Html.DropDownListFor(model=>model.method_id,new SelectList(ViewData["MethodList"] as IEnumerable<SelectListItem>,"Value","Text",Model.method_id)) %>
The record I am viewing has values in all fields. When I click submit on the View, I get an Object reference not set to an instance of an object. error on the above line.
There are a number of standard fields in the form prior to this, so the error is only occurring on dropdown lists, and it is occurring on all of them.
Any ideas? This is my first foray in to MVC, C#, and Entity so I am completely lost!
If you have [HttpPost] method like that
[HttpPost]
public ActionResult Edit(Talkback model)
{
//Do something with model
return View(model);
}
You have to fill ViewData again. If you don't do it, you'll have Object reference not set to an instance of an object errors.
The best thing to do would be to follow POST-REDIRECT-GET patter and do it like that:
[HttpPost]
public ActionResult Edit(Talkback model)
{
//Do something with model
return RedirectToAction("Edit", new { id = model.id });
}
You'll have ViewData filled again by [HttpGet] method.