I have a ASP.NET MVC 4 application that uses database to store pages (HTML), galleries, forms etc... I want to provide users a functionality to call other controller from inside pages.
Simplified problem is how to call render action from database acquired string. Just for example I would like that string contains #Html.RenderAction("Show", "Gallery", new {id=5})
Another option I have to parse string inside a controller and render all sub calls to string before rendering this HTML.
EDIT:
The database would return something like code bellow, service layer can substitute {$gallery$} with #Html.RenderAction("Show", "Gallery", {id=5})
<div class="text">
<h1> title </h1>
<p> this is some random text {$gallery$} </p>
</div>
From your statement
Simplified problem is how to call render action from database acquired
string.
I get that you want to call an action using dynamically provided action-name and controller. If this what you want you could get it using
ViewModel
public class MyViewModel{
public string Action {get;set;}
public string ControllerName {get;set;}
}
Controller
public class MyController : Controller{
public ActionResult MyView(){
return View(new MyViewModel
{ Action ="MyPartialView" , ControllerName = "my"});
}
public ActionResult MyPartialView(){
return PartialView();
}
}
View
#model MyView
....render stuff for the view
#{
Html.RenderAction(Model.Action,Model.ControllerName);
}
Related
I have an application where I need to display a username and image for the current user. I could pull the data into a viewmodel and display in the view, however this would mean that i would need to do this in every controller that uses the view. Is there a way where I can global set values and call in some partial views without having to repeatedly duplicate it in each controller?
Sounds to me like you need to call a child action from your _Layout.cshtml. Here's how it could look.
First from what you have said I am assuming your viewModel will be this
public class UserDisplayViewModel
{
public string UserName { get; set; }
public string ImageUrl { get; set; }
}
You will need a controller that is responsible for getting the username and image data.
It would look like this
public class UserController : Controller
{
[ChildActionOnly]
public ActionResult _userDisplay()
{
var viewModel = GetUserNameAndImage();
return View(viewModel);
}
private UserDisplayViewModel GetUserNameAndImage()
{
//code for getting the username and image data
}
}
You would call the child action from your _layout.cshtml file like this
#Html.Action("_userDisplay", "User")
It goes wherever you want the username and image to appear in your HTML.
You will also need a partial view called _userDisplay.cshtml which will contain the markup for how you want to display your username and image. Here's a very basic example
#model UserDisplayViewModel
#{
Layout = null;
}
<p>
Username: #Model.UserName
</p>
<p>
<img src="#Model.ImageUrl"/>
</p>
I'm developing a new application in ASP.Net MVC (beginner) from old application which is in ASP.Net and have one query that How should I convert below line of code into new in MVC?
HTML:
<div runat="server" id="dvLogList"></div>
.cs:
dvLogList.InnerHtml = sb.ToString()
I need to set the StringBuilder appended string html code to as dvLogList innerhtml
You can strongly-typed your view.
As an example I have a model:
class DisplayModel
{
public string str { get; set; }
}
In my controller I will pass this model to my view:
public ActionResult Display()
{
DisplayModel model = new DisplayModel
{
str = sb.ToString()
}
return View(model);
}
The next step is to make my view strongly typed. To make this possible add this line to the top
#model DisplayModel // Most of the cases you need to include the namespace to locate the class
<div id="dvLogList">#Model.str</div> // now your model is accessible in view
In the end, why are we doing this?
This one has the advantage compared to using viewbag because there are cases that we need to postback data to our controller. The values from your view were automatically binded to your model (given that you declare the model in your action).
// model is automatically populated
public ActionResult Save(DisplayModel model)
{
}
For further knowledge, read this link I cannot spare more time to improve this answer Strongly Typed Views
In your controller, make use of ViewData (or ViewBag)
ViewData["dvLogList"] = "whatever content you want";
In your view you can call the ViewData wherever you need it:
<div id = "dvLogList" >
#(new HtmlString(ViewData["dvLogList"].ToString()))
</div>
Hope this helps.
You can do this by following way:
in your controller action that invokes this view:
public ActionResult Index()
{
ViewBag.HTMLContent = "your HTML Content";
return View();
}
In Index.cshtml view:
<div id="dvLogList">
#Html.Raw("#ViewBag.HTMLContent") /*assuming your content is HTML content not just string*/
</div>
Use below code :
//Controller Action
public ActionResult Index()
{
ViewBag.HTMLContent = "Your HTML Data";
return View();
}
//View page code
<div id="dvLogList">
#Html.Raw((String)ViewBag.HTMLContent)
</div>
I'm working on a school project and I need some help.
I've created a form and I want to get the submitted values from it.
Is it possible to do this without using JavaScript?
And in that case, how do I do it?
Form:
<div id="secondRowInputBox">
<% using (Html.BeginForm("Index","Home",FormMethod.Post))
{%>
<%= Html.TextBox("Id")%> <br />
<%= Html.TextBox("CustomerCode") %><br />
<%= Html.TextBox("Amount") %><br />
<input type="submit" value="Submit customer data" />
<%} %>
</div>
Just create an HttpPost action in your controller accepting the form values as parameters:
[HttpPost]
public ActionResult Index(int id, string customerCode, int amount)
{
// You can change the type of the parameters according to the input in the form.
// Process data.
}
You might want to look into model binding. This allows you to create strongly-typed views and saves you the trouble of creating actions with dozens of parameters.
You have already done half the work, now in home controller make an actionresult
[HttpPost]
public ActionResult Index(int id, string customerCode, int amount)
{
// work here.
}
form post method will call this method, as you have specified it in the begin form parameters.
It will be better if you use a model for passing values and use it in view for form elements
[HttpPost]
public ActionResult Index(ModelName modelinstance)
{
// work here.
}
Sample loginModel
public class LoginModel
{
[Required]
[Display(Name = "Username:")]
public String UserName { get; set; }
[Required]
[Display(Name = "Password:")]
[DataType(DataType.Password)]
public String Password { get; set; }
}
now if was using this login model in the form
then for the controller action, modelinstance is simply the object of model class
[HttpPost]
public ActionResult Index(LoginModel loginDetails)
{
// work here.
}
if you have a lot of variables in the form then having a model helps as you don't need to write for all the properties.
Henk Mollema's answer is good. Here to say something more on it.
Html.TextBox will generate html like below one, there's a name attribute.
<input id="CustomerCode" name="CustomerCode" type="text">
When you submit the form, all the values of input fields can be get from Request.Form by name attribute as key Request.Form["CustomerCode"], and ASP.NET MVC has done some magic for us, so it can simply go into the param of the action method.
So right now if I want to change what partial view I display on a page based of off configuration I do the follow:
Config Item:
<add key="InstanceOwner" value="companyName" />
Call to render partial view:
<div id="" class="sidebarBox side-box3">
Html.RenderAction("ProductFeature", "Dashboard");
</div>
Controller ActionResult:
[OutputCache(Duration = 1)]
[ValidateInput(false)]
public ActionResult ProductFeature(string viewName = InstnaceOwner+"ProductFeature")
{
return PartialView(viewName);
}
I will name the partial views using a naming convention that is companyName-ProductFeature, the companies name will be variable. Doing it this way feels wrong and inefficient. I'm still really new to .NET MVC though and just want to know what the best approach to this is,Thanks!
the plan is to just change the value of the configuration key if I'm
having to change which instance (which customer) the app is being used
for
Based on that comment then it could just be as simple as reading the config value and use that to determine which view to show. You don't need to accept any parameters for the controller method.
public ActionResult ProductFeature()
{
var prefix = ConfigurationManager.AppSettings["InstanceOwner"];
return PartialView(prefix+"ProductFeature");
}
What version of MVC are you using?
If i was you, i will get all the data soon as i enter the page controller (e.g. HomeController)
public ActionResult Index()
{
var model = new SomeViewModel();
model.ProductFeature = InstnaceOwner + "ProductFeature"
return View(model);
}
Then in the View, (index.cshtml)
#Html.Partial("_ProductFeature", Model.ProductFeature)
and in the partial View (_ProductFeature.cshtml)
#model string
<span>Product Feature is #model</span>
Hope this answers your question
Is it possible from a Controller to show a view, and then dependant on what that user selects in dropDownList - render another different view back in the original calling controller? Kind of a "daisy-chaining" effect.
The thinking behind this - is a user selecting a vehicle type - (associated with an ID number) in a view, back in the Controller dependant on what was chosen will render another view immediately displaying HTML according to the vehicle type they chose e.g. an HTML page for car or a boat or aeroplane etc...
If this is possbile can someone point me to a code examaple?
Actual Database Model below - but it is for documents, not vehicles!
check the method paremetares of your action method and return different views baed on that . Something like this.
public ActionResult GetInfo(string id,string vehicleTypId)
{
if(String.IsNullOrEmpty(vehicleTypeId))
{
var vehicle=GetVehicleType(vehicleTypId);
return View("ShowSpecificVehicle",vehicle) ;
}
var genericVehicle=GetVehicle(id);
return View(genericVehicle);
}
EDIT : Saying so, I seriously think you should keep those in 2 seperate Action methods. That makes your code clean and better readable. You may move the common functionality to a function and call if from bothe the action methods id needed. So i would do it in this way
Assuming you have a ViewModel for the first page( displays all vehicletypes)
public class VehicleTypesViewModel
{
//other relevant properties
public IEnumerable Types { set;get;}
public int SelectedTypeId { set;get;}
}
Your GET request for the initial view will be handled by this action result.It gets all the Vehicle types and return that to your view in the ViewModels Types property.
public ActionResult VehicleTypes()
{
VehicleTypesViewModel objVM=new VehicleTypesViewModel();
objVM.Types=dbContext.VehicleTypes.ToList();
return View(objVM);
}
and in your View called VehicleTypes.cshtml,
#model VehicleTypesViewModel
#using(Html.BeginForm())
{
#Html.DropDownListFor(Model.SelectedTypeId,new SelectList(Model.Types,"Text",Value"),"Select")
<input type="submit" value="Go" />
}
Another Action method to handle the form post. You have the selected type id here and you can get the specific details here and return a different view
[HttpPost]
public ActionResult VehicleTypes(VehicleTypesViewModel model)
{
// you have the selected Id in model.SelectedTypeId property
var specificVehicle=dbContext.Vehicles.Where(x=>x.TypeId=model.SelectedTypeId);
return View("SpecificDetails",specificVehicle);
}
Alternatively you can do a Get request for the specific vehicle using RedirecToAction method. I would prefer this approach as it sticks with the PRG pattern.
[HttpPost]
public ActionResult VehicleTypes(VehicleTypesViewModel model)
{
int typeId=model.SelectedTypeId;
return RedirectToAction("GetVehicle",new {#id=typeId});
}
public ActionResult GetVehicle(int id)
{
var specificVehicle=dbContext.Vehicles.Where(x=>x.TypeIdid);
return View(specificVehicle);
}
With Javascript : You can do a get call to the new view from your javascript also. without the HTTPpost to controller. You should add some javascript in your initial view for that
#model VehicleTypesViewModel
//Include jQuery library reference here
#Html.DropDownListFor(Model.SelectedTypeId,new SelectList(Model.Types,"Text",Value"),"Select")
<script type="text/javascript">
$(function(){
$("#SelectedTypeId").change(){
window.location.href="#Url.Action("GetVehicle","Yourcontroller")"+"/"+$(this).attr("id");
});
});
</script>
I think to get a better user experience create a partial view, and load that partial view in a div in the same page via an ajax call.
public ActionResult GetVehicalInfo(string id, string vehicleType)
{
var vehicle = GetVehicleType(id, vehicleTypId);
return PartialView("vehicle);
}