I have a tuble like this as model.
#model Tuple<Urun,List<UrunKatagori>>
inside the view I need to pass those data to controler.
here is the my button.
Html.X().Button().Text("Guncelle").Icon(Icon.PageSave)
.DirectEvents(de =>
{
de.Click.Url = "Urunler/Guncelle";
de.Click.ExtraParams.Add(new Parameter { Name = "Urun", Value ="Model.Item1", Mode = ParameterMode.Raw });//Iguess here is wrong
})
and my controller
[HttpPost]
public ActionResult Guncelle (Urun Urun){
Urun_BLL urun_bll = new Urun_BLL();
// urun_bll.Update(mdl);
X.Msg.Notify(new NotificationConfig
{
Icon = Icon.Accept,
Title = "Working",
Html =Urun.Ad.ToString()//I need to get data here
}).Show();
return this.Direct();
}
I strongly suggest that you create a viewmodel class, rather then passing a Tuple e.g.
public class GuncelleViewModel
{
public Urun Urun { get ;set; }
public List<UrunKatagori>> UrunKatagori { get; set; }
}
Then you can pass that to the view like so:
[HttpPost]
public ActionResult Guncelle (Urun Urun)
{
Urun_BLL urun_bll = new Urun_BLL();
// urun_bll.Update(mdl);
X.Msg.Notify(new NotificationConfig
{
Icon = Icon.Accept,
Title = "Working",
Html =Urun.Ad.ToString()//I need to get data here
}).Show();
var viewModel = new GuncelleViewModel()
viewModel.Urun = Urun;
viewModel.UrunKatagori = // TODO - However you get the categories.
return View(viewModel);
// this.Direct(); What does this.Direct() do? Replace it with calling the view instead, much cleaner.
}
In the view, use the following model
#model GuncelleViewModel
Useing a viewmodel class, which is associated one-to-one with a view file (*.cshtml), is a very good practise. It can help keep your design clean and more flexible, rather then passing specific data types, such as Tuple.
Related
I am trying to pass a parameter value from my url back to the view model. Here is the url: StudentDetails/MarkingToolView/1?studentId=1
I am trying to get the first parameter of 1 (after MarkingToolview/) so I can post it back to my database
my viewModel:
public class MarkingVM
{
public int? ModuleID { get; set; }
}
my view:
#Html.HiddenFor(m => m.ModuleID, new { id = ??? })
What is the best way to do this?
I think you are asking how to get the url parameter into your view perhaps? Something like the following will populate your view model.
Controller
public action MarkingToolView(int studentId)
{
MarkingVM vm = new MarkingVM(); //or however that is initialized.
vm.ModuleID = studentId;
return View(vm);
}
I have a _LoginPartial View and want to send data to it by ViewBag, but the Controller that I'am sending data from, doesn't have a View.
public PartialViewResult Index()
{
ViewBag.sth = // some data
return PartialView("~/Views/Shared/_LoginPartial.cshtml");
}
This code didn't work for me.
It seems you're expecting this Index action to be called when you do: #Html.Partial('_LoginPartial'). That will never happen. Partial just runs the partial view through Razor with the current view's context and spits out the generated HTML.
If you need additional information for your partial, you can specify a custom ViewDataDictionary:
#Html.Partial("_LoginPartial", new ViewDataDictionary { Foo = "Bar" });
Which you can then access inside the partial via:
ViewData["Foo"]
You can also use child actions, which is generally preferable if working with a partial view that doesn't need the context of the main view. _LoginPartial seems like a good candidate, although I'm not sure how exactly you're using it. Ironically, though, the _LoginPartial view that comes with a default MVC project with individual auth uses child actions.
Basically, the code you have would already work, you would just need to change how you reference it by using Html.Action instead of Html.Partial:
#Html.Action("Index")
Notice that you're calling the action here and now the view.
You can always pass data directly to the partial view.
public PartialViewResult Index()
{
var data = // some data
return PartialView("~/Views/Shared/_LoginPartial.cshtml", data);
}
Pass multiple pieces of data
public class MyModel
{
public int Prop1 { get; set; }
public int Prop2 { get; set; }
}
public PartialViewResult Index()
{
var data = new MyModel(){ Prop1 = 5, Prop2 = 10 };
return PartialView("~/Views/Shared/_LoginPartial.cshtml", data);
}
I passed viewBag data to my partial view like below, and I converted that viewBag data object to JSON in my partial view by using #Html.Raw(Json.Encode(ViewBag.Part));
my code sample is given below.
public async Task<ActionResult> GetJobCreationPartialView(int id)
{
try
{
var client = new ApiClient<ServiceRepairInspectionViewModel>("ServiceRepairInspection/GetById");
var resultdata = await client.Find(id);
var client2 = new ApiClient<PartViewModel>("Part/GetActive");
var partData = await client2.FindAll();
var list = partData as List<PartViewModel> ?? partData.ToList();
ViewBag.Part = list.Select(x => new SelectListItem() {Text = x.PartName, Value = x.Id.ToString()});
return PartialView("_CreateJobCardView" ,resultdata);
}
catch (Exception)
{
throw;
}
}
Here i have passed both model and viewBag .
First off, the code in your question does not run. When you do #Html.Partial("_SomeView") the Index() method you have there does not run. All #Html.Partial("_SomeView") does is render _SomeView.cshtml in your current view using the current view's ViewContext.
In order to get this to work you need a bit of functionality that's common to all the controllers in your project. You have two options: extension method for ControllerBase or a BaseController that all the controllers in your project inherit from.
Extension method:
Helper:
public static class ControllerExtensions
{
public static string GetCommonStuff(this ControllerBase ctrl)
{
// do stuff you need here
}
}
View:
#ViewContext.Controller.GetCommonStuff()
BaseController
Controller:
public class BaseController : Controller
{
public string GetCommonStuff()
{
// do stuff you need here
}
}
Other controllers:
public class SomeController : BaseController
...
...
View:
#((ViewContext.Controller as BaseController).GetCommonStuff())
I am developing an application. I have created a view and a controller. The view has a button, on the click of which I am supposed to do database operations. I have put the database operations in the model, I am creating the object of model in the controller. On clicking the button the action is handled by a method in the controller, and the object of the model is created to get the records from the database. I would like to know if there is any way to display this data in the view.Is the approach correct or the view is supposed to interact with model directly to get the data.
Following is the code in controller that gets invoked on the button click
public ActionResult getRecord()
{
DataModel f_DM = new DataModel();
DataTable f_DT = f_DM.getRecord();
return View();
}
DataModel is the model class with simply a method "getRecord".
Any help will be highly appreciated.
I would like to add that i am using vs2010 and mvc4
Regards
you should write the logic of retrieving data in your controller. Store all your data in view model and pass it to the view.
for eg.
Model
namespace Mvc4App.Models
{
public class Product
{
public string Name { get; set; }
}
public class ProductViewModel
{
public Product Product { get; set; }
public string SalesPerson { get; set; }
}
}
Controller
public class ProductController : Controller
{
public ActionResult Info()
{
ProductViewModel ProductViewModel = new ProductViewModel
{
Product = new Product { Name = "Toy" },
SalesPerson = "Homer Simpson"
};
return View(ProductViewModel);
}
}
View
#model Mvc4App.Models.ProductViewModel
#{ ViewBag.Title = "Info"; }
<h2>Product: #Model.Product.Name</h2>
<p>Sold by: #Model.SalesPerson</p>
This is the best known practice to pass data from controller to the view.
you may use other techniques also like,
1. ViewData
2. ViewBag
3. TempData
4. View Model Object
5. Strongly-typed View Model Object
Yes, it's possible, but actually now very logical way to to this.
Lets follow your way. You have some View were you have a button, that will trigger this action.
For ex:
public ActionResult Index()
{
return View();
}
Inside view you can have a Ajax link, that will trigget your getRecord method:
<div id="GetDataDiv"></div>
<div>
#Ajax.ActionLink("Get Record", "getRecord", "ControllerName", null, new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "GetDataDiv" })
</div>
In the getRecord method you should have:
public ActionResult getRecord()
{
DataModel f_DM = new DataModel();
DataTable f_DT = f_DM.getRecord();
return PartialView(f_DT);
}
And in View it should be:
#model DataTable
#Model.PropertyOne #Model.PropertyTwo
It should works for you.
Actually same exaple here: http://www.dotnetpools.com/Article/ArticleDetiail/?articleId=151
In my controller I have the following code:
var viewModel = new ListCityViewModel {
City = rowData,
Meta =
{
DataSourceID = dataSourceID,
Em0 = em0
}
};
In my viewModel I have the following:
public class ListCityViewModel : BaseViewModel
{
public ListCitiesViewModel()
{
Meta = new Meta
{
Title = ViewContext.Controller.ValueProvider.GetValue("controller").RawValue +
ViewContext.Controller.ValueProvider.GetValue("action").RawValue,
Desc = ViewContext.Controller.ValueProvider.GetValue("controller").RawValue +
ViewContext.Controller.ValueProvider.GetValue("action").RawValue
};
}
public ICollection<City> Cities { get; set; }
}
and:
public class BaseViewModel
{
public BaseViewModel()
{
}
public Meta Meta { get; set; }
}
However it's not working as I get a message:
Error 6 An object reference is required for the non-static field,
method, or property 'System.Web.Mvc.ControllerContext.Controller.get'
Can anyone help me with this one. Do I need to pass something to the viewModel from the controller and how can I pass it. I have this viewModel common to many actions so I would like this to be automatic rather than me having to specify in the controller the controller name and action name.
In short : do not do that. It is not the right thing to do in MVC pattern. Your viewmodels should be as dumb as possible, and without any "contexts". If you need some "meta" data in your view models, depending for example on route data (action, controller), write a custom filter, which will put it there in OnActionExecuted - for example look by reflection if the current viewmodel has your "meta" properties (by this you make your own convention) and fill them from route data.
I'm passing data between my controller and my view using a ViewModel class. When there are validation errors, I return the ViewModel back to the view so the user can see the errors.
I'm having trouble figuring out the best way to deal with the data that is only passed from the controller to the view, which isn't passed back to the controller, such as the contents of dropdown lists.
Here's a simplified example from the project I'm working on:
I have a Widget object in my domain model that has an Employee property. I have a view that allows the user to edit this employee property by selecting their name from a drop down list.
public class WidgetFormViewModel {
// Used for a drop down list in the view
public SelectList EmployeeList { get; set; }
// This will contain the employee the user selected from the list
public int EmployeeID { get; set; }
public Widget Widget { get; set; }
}
And the controller:
// GET: /Widget/Edit/1
public ActionResult Edit(int id) {
var widget = _widgetService.GetWidgetByID(id);
var employees = _widgetService.GetAllEmployees();
var viewModel = new WidgetFormViewModel()
{
EmployeeList =
new SelectList(employees, "ID", "Name", widget.Employee),
Widget = widget,
WidgetID = widget.ID
};
return View("Edit", viewModel);
}
// POST: /Widget/Edit
public ActionResult Edit(WidgetFormViewModel viewModel) {
var existingWidget = _widgetService.GetWidgetByWidgetID(viewModel.WidgetID);
existingWidget.Employee = _widgetService.GetEmployeeByID(viewModel.EmployeeID);
// try { /* Save widget to DB */ } catch { /* Validation errors */ }
return ModelState.IsValid
// Update was successful
? (ActionResult) RedirectToAction("List")
// Model state is invalid, send the viewModel back to the view
: View("Edit", viewModel)
}
Now, here's the problem: When the ModelState is invalid and viewModel gets passed back to the view, its EmployeeList property is blank. What is the best way to deal with this?
Should I just repopulate it before returning to the view? This method seems difficult to maintain. (What if I add PageTitle and HeaderText to the view model as well? Suddenly there are more things to keep track of.) Is there another approach?
Inside of the catch block of the controller action handling the post, extract your error messages and add it to this.ModelState, then have it return this.Edit(viewModel.widgetID);.
You already have all the logic you need built up to display the view appropriately, you just want to use ModelState to make sure that errors make it back to the view.