I'm developing a method to display the photo of logged user in a layout page.
It looks like the method is fine, and returns for me the image path, but I don't know to make it works on <img src="">, or I can do it with some razor function?
If I call my method from url like http://localhost:29469/User/LoadPhoto, it returns the correct path.
The layout is not typed, so I can not display it like Model.Attribute
public ActionResult LoadPhoto()
{
if (User.Identity.IsAuthenticated)
{
var userStore = new UserStore<User>(new ERPIdentityDbContext());
var userManager = new UserManager<User>(userStore);
var xUser = userManager.FindById(User.Identity.GetUserId());
string xPhotoPath = HttpContext.Server.MapPath(#"~/Images/Users/") + xUser.FotoPath ;
return Content(xPhotoPath);
}
return View();
}
I want to use return for LoadPhoto method in <img src="">
If your photos are JPGs, return a File ActionResult with the image/jpeg content type:
string xPhotoPath = HttpContext.Server.MapPath(#"~/Images/Users/") + xUser.FotoPath ;
return File(xPhotoPath,"image/jpeg");
Related
In Razor Pages, how can I redirect to a URL that contains slugs?
For example, the code below takes me to the URL that contains rootValue:
return RedirectToPage("/EmailConfirmation", new {email = command.Email});
The output is like this:
https://localhost:5001/EmailConfirmation/example#gmail.com
But how can I use Razor Pages commands to go to the following URL that contains slugs?
https://localhost:5001/EmailConfirmation?email=example#gmail.com
If you want to go to the following url:
https://localhost:5001/EmailConfirmation?email=example#gmail.com
You can try to use PageModel.Redirect(String) Method:
string queryString = "?email=" + command.Email;
return Redirect("/EmailConfirmation"+queryString);
You could use RedirecToAction,
return RedirectToAction("EmailConfirmation", new { email = command.Email });
Given that you have an action named EmailConfirmation like,
public IActionResult EmailConfirmation([FromQuery] string email)
{
//your code
return View();
}
I want to redirect to welcome page and it should show/hide html elements according to user type. I have written return View("Welcome", adminvar); but it returns the Welcome page inside login URL.
Upon refresh it shows popup warning of form resubmission. I want to redirect to Welcome page. I tried this
return RedirectToAction("Welcome" , adminvar);
but it's not working.
[HttpPost]
public ActionResult Login(tbl_Admin adminObj)
{
studentDBEntities db = new studentDBEntities();
var adminvar = db.tbl_Admin.Where(x => x.Email == adminObj.Email && x.Password == adminObj.Password).Select(s=> new tbl_AdminVM {
AdminId = s.AdminId,
Email = s.Email,
Name = s.Name,
Password = s.Password,
Type = s.Type
}).FirstOrDefault();
if (adminvar != null)
{
/* return RedirectToAction("Welcome" , adminvar);*/
return View("Welcome", adminvar);
}
else
{
return View();
}
}
public ActionResult Welcome()
{
ViewBag.Message = "Welcome Admin - Admin Account Page";
return View();
}
View:
#if (Model.Type)
{
<center><p>#Html.ActionLink("Admin Management", "ListAdmin")</p></center>
}
Here you are returning Welcome View to the login method that will render welcome view content on login page and will not be redirected to welcome page.
What you can do is, after successful login, redirect to Welcome Action.
return RedirectToAction("Welcome", new { userType = adminvar.Type });
And modify Welcome action as below
public ActionResult Welcome(string userType)
Inside Welcome action get the value of usertype and send it to Welcome view using Viewbag.
ViewBag.userType = userType;
Use the value of ViewBag.userType on Welcome Page to show/hide html elements.
You Can redirect to action
return RedirectToAction(“ActionName”,”ControllerName”);
or
return RedirectToAction(“~/ControllerName/ActionName”);
I have an iframe which uses a Url.Action to open a PDF from an action controller. Is it possible to open this PDF on a certain page? Determined by a value in the model e.g. #Model.FilePage
iframe:
<iframe width="700" height="1600" src="#Url.Action("OpenPDF", new { id = 8 })"></iframe>
controller action:
public ActionResult OpenPDF(int? id)
{
CompletedCamp completedCamp = db.CompletedCamps.Find(id);
string filepath = Server.MapPath(Path.Combine("~/Surveys/" + completedCamp.SurveyName));
return File(filepath, "application/pdf");
}
To open on specific page, add #page=[page number] to the end of src
<iframe width="700" height="1600" src="#Url.Action("OpenPDF", new { id = 8 })#page=4"></iframe>
if page number should be from the model, do
public ActionResult Index()
{
MyViewModel m = new MyViewModel() { FilePage = 4 };
return View(m);
}
...
#model MVC.MyViewModel
<iframe width="700" height="1600" src="#Url.Action("OpenPDF", new { id = 8 })#page=#Model.FilePage"></iframe>
Have gone through the first 3 pages of Google and still can't get to the bottom of this. I have a controller which I am using to upload images:
[HttpPost]
[Authorize(Roles = "Admin,Tradesman,Customer")]
public ActionResult UploadFile(HttpPostedFileBase file)
{
// to do: ensure only valid file types are sent
try
{
if (file.ContentLength > 0)
{
using (var ctx = new ApplicationDbContext())
{
if (ModelState.IsValid)
{
// Need to check we have a current UserId and JobId before we go any furthur
var profileData = Session["UserProfile"] as UserProfileSessionData;
if (profileData.JobIdGuid.ToString().Length != 36)
{
// to do: something went horribly wrong! Redirect back to main view
}
if (profileData.UserIdGuid.ToString().Length != 36)
{
// to do: something went horribly wrong! Redirect back to main view
}
var photo = new Photos();
photo.Guid = Guid.NewGuid();
photo.Url = Server.MapPath("~/Images/2017");
photo.Extension = Path.GetExtension(file.FileName);
photo.JobGuid = profileData.JobIdGuid;
photo.UserIdGuid = profileData.UserIdGuid;
photo.Timestamp = DateTime.Now;
ctx.Photo.Add(photo);
ctx.SaveChanges();
string _path = Path.Combine(photo.Url, photo.Guid.ToString() + photo.Extension);
file.SaveAs(_path);
}
}
}
ViewBag.Message = "File Uploaded Successfully.";
return View();
}
catch
{
ViewBag.Message = "File upload failed.";
return View();
}
}
Each image is saved to a given location, the location saved to the db, happy days. Want I want though is for my images to be displayed on the same page after each upload. The model is as you'd expect just Id, Guid, Url, Extension, UserId, Timestamp.
Here is the view that uploads the images:
#{
ViewBag.Title = "UploadFile";
}
<h2>Upload File</h2>
#using (Html.BeginForm("UploadFile", "Job", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>
#Html.TextBox("file", "", new { type = "file" })
<br />
<input type="submit" value="Next" />
#ViewBag.Message
</div>
// to do display the images uploaded
}
Is it possible to just have some kind of for...each and have each displayed at the bottom? Anyone know how to do this! Btw this is my first C# MVC app so if this is daft question I apologise. Thanks in advance :)
You should be following the P-R-G pattern. After successfully saving the data in your HttpPost action method, you should do a redirect to your GET action method, where you will read the data you need and pass it to the view where you will display it.
I would create a view model to represent each image and use that
public class ProfileImageVm
{
public string FileName { set;get;}
public DateTime CreatedTime { set;get;}
}
Now, for your save partin your http post action method, i would advise you to not save the physical location of the file in the table. The Server.MapPath returns the physical path. Storing that is unnecessary. What if you decide to move the location to some other directory in the server tomorrow? You could simply store the unique fileName. Let's assume that you want to store all the files in the Images/2017 in app root ,you can use Server.MapPath to get the physical location so that you can store the file in disk, but do not use that to store your table record.
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
photo.Url = fileName ;
photo.Extension = Path.GetExtension(file.FileName);
With this code, it is simply storing the file name(without extension) as it is, not a unique name. That means, if you are uploading a second file with same name, it will overwrite the first one in disk. If you want to generate a unique file name, use the GetUniqueName method from this post.
Now in the GET action method, you read the Photos collection and create a list of our view model from that.
public ActionResult UploadFile()
{
var list= ctx.Photos
.Select(x=>new ProfileImageVm { FileName=x.Url + x.Extension ,
CreatedTime = x.Timestamp })
.ToList();
return View(list);
}
Now in your UploadFile view will be strongly typed to a list of ProfileImageVm, you can loop through the model data and render the images.
#model List<ProfileImageVm>
#using (Html.BeginForm("UploadFile", "Job", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.TextBox("file", "", new { type = "file" })
<input type="submit" value="Next" />
}
<h3>Images</h3>
#foreach(var item in Model)
{
<img src="~/Images/2017/#item.FileName" />
<p>Uploaded at #item.CreatedTime </p>
}
Now, after successfully saving the photo and the record in table, you will return a redirect response to the GET action.
file.SaveAs(_path);
return RedirectToAction("Upload","Job");
You can also keep the base path ~/Images/2017 in a config settings/constant and use that across your app so if you ever decide to change it to ~/Images/profilepics, there is only one place you have to change.
Goal:
I want to be able to type URL: www.mysite.com/NewYork OR www.mysite.com/name-of-business
Depending on the string I want to route to different actions without changing the URL.
So far I have:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"UrlRouter", // Route name
"{query}", // URL with parameters
new { controller = "Routing", action = "TestRouting" } // Parameter defaults
);
}
In the controller I have:
public ActionResult TestRouting(string query)
{
if (query == "NewYork")
return RedirectToAction("Index", "Availability"); // <--------- not sure
else if (query == "name-of-business")
return Redirect("nameofbusines.aspx?id=2731"); // <--------- not sure
else
return RedirectToAction("TestTabs", "Test"); // <--------- not sure
}
I have pretty much tried everything to redirect/transfer to the page without
changing the URL, but everything I've tried changes the URL or gives me an error.
Basically I'm looking for the equivalent of server.transfer where I can keep the URL but send info to the action and have it display its result.
I'm with Nick on this one, though I think you could just use regular views instead of having to do partials. You may need to implement them as shared views if they are not in the views corresponding to the controller (since it will only look in the associated and shared views).
public ActionResult TestRouting(string query)
{
if (query == "NewYork")
{
var model = ...somehow get "New York" model
return View("Index", model );
}
else if (query == "name-of-business")
{
var model = ...get "nameofbusiness" model
return View("Details", model );
}
else
{
return View("TestTabs");
}
}
Each view would then take a particular instance of the model and render it's contents using the model. The URL will not change.
Anytime that you use a RedirectResult, you will actually be sending an HTTP redirect to the browser and that will force a URL change.
Im not sure if you tried this way or if this way has any drawbacks..
Add a global.asax file to your project. In that add the following method:
void Application_BeginRequest(object sender, EventArgs e)
{
// Handles all incoming requests
string strURLrequested = Context.Request.Url.ToString();
GetURLToRedirect objUrlToRedirect = new GetURLToRedirect(strURLrequested);
Context.RewritePath(objUrlToRedirect.RedirectURL);
}
GetURLToRedirect can be a class that has the logic to find the actual URL based on the URL typed in. The [RedirectURL] property will be set with the url to redirect to beneath the sheets.
Hope that helps...
You can change your controller like this:
public ActionResult TestRouting(string query)
{
string controller,action;
if (query == "NewYork")
{
controller = "Availability";
action = "Index";
}
else
{
controller = "Test";
action = "TestTabs";
}
ViewBag.controller = controller;
ViewBag.action = action;
return View();
}
Then you can use these ViewBags in your view like this:
#{
Layout = null;
Html.RenderAction(ViewBag.action, ViewBag.controller);
}
That's it. And you can improve this example with use a class and some functions.
Are you saying you want to go to "www.mysite.com/NewYork" and then "really" go "somewhere else" but leave the url alone? Perhaps what you would want to do then is use partial views to implement this? That way, your base page would be what gets routed to, and then inside of that page you do your condition testing to bring up different partial views? I've done that in my application for viewing either a read-only version of a grid or an editable grid. It worked very nicely.
I'm not sure what you can do about the redirect to the .aspx page, but you should be able to replace the RedirectToAction(...)s with something like this:
public ActionResult TestRouting(string query)
{
if (query == "NewYork")
{
var controller = new AvailabilityController();
return controller.Index();
}
else if (query == "name-of-business")
return Redirect("nameofbusines.aspx?id=2731"); <--------- not sure
else
{
var controller = new TestController();
return controller.TestTabs();
}
}