My controller returns a string which is a url of an image of an external site.
How do I display that url on the view.
I appreciate your help.
AngryHacker is correct. I am just expanding AngryHacker's answer with some code example.
Add a property in your ViewModel for the image url and return it in the first get call. Then use it in the View. Thus you are avoiding an unnecessary http request to to the action again
public class UserProfileViewModel
{
public string DisplayName { set;get;}
public string GravatarURL { set;get;}
}
and in your ACtionMethod,
public ActionResult Get(int id)
{
UserProfileViewModel objVm=new UserProfileViewModel();
objVM.GravatarURL="http://www.externalsite.com/image/tiyra.jog";
//Set other properties also.
return View(objVm);
}
and in the View which is strongly typed to your UserProfileViewModel,
#model UserProfileViewModel
<h2>"#Model.DisplayName </h2>
<img src="#Model.GravatarURL" />
<p>The image is loaded from #Model.GravatarURL</p>
Make the URL part of your model and just reference it in the View.
Perhaps you're missing the part where you have to HTML-encode your output with the <%: %> tag, a la:
<%: Html.Label(ViewData["PicUrl"].ToString()) %>
...or, if it's a string property on your model...
<label><%: Model.PicUrl %></label>
Related
When I post my model to the controller with a property that contains a XML tag like <web.config>, it's a div in the controller, why? (in the browser's devtools the postdata is still correct)
The property in view:
[AllowHtml]
[Display(Name = "DataConfig")]
public string DataConfig { get; set; }
The controller:
[HttpPost]
public ActionResult Edit(MyModel data)
{
//Here data.DataConfig contains the <div> instead of <web.config>
return Redirect("myRedirct");
}
I want to post plain text with random tags like f.e, this is the TextAreaFor in the view:
Notice the formdata:
And the result, two divs..
I am not sure what the issue was but this seems a workaround for me:
model.DataConfig = this.HttpContext.Request.Unvalidated.Form["DataConfig"];
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>
Without customization, can I do something like this in MVC 3?
[HttpGet]
public ViewResult MyAction(ViewModel model)
{
// Do stuff
return View("ViewName", model);
}
The reason I am doing this is to pass data between different pages as part of a work flow. (I.e. when user fnishes what's needed in step 1, pass the form data to step 2...)
It will work as long as you have the same parameter Name as of the Property name of your Model class
Assuming your class is like this
public class ViewModel
{
public string Name { set;get;}
public string Loc{ set;get;}
}
You can do a Get request like this
MyAction?Name=jon&Loc=America
Shyju's answer only works if the members of class in the endpoint's method signature contains only scalar properties. But what if you have nested classes? Let's assume that your ViewModel class looks like this:
public class ViewModel
{
public string Name { get; set; }
public string Title { get; set; }
public Address MyAddress { get; set; }
}
And the Address class looks like this:
public class Address
{
public string Line1 { get; set; }
public string Line2 { get; set; }
}
Now let's say the GET request was done via AJAX and you did something like this in JavaScript:
var address = {
Line1: "123 Nowhere St.",
Line2: "Apt. B5"
}
var getRequestData = {
Name: "Joe",
Title: "Manager",
MyAddress: address
}
var uriString = $.param(getRequestData); //the parameters for the GET request
$.get("/ViewResult?" + uriString, function (data) { /*callback function*/ });
Even though the shape of your address object in JavaScript perfectly matches the C# Address class in the endpoint's method signature, the Line1 and Line2 sub-properties will NOT bind. Their values will come through as null.
There are two workarounds to this.
Workaround 1:
The first is to use dot notation when naming the parameters in the GET request instead of nested JavaScript objects. Using this method, the GET request data in AJAX would look like this:
var getRequestData = {
Name: "Joe",
Title: "Manager",
MyAddress.Line1: "123 Nowhere St.",
MyAddress.Line2: "Apt. B5"
}
MVC model binding will know how to do this, as long as all your property names all match up (they are case-sensitive, so be careful).
If you're not using AJAX, but just a plain HTML form submit, it's even easier. Just name the input elements with that same dot notation. Razor syntax makes this really easy with helper methods like TextBoxFor(), but here's an example in plain HTML:
<form method="get" action="/ViewResult">
<input type="text" name="Name" />
<input type="text" name="Title" />
<input type="text" name="MyAddress.Line1" />
<input type="text" name="MyAddress.Line2" />
<button type="submit">Submit GET request</button>
</form>
Workaround 2:
The other way around this is to simply use a POST request instead of a GET. Beware that it's technically bad practice to perform a POST request without the intent of actually changing some data on the server side, but it is an option.
You can do it; it will automatically bind any values in the query string to properties with matching names.
That said, it's not something that's generally done; it's the [HttpPost] method where you see the model binding performed, as the interfaces for the two actions need to be different somehow. You can solve that by posting back to a different action name, but you may still trigger model validation errors on the (partial) load of the model, which would be really confusing to a user.
For Web API 2:
[HttpGet]
public ActionResult Get([FromUri]ViewModel model)
{
// Do stuff
return View("ViewName", model);
}
You can post a form to a get by setting the PostMethod attribute to get. If the form's input fields match any of the accepting ViewModel then they will be filled. These matches are determined by the name field in an input (<input name="MatchedField"> -> public string MatchedField { get; set; }).
What you should do is pass the form from a post, and then redirect to the get from the post action. This pattern is best practice and is known as the Post-Redirect-Get pattern.
I would advise against this approach. Best solution to just use POST, because if you use GET, once you click back from step 3 to step 2 and the browser cache is not available, you will perform actions on an old version of the ViewModel. Is there a particular reason why you want to use GET?
I can not suggest to use QueryString to pass values.
You can use one of below:
This code will render a partial view with the given model.Be sure you add model to your view. And your view should be placed in Shared folder
public ActionResult myaction(ViewModel model)
{
return PartialView("anotherView", model);
}
Another way to do almost the same thing:
public ActionResult myaction(ViewModel model)
{
return View("someAnotherView", model);
}
if your view is not in the same controller , use the path for view name like "../Controller/viewName"
There is also a different approach which can be done by using TempData:
public ActionResult myaction(ViewModel model)
{
TempData["model"] = model;
return RedirectToAction("someAnotherView");
}
but you should reach your data in the view with the code as shown below:
#{
ViewModel model=(ViewModel)TempData["model"];
}
Hope one of above helps..
Regards
I was having a weird issue with a very simple model. When posted back to the controller, the model was always null. Not being able to find the issue, I pulled it apart rebuilt the model, adding an accessor at a time.
I finally discovered that having a string accessor called "State" and using it in a view was causing the issue:
<%= Html.HiddenFor(m => m.State) %>
Why would this happen?
Here is the model:
public class StudentSelectState
{
public string State { get; set; }
public int SelectedYear { get; set; }
public IDictionary<string, string> Years { get; set; }
}
Here is the controller:
[HttpGet]
public ActionResult SelectStudent()
{
var StudentYears = absenceServices.GetStudentYears();
var state = new StudentSelectState {Years = Lists.StudentYearListToDictionary(StudentYears)};
return View(state);
}
[HttpPost]
public ActionResult SelectStudent(StudentSelectState state)
{
var StudentYears = absenceServices.GetStudentYears();
state.Years = Lists.StudentYearListToDictionary(StudentYears);
return View(state);
}
and here is the view:
<% using (Html.BeginForm())
{%>
<%= Html.ValidationSummary() %>
<%= Html.TextBoxFor(m => m.State) %>
<%= Html.RadioButtonListFor(m => m.SelectedYear, Model.Years, "StudentYears") %>
<div style="clear: both;">
<input value="submit" />
</div>
<% } %>
The RadioButtonListFor is a HtmlHelper I wrote to populate RadioButtonLists.
I am using Ninject 2.0 to inject services into the contructor, but I don't think this has a bearing on this issue.
I could rename the accessor, but I'm curious as to why this is happening.
You could also rename the argument of your POST action.
[HttpPost]
public ActionResult SelectStudent(StudentSelectState model)
When you POST the form the following is sent in the request:
State=abcd
Now the default model binder sees that your action argument is called state and it tries to bind the abcd value to it which obviously fails because the state variable is not a string. So be careful when naming your view model properties.
To avoid those kind of conflicts I prefer to name my action arguments model or viewModel.
Yet another possibility if you don't want to rename anything is to use the [BindPrefix] attribute, like so:
[HttpPost]
public ActionResult SelectStudent([Bind(Prefix="")]StudentSelectState state)
When StudentSelectState is posted back to the controller the default mode binder (because you are not using a IModelBinder) can not know when to put in the StudentSelectState instance.
The view will not hold the state for the State property and it has to be specified in the form or obtained from a different method to be returned to the controller action.
You could use a hidden field for this or bind it using a custom IModelBinder class.
Hope this helps.
How do I retrieve the value of a textbox in asp.net mvc to store the value on to some variable?
I have a textbox like this <%=Html.TextBox("testbox") %> on the index view page.
I have a button like this <input type="submit" />
I'm using the default view page which comes when you open a new mvc app.
Thanks.
In your controller;
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Search(FormCollection collection)
{
String g = collection["textFieldname"]
}
or you could use;
TryUpdateModel(modelName);
The above is the prefered solution. If you need more info on TryUpdateModel then post a comment and I'll flesh it out for you.
EDIT:
Rather than explain it let me simply show you;
In your controller:
public class MyFormViewModel
{
public string myInput {get; set;}
}
public ActionResult Search()
{
MyFormViewModel fvm = new MyFormViewModel();
return View(fvm);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Search(FormCollection collection)
{
MyFormViewModel fvm = new MyFormViewModel();
TryUpdateModel<MyFormViewModel>(fvm);
string userInput = fvm.myInput;
}
Then in your view;
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<YOURNAMESPACE.Controllers.MyFormViewModel>" %>
<%= Html.TextBox("myInput", Model.myInput) %>
Notice two things.
The page is inheriting from your model/class defined in the controller. Not the best place for it but as an example it'll do.
The other thing is that the text box is name the same as the property in the model. In this case myInput.
When the controller does UpdateModel it'll reflection the thing out and match up the textbox name with the name of the field within your form view model.
Make sense?
EDIT 2
Also don't forget to wrap the button and your field in a;
<% using (Html.BeginForm()) {%>