How to concatenate the img src in asp.mvc aspx view page? - c#

in asp.net mvc aspx page i am writing the html input image like this.
<img src="/public/images/"+<%: roleid %>+".jpg" alt="please load the image.." />
in above code roleid -1 is coming from db.but src not forming correctly.
expected result src : /public/images/1.jpg but src not forming correctly.please tell me how to concatenate the string in aspx view engine?
thnaks

Assuming roleid is defined somewhere above in the View, you should form the attribute value in this manner:
src='<%: string.Format("/public/images/{0}.jpg", roleid) %>'
Things to note:
The quotation pattern: single quotes for the whole value, double quotes for strings in C# code.
Value string is generated within the <%: %> tag

There are couple of things i would like talk about.
1) Generating Image URL at runtime in View is not a good practice. You should Use ViewModel for that purpose like this
public class MyViewModel
{
public MyModel m;
public void MyViewModel(MyModel m){this.m=m;}
public string ActualIMageUrl
{
get
{
return "public/Images/"+m.RoleId+".jpg";
}
}
}
Now make your view strongly typed view of this ViewModel class instead of Model.
2)Dont directly use IMG tag in your View, Rather create new method for HtmlHelperClass using extenion method as follows,
public static class MVCExtensions
{
public static MvcHtmlString Image(this HtmlHelper helper, string src, string altText, string height)
{
var builder = new TagBuilder("img");
builder.MergeAttribute("src", src);
builder.MergeAttribute("alt", altText);
builder.MergeAttribute("height", height);
return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing));
}
}
Now in the View
#model MyViewModel
.
.
.
#Html.Image(Model.ActualImageUrl);
Hope it helped

Related

how to change image in razor page in asp.net core 2

I have some logic in C#, that controls which image I should show on a webpage.
basically I want to update the image, when a button is pushed, but I want to do it in the controller of a razor page. And not I javascript or html, where it is fairly simple.
I am thinking somehow along the lines of:
// the controller
public class APageController {
...
public IActionResult AButtonPushed() {
bool yes;
...
// some logic that changes yes
...
aPageModel.ImagePath = yes // how do I access the
? "\images\true.jpg" // razor view class from
: "\images\ohNooo.jpg" // controller
return RedirectToPage("/aPage");
}
...
}
// the razor page model
public class aPageModel : PageModel {
...
public string ImagePath {get;set;}
...
}
// and the razor page html
...
< img src="#Model.ImagePath"/>
...
or it maybe I should use some helper tag, to force the page to react to the change of imagePath in the PageModel.

return custom html from ViewComponent

In an ASP.NET Core app I want to return custom html from a ViewComponent. I can return custom text, but the html will be encoded instead of being embedded:
public class BannerViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(string param1, int param2)
{
return Content("<strong>some custom html</strong>");
}
}
I use it in my .cshtml page:
#await Component.InvokeAsync("BannerView")
On the page this will Show as <strong>some custom html</strong> instead of some custom html.
How do I directly return HTML instead of text from the ViewComponent?
If you don't want to return a view you can return HTML this way without a view:
return new HtmlContentViewComponentResult(new HtmlString("Not bold - <b>bold</b>"));
Your ViewComponent could have its own view as well and you can render the html there. The solution would be the following:
public class BannerViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(string param1, int param2)
{
string model = "<strong>some custom html</strong>";
return View("Index", model);
}
}
Add the following to your Views folder: Views\Shared\Components\BannerViewComponent\Index.cshtml and put the following in the ViewComponent's view:
#model string
#Html.Raw(Model)
You can change the model to be a class instead of just a string so that you can structure the ViewComponent's output, but the key part is the Html.Raw() method to output unencoded html.
Although I would recommend using a view in most cases (and putting all the HTML in the view rather than using it just to output the HTML created by the view component), for very simple components you may want to consider this:
The Invoke() method on the view component does not need to return IViewComponentResult, it can return HtmlString.
For example:
public HtmlString Invoke()
{
return new HtmlString(#"<b>Hello World</b>");
}

MVC3 Model binding in HTTP GET request?

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

How to display external image in MVC 3

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>

How does the Html Helper, RenderPartial, work? How can I implement a helper that can bring in content from a partial view?

When you use Html.RenderPartial is takes the name of the view you want to render, and renders it's content in that place.
I would like to implement something similar. I would like it to take the name of the view you want to render, along with some other variables, and render the content within a container..
For example:
public static class WindowHelper
{
public static string Window(this HtmlHelper helper, string name, string viewName)
{
var sb = new StringBuilder();
sb.Append("<div id='" + name + "_Window' class='window'>");
//Add the contents of the partial view to the string builder.
sb.Append("</div>");
return sb.ToString();
}
}
Anyone know how to do this?
The RenderPartial extensions are programmed to render directly to the Response object... you can see this in the source code for them:
....).Render(viewContext, this.ViewContext.HttpContext.Response.Output);
This means that if you change your approach a little bit, you can probably accomplish what you want. Rather than appending everything to a StringBuilder, you could do something like this:
using System.Web.Mvc.Html;
public static class WindowHelper
{
public static void Window(this HtmlHelper helper, string name, string viewName)
{
var response = helper.ViewContext.HttpContext.Response;
response.Write("<div id='" + name + "_Window' class='window'>");
//Add the contents of the partial view to the string builder.
helper.RenderPartial(viewName);
response.Write("</div>");
}
}
Note that including System.Web.Mvc.Html allows you access to the RenderPartial() methods.
We are fixing this in MVC 2. You will be able to call Html.Partial() and get the actual contents of the view as a string.
Why not create a second view and have the partial inside that, pass Name as ViewData or in model etc..
Something like:
<div id='<%= ViewData["Name"] + "_Window"%>' class='window'>
<% Html.RenderPartial(ViewData["Name"]); %>
</div>
Hope that helps,
Dan

Categories

Resources