Viewmodel returning no data - c#

Been trying to follow some online examples, with the aim of moving away from using models for my views, to using viewmodels.
I have a model called 'Property' and i have created a ViewModel called 'PropertyIndexViewModel', which my view is now referencing.
My controller action is:
// GET: Property ***TEST***
public async Task<ActionResult> Index1(int? id, PropertyIndexViewModel viewModel)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Property property = await db.Property.FindAsync(id);
if (property == null)
{
return HttpNotFound();
}
return View(viewModel);
}
My view isn't throwing any errors, but it's also not returning the expected data from the model?

You have to initialize the view model, fill it with the Property model data and return it.
// GET: Property ***TEST***
public async Task<ActionResult> Index1(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Property property = await db.Property.FindAsync(id);
if (property == null)
{
return HttpNotFound();
}
var viewModel = new PropertyIndexViewModel {
Prop1 = property.Prop1
// your stuff
};
return View(viewModel);
}
In your view you have to specify the model:
#model PropertyIndexViewModel

Related

How to pass list of strings to view with action result method in ASP dotNet Core

I have an ActionResult Method which i wanted to return some values to the view for using in a form to submit afterwards.
How can I access these data from view for submition in a form?!
Here is my ActionResult method:
[HttpPost]
public virtual async Task<IActionResult> ImportPhonenumbersFromExcel(IFormFile importexcelfile, int currentFestivalId)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageFestivals))
return AccessDeniedView();
try
{
if (importexcelfile != null && importexcelfile.Length > 0)
{
var result = await _importManager.ImportPhonenumbersFromXlsxAsync(importexcelfile.OpenReadStream());
}
else
{
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Common.UploadFile"));
return RedirectToAction("Edit", new { id = currentFestivalId });
}
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Festival.Phonenumbers.Imported"));
return RedirectToAction("Edit", new { id = currentFestivalId });
}
catch (Exception em)
{
await _notificationService.ErrorNotificationAsync(em);
return RedirectToAction("Edit", new { id = currentFestivalId });
}
}
For strongly typed data a view model is the best option. It is a class with properties that can be used to store your specific values which you want to pass to the view. To use a viewmodel:
Create the viewmodel class and add the properties you need.
Instantiate a new viewmodel object in your controller. The example shown below is from the Microsoft documentation where the viewmodel class is named Address.
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
var viewModel = new Address()
{
Name = "Microsoft",
Street = "One Microsoft Way",
City = "Redmond",
State = "WA",
PostalCode = "98052-6399"
};
return View(viewModel);
}
Once you have set the values of the properties of the viewmodel object in the controller you can then add the viewmodel to the view.
To send the viewmodel to the view, pass it as a parameter:
return View(viewModel);
Finally, add to the top of your view file:
#model yourViewModelsAddress
To refer to the properties of your viewmodel in your view, follow this example:
`#Model.Property`
You can create a view model that will contain the list and everything else you want to pass to the view.
Then in the view you can access it by using #model.

using same ActionLink call two function master and details in same Controller c#

i am new in MVC5. I am trying to load master and details data using ActionResult for retrieving master data and JsonResult for Details retrieving data single click in ActionLink.
public JsonResult getOrderDetails(int? id)
{
List<OrderDetail> OrderDetail = new List<OrderDetail>();
OrderDetail = db.OrderDetails.Where(a => a.OrderID==id).OrderBy(a => a.OrderDetialsID).ToList();
return new JsonResult { Data = OrderDetail, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
OrderMaster OrderMaster = db.OrderMasters.Find(id);
return View(OrderMaster);
}
No, this won't work. It will throw an exception explaining that a link must point to exactly one resource (a.k.a one Controller, one Action). Also, that's not how you normally think of doing it in MVC. This is not WebForms where you load the master and detail separately.
You should be doing something like this instead:
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var orderMaster = db.OrderMasters
.Where(om => om.OrderMasterId == id)
.Include(om => om.OrderDetails) // include the details here
.Single();
return View(orderMaster);
}

Fix error with route url in Asp.Net MVC 5

