I am calling a Controller Action from a view, within that controller I need to invoke another Action which I will invoke to save the view to a network location as either HTML or Image.
How do I retrieve the URL to an Action from within a Controller. Please note I need the actual URL, this means RedirectionToAction or View() wont work.
Why? I need to pass in a URL which will contain a call to a View. This view will be used to generate an image or HTML document using the System.Windows.Forms.WebBrowser.
.NET 3.5; C#; MVC 1;
I could do something like this, but its dirty ... well it leaves me with that dirty feeling.
using(Html.BeginForm("Action", "MyWorkflowController",
new {
MyId = "bla",
URLToGenerateImage = Url.Action("GenerateImage", "MyWorkflowController")
}))
I ended up using the MvcContrib.UI.BlockRenderer to convert to View to Html instead of generating the image. I proceeded to save the html string to a file system location.
Here is a link for further information
http://www.brightmix.com/blog/how-to-renderpartial-to-string-in-asp-net-mvc/
How about ContentResult - Represents a text result, so you could have
/Controller/GetUrl/id
Public ActionResult GetUrl(int id)
{
// builds url to view (Controller/Image/id || Controller/Html/id)
var url = BuildImageUrl(id);
return ContentResult(url);
}
in view you could have:
GenerateImage
Related
I have a view which is a .cshtml file with a button that executes the function submitForm() when clicked.
function submitForm() {
fetch(`#{REPLACE_URL}#`);
}
In my controller I have an endpoint that modifies the .cshtml and then returns the View, but it shows the default .cshtml, not the modified one.
What I'm trying to to is to modify the #{REPLACE_URL}# value with a proper url. I need to do it in runtime since this url is different between the environments.
public IActionResult ShowViewEndpoint(...)
{
...Modify the "#{REPLACE_URL}#" tag in the View...
return View(builder.HtmlBody);
}
How could I show the modified View? Is there a better way to do it instead the one I'm trying?
Assuming your JS function is in the .cshtml file, you can set the value using Razor:
function submitForm() {
fetch(`#(Model.MyUrl)`);
}
That way you can pass the URL from the server to the frontend
Can I run these get and post actions with just single button? I get an id from my view then I just wanna run my post action.
I've already tried to getting id with parameter and put it in session but couldn't do it with one submit button
[HttpGet]
public ActionResult JoinEvent(int id)
{
Session["EventID"] = id;
return View();
}
[HttpPost]
public ActionResult JoinEvent(EventPerson eventPerson)
{
Person per =(Person) Session["Login"];
eventPerson.PersonID = per.PersonID;
eventPerson.EventID = (int)Session["EventID"];
eventPerson.TotalPerson = eventPerson.TotalPerson + 1;
eventManager.Join(eventPerson);
return View();
}
and this is my view
<td class="buy_link">
#Html.ActionLink("Join","JoinEvent","Join",item.EventID,null)
</td>
As what you posted here, it looks like the EventId can be set freely (without any security restrictions) by the client by simply navigating to GET /JoinEvent?id=100.
If security isn't an issue, you can do it by many many ways
Passing the event id to the client, which in turn will give it back to the server.
How ? Here is one way
Passing it as part of EventPerson model, which you will need to add a new property inside of that model.
ActionResult should: return View(new EventPerson { EventId: id })
Decorating view top row (after import statments) with the following #model EventPerson, this will tell the view that now he represents this type. (Which was passed by the GET action)
Now we should decide if we want to pass it back to the server as query string parameter or a body parameter ? Because we're doing a semantic "Insert" action, in most cases the practice asks us to pass it as part of the body. thus, you should use an hidden text box to pass EventId parameter.
#Html.Hidden("EventId", #model.EventId))
"EventId" is the property we want to bind on our POST server action EventPerson newly property. (Point#1)
#model.EventId is the value we took from the server and passed it into the View (Point#2)
Technically you cannot. When you create an anchor tag using action link, it creates a link to the specified URL. When you click on that link that fires a GET request. That will not POST data to the action method. If you need to POST data, you need to either submit a form or you can use Javascript/jQuery to do that. You can collect the data and send it as a POST using Js/jQuery. But just the anchor won't send a POST method.
Refer this
Users receive an email with link that they must click on in order to certify their email address. Once the link is clicked, the user should be redirected to one of two static HTML pages, one saying "You're certified" the other stating "The link is expired"
I have attempted a few options. The first I added a Response.Redirect to my controller with a path to the View. I also tried where I added a routes.MapPageRoute to my RouteConfig file and changed my redirect call to attempt to use this name, but that doesn't work either. I looked at this example for that fix ( Redirect to an html page inside Views Folder )
Here is my code attempting to access the HTML file with the redirect:
EmailCertification.UpdateDBEmailCertified(userName, int.Parse(memberNumber), certSentDT);
return Redirect("~/Views/EmailCertification/EmailCertified.html");`
The error I get is that:
Path to /Views/EmailEmailCertification/EmailCertified.html is not found. I verified the spelling and the path is all is correct.
If I changed my code to include MapPageRoute in RoutesConfig it still doesn't work.
Here is my route config:
routes.MapPageRoute("HtmlPage", "EmailCertifiedURL", "~/Views/EmailCertification/EmailCertied.html");`
Here is my controller:
return Redirect("EmailCertifiedURL");
Here is my controller in action, it is a HttpPost
public ActionResult EmailCertify(string userName, string memberNumber, string certSentDate)
{
DateTime certSentDT;
long lngCertSent = long.Parse(certSentDate);
certSentDT = new DateTime(lngCertSent);
if (certSentDT < DateTime.Now.AddDays(-14))
return Redirect("EmailOldURL");
EmailCertification.UpdateDBEmailCertified(userName, int.Parse(memberNumber), certSentDT);
return Redirect("~/Views/EmailCertification/EmailCertified.html");
}
The error I get on this is that
the controller doesn't have a action EmailCertifiedURL. This code I took from the above mentioned StackFlow article.
All I want is the email link to fire off the controller action EmailCertify and redirect me to a static HTML page.
https://localhost:44344/EmailCertification/EmailCertify?userName=IS&memberNumber=3000050&certSentDate=636959314302036120
That seems strange. A work around could be adding a new action that returns your entire html with no layout. I mean, try with this
public ActionResult CertifiedEmail(){
return View();
}
Then you should create a view for your action with the same name ( CertifiedEmail.cshtml ), and inside your View paste all your html. At the beginning you should add this code to remove the Layout
#{
Layout = null;
}
I tend to use RedirectToAction() methods instead of just Redirect()
The 2nd parameter will need to be the name of the controller if it is a different controller.
return RedirectToAction("EmailCertifiedURL", "EmailCertification");
public ActionResult Questionnaire()
{
return Redirect("~/MedicalHistory.html");
}
I am using web api in my mvc application. I have a problem while calling web api using jquey.get function. Consider the following scenario:
I have 2 controller name:
HomeMVCController
TestAPIController (using mvc style routing i.e. api/{controller}/{action}/{id})
HomeMVC controller contains 2 actions
Index
About
TestAPI controller contains 1 action
Get
When i was on Index view of HomeMVC controller i.e.
http://localhost:1025/Home
and when i call $.get("api/TestAPI/Get") from the browser it returns the expected json response.
But when i was on About view of HomeMVC controller i.e.
http://localhost:1025/Home/About
and when i call $.get("api/TestAPI/Get") from the browser it returns error, resource not found, and the resource it is trying to locate is:
http://localhost:1025/Home/About/api/TestAPI/Get
instead of
http://localhost:1025/api/TestAPI/Get
Why browser added Home/About in the url to api and why it is not added Home/Index when i was on Index view. On Index view why api call is working as expected and why not working on About view ??
You used a relative url when you should be using an absolute url.
You should instead use an absolute url by doing:
$.get("#Url.RouteUrl("#Url.RouteUrl("DefaultApi", new {httproute="", controller="TestAPI", action="Get"}))
If you want to keep your javascript in separate js files (and not in the razor files) what you can do is have an initialize method that is called from a razor view.
The .js file:
var myPageJsUrls = {};
var MyPageInitialize = function(getItemsUrl, saveItemUrl, editItemUrl){
myPageJsUrls.getItemsUrl = getItemsUrl;
myPageJsUrls.saveItemUrl = saveItemUrl;
myPageJsUrls.editItemUrl = editItemUrl;
}
var getItems = function(){
return $.get(myPageUrls.getItemsUrl);
}
...
In the razor file:
<script>
myPageInitialize('#Url.Action("AllItems", "Items")', '#Url.RouteUrl("DefaultApi", new {httproute="", controller="TestAPI"}, ...)
</script>
K... I'm doing something obviously wrong. I have a simple page with a file input control on and a submit button. I'm trying out the new "File" ActionResult that was released with the Mvc RC...
All, I want to happen is when the submit button is clicked the selected file is uploaded to the database. This all works fine...
Then, after the page refreshes I want a image to display the resulting image that was uploaded. The issue, is that the image is not rendering... I get the broken image...
This is the portion that is getting the file and sending it back to the view...
var a = Helper.Service.GetAttachmentById(id, MembershipProvider.SecurityTicket);
if (a == null)
{
return View(new ImagePlaceHolderViewData(new { Id = id }));
}
return View(new ImagePlaceHolderViewData(new { Id = a.Id, Image = a, FileContent = File(a.Data, a.ContentType) }));
Then in the view I have a image tag like so...
<img src="<%=Model.FileContent.FileContents %>" />
I have also tried...
<img src="<%=Model.FileContent%>" />
Thoughts..??
FileResult returns the ASCII or binary contents of the file. When you say do the following:
<img src="<%=Model.FileContent.FileContents %>" />
You are attempting to push the binary image data into the src attribute. That will never work, because the src must a URL or a path to an image.
There are several ways of doing what you want, and the most correct solution in this case, would be to create a new controller that returns the binary data like you are attempting, and then you set the src attribute to be the path to correct action on your new controller. E.g:
<img src="/image/result/12345" />
This points to the following (really simple and incomplete) example controller:
public class ImageController : Controller
{
public ActionResult Result(int resultID)
{
// Do stuff here...
return File(..);
}
}
Note that the name I chose for the action is most likely not any good, but it serves its purpose as an example. Hope this was helpful.
I think it's pretty simple: the src attribute of your img tag requires an URL. What you're doing here is just putting the FileStream object in there (which implicitly calls the ToString method on that object). Your resulting html is probably something like this:
<img src="FileStream#1" />
Did you check your html source?
What you probably should do is provide a method which returns the data, and pass the route to that to your view. Your resulting html 'should' then look something like this:
<img src="/Images/View/1" />
So, steps you have to do are:
Create a method on your controller that returns a FileContentResult
Pass your image ID to your view
Use Url.RouteUrl to generate an url which you can put in your img tag, which points to the method returning your image data.
There's also another solution:
<img src="data:image/gif;base64,<%=Convert.ToBase64(Model.FileContent)%>"/>
which works in some browsers, and doesn't in some browsers(IE! of course). But the stable solution is what Thomas J mentioned.