I have a series of dynamic links on my view that render like this:
Course Image <strong>(600x384)</strong>
I have a method that looks like this:
public class CantoDownloadPreset
{
public static FileResult DownloadPreset(string preset)
{
...
}
}
how can I call the helper DownloadPreset method and send data-itemid parameter.
CantoDownloadPreset should be a controller in a named file CantoDownloadPresetController.cs inside Controllers Folder.
Then if you need to do a GET, inherit Controller and remove static:
public class CantoDownloadPresetController : Controller
public FileResult DownloadPreset(string preset)
{
...
}
But take consideration if you want to return a FileResult and where. This question implies a lot of research about how MVC Web Controller works and you should be more in focus. But anyway, the link should be then (only for GET of course):
/method/action/value
then:
/CantoDownloadPreset/DownloadPreset/?preset=value
Related
I am trying to display images from the local storage(not Content folder). The image tag I am using looks like this.
#if (Model.PreviousCoverPic != null)
{
<img src="#Url.Action("ServeImage", "Profile",new {path = Model.PreviousCoverPic})" alt="Previous Profile Pic" />
}
I made the ServerImage method an extension method since it will be used by more than one controller. Here is the code for the method:
public static ActionResult ServeImage(this System.Web.Mvc.Controller controller, string path)
{
Stream stream = new FileStream(path, FileMode.Open);
FileResult fileResult = new FileStreamResult(stream, "image/jpg");
return fileResult;
}
It returns a FileResult of the image so that it can be displayed. However, when the view is rendered it doesn't show the image. I checked the Model.PreviousCoverPic value and it is not null. What am I missing here? How can I achieve displaying methods from a local folder? Also, I followed the answer in this question and added the name space of the class which contains the extension method but the image still doesn't get rendered in the view.
According to the following sources
Can MVC action method be static or extension method
And this answer
extend ASP.NET MVC action method,How to do return View
The extension method wont work with routing the Url.Action. You can use inheritance to make a base class with the action. that way all inherited classes will have the action and calls to Url.Action will be valid.
public abstract class MyBaseController : Controller {
public ActionResult ServeImage(string path) {...}
}
public class ConcreteController : MyBaseController {...}
My application has a view that is linked from various different other views located in different controllers. I would like to have a 'Back' button in this view that will send the user back to the previous view, which ever that may be.
To this end I have added a string attribute to the viewmodel which I would like to use to reference the originating view /MyController/MyAction in the #Html.ActionLink parameters.
Some of the views linking to this view belongs to current controller, some belong to other controllers. This means I have to pass the controller as well as the action to the ActionLink.
As it stands, my code looks something like this:
ViewModel:
public class MyViewModel
{
public int MyData { get; set; }
[HiddenInput]
public string ReturnUrl { get; set; }
}
View:
#Html.ActionLink("Back", Model.ReturnUrl)
This produces the undesirable result of localhost:####/CurrentController/MyController/MyAction
Of course I could always save two strings on the ViewModel (one for the controller and one for the action) and pass them to the ActionLink seperately, but if possible I would like to avoid that. Is there an overload of ActionLink that allows me to use a single return url string, without making implications about the controller?
Also, is it possible to achieve the same thing on the controller side, f.ex. like this:
[HttpPost]
public ActionResult DoStuff(MyViewModel model)
{
// do stuff
return RedirectToAction(model.ReturnUrl);
}
You shouldn't use ActionLink. Just use an anchor tag, like this:
<a href='#Url.Content(Model.ReturnUrl)'>Back</a>
And, in your Action, you can do it like below:
[HttpPost]
public ActionResult DoStuff(MyViewModel model)
{
// do stuff
return Redirect(model.ReturnUrl);
}
Also, another solution would be to have two properties (ReturnController and ReturnAction) in your model.
I'm writing my app using Asp.Net MVC 3. In my controller I have two action methods with the very same code apart from one line. Here it is:
[HttpPost]
public ActionResult EditPost(Post post)
{
if (ModelState.IsValid)
{
_postsRepository.UpdatePost(post);
return RedirectToAction("NewsFeed");
}
return View("EditPost", post);
}
[HttpPost]
public ActionResult AddPost(Post post)
{
if (ModelState.IsValid)
{
_postsRepository.UpdatePost(post);
return RedirectToAction("NewsFeed");
}
return View("AddPost", post); // the return view is different
}
So, I want to withdraw all this code into helper method.
What I've already tried:
1) I tried to put all the code into helper method and pass as parameters ModelState.IsValid and View name. And then in AddPost and EditPost I call this helper method instead of code listed above. Here is the new code:
[HttpPost] // also tried without this attribute
public ActionResult HelperPost(Post post, string viewName, bool modelState)
{
if (modelState)
{
_postsRepository.UpdatePost(post);
return RedirectToAction("NewsFeed");
}
return View(viewName, post);
}
[HttpPost] // also tried without this attribute
public void AddPost(Post post)
{
HelperPost(post, "AddPost", ModelState.IsValid);
}
The EditPost code is almost the same. The view name is "EditPost".
When I run the app and AddPost method executes the validation works and the new post is created but this line never executes:
return RedirectToAction("NewsFeed");
So I'm redirected to "AddPost" view again and again.
2) Also tried to redirect to HelperPost method instead of calling it withing AddPost and EditPost. The result is still the same: seems like RedirectToAction("NewsFeed") doesn't execute. (Here I neglected the validation just to simplify the example, cause I would have to create new model with properties: Post post, string viewName, bool modelState). The code:
[HttpPost] // tried without attribute
public void AddPost(Post post)
{
return RedirectToAction("HelperPost", post);
}
[HttpPost] // tried without attribute
public RedirectToRouteResult HelperUpdatePost(Post post)
{
_postsRepository.UpdatePost(post);
return RedirectToAction("NewsFeed");
}
So, How could I refactor my code so my action methods (EditPost and AddPost) would not contain the same chunk of code?
p.s. I need different views for AddPost and EditPost methods cause the "back to content" links in them are different. So, I can't just redirect to the EditPost view from AddPost method.
Thanks for help in advance!
Just put your "back to content" link in the model, then use the same view for both, then you can use the same HttpPost method. Saves having to duplicate everything.
I would solve it like this:
I would withdraw the method implementation into separate private
method. This method will be invoked by each of the public action
methods. Since the View name differs for both methods I would pass
the view name as parameter to the private method.
The private method doesn't need the HttpPostAttribute!
Don't forget to declare Add and Edit action methods as returning
ActionResult! As parameter they will expect only Post, the view name has to be hard-coded into the action methodsiteslf ;-)
I hope this helps.
This is the method I wanna call:
[AcceptVerbs(HttpVerbs.Post)]
public string MyPostMethod(int i)
{ ... }
I want to call it from another method in the same controller:
[AcceptVerbs(HttpVerbs.Get)]
public string MyOtherMethod(int i)
{ MyPostMethod(i); }
Is there a way to do this?
You should treat the controller methods as class methods .(A controller is just a class)
So would you do it for a class? If it is YES, you can do it for a controller too
Anyway, I would encapsulate the code in a private method and call it within the controller's
methods.
i have done as Vdex suggested here:
https://stackoverflow.com/a/5801502/973485
And used the RenderPartialToString method he found. And it works perfectly like this:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Test()
{
string t = ViewToString.RenderPartialToString("Index", null, ControllerContext);
return Content(t);
}
}
But if i want to render the Home > Index from another Controller, i get:
Value cannot be null.
Parameter name: controllerContext
Like this:
public class FooController : Controller
{
public ActionResult Index()
{
string t = ViewToString.RenderPartialToString("Index", null, new HomeController().ControllerContext);
return Content(t);
}
}
Is there any way to pass a View from another Controller to a string? I have tried many different methods, and it all of them fails at the ControllerContext. Many thanks!
Update: Why i need to do this:
Imagine i have a website full of widgets, the amount of widgets on each page is dynamic, so i cannot hardcode them in my cshtml file. But in that file there are different areas defined where the widgets gets printet out. To print out these widget i have a list of IWidgetController wich contains alle the different Widgets available, and the interface sais that they need to containe a ActionResult for edit, new and view. example of widgets: CalenderController, NewsController, GalleryController and so on... So in those areas i need to print out the content of each of those Controllers. Now i could also load the URLHTML but i figured doing it from the inside would be faster... right?
Try this:
string t = ViewToString.RenderPartialToString("Index", null, this.ControllerContext);
Anyway, why do you need to convert to a string?