I have this datamodel:
so one Project has many Milestones.
What I did is this: when I go to the detail of a specific Project, I can add/create Milestones for it, like in the picture:
When I click "Create Milestone" I navigate to the View where I can create the milestone for this specific Project, when I click save, it will automatically be saved for this project. Here the HttpPost method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateMilestone([Bind(Include = "Name,Description,FromDate,DueDate,Finished,ProjectID")] Milestone milestone, int? id)
{
if (ModelState.IsValid)
{
var forProject = db.Projects.Where(x => x.ID == id).FirstOrDefault();
if (forProject != null)
{
milestone.Project = forProject;
db.Milestones.Add(milestone);
db.SaveChanges();
return RedirectToAction("Details", forProject);
}
else
{
return HttpNotFound();
}
}
else
{
return View(milestone);
}
}
Here is a screenshot of the CreateMilestone View, and focus on the url (it's localhost:xxxxx/Projects/CreateMilestone/3002). The id parameter in the CreateMilestone method is for the Project ID, and in the url the id (3002) is also for the project.
I'm trying to make the app to navigate to the Details view of that specific Project I just added a milestone, which I do actually!
And as you see it works:
But: look at the url! Instead of being localhost:xxxxx/Projects/Details/3002 it is: http://localhost:55623/Projects/Details/3002?Milestones=System.Collections.Generic.HashSet%601%5BTheProjectManager.Models.Milestone%5D&Users=System.Collections.Generic.HashSet%601%5BTheProjectManager.Models.ApplicationUser%5D&ProjectName=Testing&Description=Testing%20data
So, how can I make the url be like: localhost:xxxxx/Projects/Details/3002 when I navigate to the details view after adding a new milestone?
UPDATE:
the Get Details:
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Project project = db.Projects.Find(id);
if (project == null)
{
return HttpNotFound();
}
return View(project);
}
and the Get CreateMilestone:
public ActionResult CreateMilestone(int? id)
{
var forProject = db.Projects.Where(x => x.ID == id).FirstOrDefault();
if (forProject != null)
{
return View();
}
else
{
return HttpNotFound();
}
}
In this line
return RedirectToAction("Details", forProject);
you are redirecting to Details action and as parameter you send "Project" object which is serialized to query string. Instead of full object you can use only id. But you also need to change Details action to accept int as parameter instead of Project class
Instead of return RedirectToAction("Details",forProject);
try this return RedirectToAction("Details", new { id = id });

Edit Controller in MVC doesn't change data in database

I am new to ASP.NET MVC and I'm trying to create a small project but I'm stuck in the Edit Controller part.
This is my "real" controller with a function named PostEditViewModel with the queries inside to change the data.
public EditViewModel PostEditViewModel(EditViewModel model)
{
//var model = new EditViewModel();
using (var db = new NorthwindEntities())
{
var dati = db.Products
.Where(p => p.Id == model.Id).Single();
dati.Id = model.Id;
dati.Name = model.Name;
db.SaveChanges();
return model;
}
}
And this is my controller, its function is to only validate the model state.
[HttpPost]
public ActionResult Edit(EditViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
return RedirectToAction("Index");
}
Any help would be appreciated.
My bad, the validation didn't make sense at all.
[HttpPost]
public ActionResult Edit(EditViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
else
{
WorkerServices.PostEditViewModel(model);
return RedirectToAction("Index");
}

MVC how to return a view after an IF statement

My page has a search box which for has a few radio buttons. Depending on which radio button is selected will depend on which view is shown.
However, I don't know how to return the View.
My code is
public ActionResult Index(string jobType)
{
if (jobType.ToLower() == "this")
CandidateResults();
else
JobResults();
}
private ActionResult CandidateResults()
{
var model = //logic
return View(model);
}
private ActionResult JobResults()
{
var model = //logic
return View(model);
}
But this displays nothing on screen (a white page). This makes sense but I don't want to return Index, I want to return a new page (called either JobResults or Candidates) and create a View for both of these new pages but when I right click in my methods (JobResults() or Candidates()) I don't get the option to Add View.
At this stage I'm lost, can any one please give advice.
Either return the view from Index or redirect to CandidateResults or JobResults actions.
public ActionResult Index(string jobType)
{
if (jobType.ToLower() == "this")
return CandidateResults();
else
return JobResults();
}
private ActionResult CandidateResults()
{
var model = //logic
return View(model);
}
private ActionResult JobResults()
{
var model = //logic
return View(model);
}
Try this
public ActionResult Index(string jobType)
{
return (jobType.ToLower() == "this") ?
RedirectToAction("CandidateResults") :
RedirectToAction("JobResults");
}
private ActionResult CandidateResults()
{
var model = //logic
return View(model);
}
private ActionResult JobResults()
{
var model = //logic
return View(model);
}
In your private methods you have to specify the actual view you want to display.
public ActionResult Index(string jobType)
{
if (jobType.ToLower() == "this")
CandidateResults();
else
JobResults();
}
private ActionResult CandidateResults()
{
var model = //logic
return View("CandidateResults", model);
}
private ActionResult JobResults()
{
var model = //logic
return View("JobResults", model);
}
This happens because of the way the view engine works. The action name for the current request is always Index when the index function is called. Even if you call another method, the view engine will use the name of the current action and not the name of the currently executing function.
Just you need to redirect the user to proper controller method and that method will return its View as below:
public ActionResult Index(string jobType)
{
if (jobType.ToLower() == "this")
return RedirectToAction("CandidateResults","ControllerName");
else
return RedirectToAction("JobResults","ControllerName");
}
public ActionResult Index(string jobType)
{
if (jobType.ToLower() == "this")
return RedirectToAction("CandidateResults");
return RedirectToAction("JobResults");
}
private ActionResult CandidateResults()
{
var model = //logic
return View(model);
}
private ActionResult JobResults()
{
var model = //logic
return View(model);
}

Categories

Resources