I have a view that needs to load different component vieww dynamically based on component view name. I am using a function in C# to achieve this:
public ViewComponentResult GetComponentView(string componentName, int id)
{
return ViewComponent(componentName, new { id = id });
}
This is in a controller CT40. So the file structure is:
/Controllers/CT40/CT40Controller
/Views/CT40/Components/Maintenance/Default.cshtml
/Views/CT40/Components/Maintenance/MaintenanceViewComponents.cs
Inside MaintenanceViewComponents.cs I have:
[ViewComponent(Name = "Maintenance")]
It works find when I call the GetComponentView function with "Maintenance" as the component name.
But I want to move the GetComponentView function to the HomeController. When I do this, it returns
"System.InvalidOperationException: The view 'Components/Maintenance/Default'"
I have tried every path I can think of, same thing:
/CT04000/Maintenance
/CT04000/Components/Maintenance
/CT04000/Components/Maintenance/Default.cshtml
Views/CT04000/Components/Maintenance/Default.cshtml
Same error every time.
Any idea what path I need to put in to get Homecontroller to look in:
/Views/CT40/Components/Maintenance?
I was looking at the problem in the wrong place.
I was trying to put the path to the view in componentName here:
public ViewComponentResult GetComponentView(string componentName, int id)
{
return ViewComponent(**componentName**, new { id = id });
}
But the path needed to go in statement
return View(path, model);
in the file MaintenanceViewComponents.cs.
I added the path "~/Views/CT04000/Components/Maintenance/Default.cshtml" and worked liked charm.
Related
I am trying to get parameter form a View and passing it to the controller:
[HttpPost]
public string GetWord()
{
string word = Request["word"];
return word;
}
But I got an error
Indexing using the [] construct cannot be used for an Http Request expression
I looked at documentation and I don't know why it is not working. What should I do to fix this?
You can use more specific property to get the value, instead of Request["word"], depends where the "word" key is:
In query string -> Request.QueryString["word"];
In ServerVariables -> Request.ServerVariables["word"];
In Params -> Request.Params["word"];
In Form -> Request.Form["word"];
In Cookies -> Request.Cookies["word"];
In Headers -> Request.Headers["word"];
In your case, you could use the 4th one: Request.Form["word"], but please make sure the <input> control is included in the BeginFrom tag.
Try binding a parameter to the form
[HttpPost]
public string GetWord([FromForm]string word)
{
var postedWord = word;
return postedWord;
}
As your form gets more complex you might like to create a class and bind the submitted form to that
public string GetWord([FromForm]MyFormModel formData)
I'm using ASP.Net MVC 5, and I want to pass data from the controller to the view WITHOUT adding it to the URL.
I've tried it like this:
public ActionResult Index(LoginViewModel loginViewModel)
{
var landingPgVm = new LandingPgViewModel();
landingPgVm.ElectionName = loginViewModel.ElectionName;
landingPgVm.LandingPageTitle = loginViewModel.LandingPageTitle;
landingPgVm.LandingPageMessage = loginViewModel.LandingPageMessage;
return View("Landing", landingPgVm);
}
And this:
public ActionResult Index(LoginViewModel loginViewModel)
{
var landingPgVm = new LandingPgViewModel();
landingPgVm.ElectionName = loginViewModel.ElectionName;
landingPgVm.LandingPageTitle = loginViewModel.LandingPageTitle;
landingPgVm.LandingPageMessage = loginViewModel.LandingPageMessage;
ViewData["lpvm"] = landingPgVm;
return View("Landing");
}
And still, I get this:
http://localhost:nnnnn/Landing?VotingIsOpen=False&UserIp=%3A%3A1&BrowserAgent=Mozilla%2F5.0%20%28Windows%20NT%2010.0%3B%20Win64%3B%20x64%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F73.0.3683.103%20Safari%2F537.36&ElectionId=1&LoginId=********&LoginPin=*********&ElectionName=2019%20Member-at-Large%20Board%20Election&LandingPageTitle=Success%21&LandingPageMessage=Landing%20Page%20MESSAGE
So sorry that I let my frustration at, what turned out to be MYSELF, spill over onto these pages.
It's been some time since I've done a 'standard' MVC site and forgot how the logic is supposed to flow. (Sometimes it takes getting all the way to posting to SO before I finally figure out/realize the error(s) of my way(s)).
Thanks to info found on the MS docs site here (https://learn.microsoft.com/en-us/aspnet/mvc/overview/security/create-an-aspnet-mvc-5-web-app-with-email-confirmation-and-password-reset), namely, the POST method example under the "You must also update the HttpPost Login action method:" text, I've got it figured out.
I'm trying to create a ResetPassword Page and I need to create something like that!
myApi.azure.com/ResetPassword?hash=YYYYYYYYYYYYYY
I already know how to create a link to another controller, but that way it would trigger the Action just with the click, and what I need is pass the hash as parameter inside of that URL and them, call a controller!
var link = new Uri(Url.Link("ValidationEmailUser", new { Code = emailToken }));
Something like this:
public IHttpActionResult RedirectAction()
{
var urlFormat = string.Format("https://www3.olx.com.br/account/forgotten_password/?hash={0}", emailToken);
var location = new Uri(urlFormat);
return this.Redirect(location);
}
This question already has answers here:
MVC3: How to get currently executing view or partial view programatically inside a HtmlHelper extension?
(4 answers)
Closed 9 years ago.
Is there any way to get the file name (or view name) being rendered from an extension method. Something like :
public static string Something<T>(this System.Web.Mvc.HtmlHelper<T> helper, int value)
{
string viewName = ...; // ???
...
return someValueFromViewName;
}
** Edit **
The suggested question's answer :
var webPage = htmlhelper.ViewDataContainer as WebPageBase;
var virtualPath = webPage.VirtualPath;
does not work, and is not an answer to this question. I need the script being rendered at call time. If it is a partial, I need that partial name. Those two lines only returns the view being rendered from the controller, and not necessarily the view script being rendered at call time.
** Edit 2 **
These also ddo not work. They all return the same value; the controller's view script and not the view script (partial) calling the extension method.
var view = htmlhelper.ViewContext.View as BuildManagerCompiledView;
var virtualPath = webPage.ViewPath;
How about WebPageContext.Current.Page.VirtualPath?
public static string Something<T>(this System.Web.Mvc.HtmlHelper<T> helper, int value)
{
string viewName = Path.GetFileName(WebPageContext.Current.Page.VirtualPath);
string someValueFromViewName = viewName.DoSomething();
return someValueFromViewName;
}
Since views are compiled I think that you would have to inspect the current call stack to be able to determine which partial view that is being rendered.
Getting the name of the partial view code that is calling your code is pretty much like getting the name of the method that is calling you.
I have an ASP.NET MVC controller that generates images (they are stored in memory, I don't want to store them on the hard drive) and should return them to my view.
The problem is: I don't how know how to return multiple images from one controller method (I want to show the images in 1 view). I know that I can return a single image with the FileResult for example, but I can't find out (not on google/stackoverflow) how to return multiple images from the same method. Splitting the method up in multiple methods can't be done. Oh, all of the images are converted to a byte[], but that can be reversed if necessary.
This should work. Note I am reading my images from disk for my example but they can come from memory or anywhere. Then on the client side use java-script to display them.
[HttpGet]
public JsonResult Images()
{
var image1Base64 = Convert.ToBase64String(System.IO.File.ReadAllBytes(Server.MapPath("~/Images/1.jpg")));
var image2Base64 = Convert.ToBase64String(System.IO.File.ReadAllBytes(Server.MapPath("~/Images/2.jpg")));
var jsonResult = Json(new { image1 = image1Base64, image2 = image2Base64 }, JsonRequestBehavior.AllowGet);
jsonResult.MaxJsonLength = int.MaxValue;
return jsonResult;
}
If you have access to the MIME type of the image, you could always render them as Base64-encoded images, instead of making another request to a different controller method. This is a view model I use:
public class ImageViewModel
{
public string FileName { get; set; }
public string MIME { get; set; }
public byte[] Data { get; set; }
public override string ToString()
{
return string.Format(#"data:{0};base64,{1}", MIME.ToLower(), Convert.ToBase64String(Data));
}
}
You can use the Filename property in the alt attribute of the <img /> tag, so the markup & model-binding in your view would look something like this (assuming Razor syntax):
<img src="#model.ToString()" alt="#model.FileName" />
You do lose image-caching, AFAIK - that hasn't been an issue for me, but is understandably a deal-breaker for some.
I think that you can solve it in another way, instead of returning multiple images, you can create a utility method that loads the image in the controller
public FileContentResult GetImage(int imageId)
{
var image = GetImageById(imageId); // get from a list for example
return File(image, "image/jpeg"); // your image Mime type
}
and in the View you can do the following, iterate over the images
#foreach (var image in Model)
{
<img alt="" src="#Url.Action("GetImage", "ControllerName", new {imageId =image.Id})"/>
}
You wish to show multiple images based on input of the user, but don't want to save to the hard disk (chat). Therefor I recommand you using a session variable to save the users input in. And the use a simple FileResult to return multiple images based on that session variable.
http://blog.theobjectguy.com/2009/12/session-with-style.html
If your requirement is to show multiple images in one view it would be easier to use 2 action methods. One that returns a image with FileResult and another where you just use standard html img tags pointing the first action method