Q) How do I access my website content, e.g. books collection in my WebAPI class?
In an Umbraco 8 website project, I am using the following in my razor view to get content, which works fine, allowing me to then iterate over the collection and build my page, all great.
#inherits Umbraco.Web.Mvc.UmbracoViewPage
#using ContentModels = Umbraco.Web.PublishedModels;
#using System.Text.RegularExpressions;
#{
var books = Model.Root().DescendantsOfType("Book")
.Cast<Book>().Where(x => x.ShowInWebsite);
}
//...
However, this doesn't compile in my WebAPI class - I don't know how to fix the references needed.
Error I'm getting:
The name 'Model' does not exist in the current context
Other things I've tried:
var books = Umbraco.ContentAtRoot().DescendantsOrSelf().OfTypes("Book");
// Which gives error:
IEnumerable<IPublishedContent>' does not contain a definition for 'DescendantsOrSelf' and the best extension method overload 'PublishedContentExtensions.DescendantsOrSelf(IPublishedContent, string)' requires a receiver of type 'IPublishedContent
You WebApi class doesn't have a model, but as long as it inherits from UmbracoApiController you should be able to do
Umbraco.ContentAtRoot()...
instead?
https://our.umbraco.com/documentation/reference/routing/webapi/
According to https://our.umbraco.com/documentation/Reference/Querying/IPublishedContent/Collections/#oftypes you should then be able to do
Umbraco.ContentAtRoot().DescendantsOrSelf().OfTypes("Book")
Thanks to the comment by #Jannik Anker
I managed to get my collection by so:
var parent = Umbraco.ContentAtRoot().First().Children().FirstOrDefault(x => x.Name == "Booklist");
if (parent != null)
{
var books = parent.Children();
var test = "";
foreach (var book in books)
{
test += book.Id + ": " + book.Name + "\r\n";
}
return test;
}
I'm trying to get the ID of a child item's image property so I can use Umbraco.Media() to display the image.
I'm trying to use best practice by using strongly-typed models and I think I've called the strongly-typed models correctly here.
Why is the following code returning the 'Object reference not set to an instance of an object' error at the 'var imageId = location.LocationImage.Id;' line?
Thank you.
#inherits Umbraco.Web.Mvc.UmbracoViewPage<ContentModels.Locations>
#using ContentModels = Umbraco.Web.PublishedModels;
#{
Layout = "master.cshtml";
var locations = Model.Children<Location>();
}
#foreach (var location in locations)
{
<p>#location.LocationName</p> //this returns a string as expected
var imageId = location.LocationImage.Id; //this throws the error
var image = Umbraco.Media(imageId);
<img src="#image"/>
}
For info, I've enabled AppData ModelsMode and rebuilt the models. The implementation in my Location.generated.cs is:
/// Location Image
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Umbraco.ModelsBuilder", "8.0.4")]
[ImplementPropertyType("locationImage")]
public Image LocationImage => this.Value("locationImage");
This was solved on the Umbraco forums so I'll post the answer here.
With Umbraco strongly-typed models you can pass the value inline to the html tag, e.g.:
<img src="#location.LocationImage.Url"/>
Instead of having to pass it to a service.
below content has pulled from database
<div class="main"><div class="col1">content</div>
in above example main div has not closed in my database so I want to close it.
I have simply add in my razor view page
#Html.Raw(a.shortDesc)
but my page has disturbed. so please suggest me.
I would suggest using the HtmlAgilityPack (https://html-agility-pack.net/) to fix the HTML before you render it out using #Html.Raw in your view.
In the ShortDesc property of your ViewModel, you could do something like this:
private string _shortDesc;
public string ShortDesc
{
get
{
var doc = new HtmlDocument();
doc.LoadHtml(_shortDesc);
return doc.DocumentNode.OuterHtml;
}
set
{
this._shortDesc = value;
}
}
#{
var data = #a.shortDesc+"</div>";
}
#Html.Raw(#data)
I have an existing ASP.NET MVC application that displays thumbnail images from physical storage connected to the web server. This can also be storage located elsewhere via the file url per the database record.
The image thumbnails are referenced by URL strings (i.e. https://domain/path/file.jpg) in image tags in a for each loop in the view. Also using lazy loading of the image for performance using jquery.lazy.min.js.
Due to the sensitive nature of the images I am required to secure the url of the file to prevent unauthorized access to the images by viewing the page source. The image thumbnail URL’s are provided in a List via the view model passed to the view from the controller.
From what I have been reading the best possible means of securing the URL of the image is to generate a blob:https, or blob:file so that the reference is secured for the current page.
I have been working on trying to accomplish this using (URL || webkit).createObjectURL(file_url) but the problem is that the thumbnail image url is a string and I need to get it into an Object File type.
I see that using and createObjectURL works to secure the image source that is loaded with a result such as this: http://localhost:10480/91733a7a-65fe-4176-979e-82c2fc7148c3" title="Original size: 1635x2623">
My question, in the for each loop to load and display the image tags in the view, is how can I supply the img tag data-src with the file blob instead of the url string? Not sure how to mix the HTML and Javascript to do this.
Any help or direction is greatly appreciated. Thank you.
I think this can help you.I created a function in View(you can do it in back end)
and call it by Image path.Then this function convert your image to Base64String and your address will be secure and any one don't know where is you actual path.
#using System.Drawing
#{
ViewBag.Title = "Home Page";
#helper GetBinayImage(string path)
{
using (Image image = Image.FromFile(path))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
string imageSrc = string.Format("data:image/gif;base64,{0}", base64String);
<img src="#imageSrc" width="100" height="100" />
}
}
}
}
<div>
#GetBinayImage(#"path/file.jpg")
</div>
When you look at page source you see some thing like this:
And if your path is url you can use some thing like this:
#using System.Drawing
#{
ViewBag.Title = "Home Page";
#helper GetBinayImage(string path)
{
var webClient = new WebClient();
byte[] imageBytes = webClient.DownloadData("http://www.google.com/images/logos/ps_logo2.png");
string base64String = Convert.ToBase64String(imageBytes);
string imageSrc = string.Format("data:image/gif;base64,{0}", base64String);
<img src="#imageSrc" width="100" height="100" />
}
}
<div>
#GetBinayImage(#"https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png")
</div>
How can I quickly determine what the root URL is for my ASP.NET MVC application? I.e., if IIS is set to serve my application at http://example.com/foo/bar, then I'd like to be able to get that URL in a reliable way that doesn't involve getting the current URL from the request and chopping it up in some fragile way that breaks if I re-route my action.
The reason that I need the base URL is that this web application calls another one that needs the root to the caller web application for callback purposes.
Assuming you have a Request object available, you can use:
string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));
If it's not available, you can get to it via the context:
var request = HttpContext.Current.Request
So none of the ones listed here worked for me, but using a few of the answers, I got something working:
public string GetBaseUrl()
{
var request = HttpContext.Current.Request;
var appUrl = HttpRuntime.AppDomainAppVirtualPath;
if (appUrl != "/")
appUrl = "/" + appUrl;
var baseUrl = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, appUrl);
return baseUrl;
}
Update for ASP.NET Core / MVC 6:
ASP.NET Core makes this process a bit more painful, especially if you are deep in your code. You have 2 options to get at the HttpContext
1) Pass it in from your controller:
var model = new MyClass(HttpContext);
then in model:
private HttpContext currentContext;
public MyClass(HttpContext currentContext)
{
this.currentContext = currentContext;
}
2) Perhaps the cleaner way is to inject it into your class, which starts with registering the types in your Startup:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.AddTransient<MyClass, MyClass>();
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
then have it injected for you like this:
private HttpContext currentContext;
public MyClass(IHttpContextAccessor httpContextAccessor)
{
currentContext = httpContextAccessor.HttpContext;
}
in either case, here is the updated for .NET Core GetBaseUrl():
public string GetBaseUrl()
{
var request = currentContext.Request;
var host = request.Host.ToUriComponent();
var pathBase = request.PathBase.ToUriComponent();
return $"{request.Scheme}://{host}{pathBase}";
}
In Code:
Url.Content("~/");
MVC3 Razor Syntax:
#Url.Content("~/")
Maybe it is extension or modification of the answers posted here but I use simply the following line and it works:
Request.Url.GetLeftPart(UriPartial.Authority) + Url.Content("~")
When my path is: http://host/iis_foldername/controller/action
then I receive : http://host/iis_foldername/
The following snippet works nicely for me in MVC4, and doesn't need an HttpContext available:
System.Web.HttpRuntime.AppDomainAppVirtualPath
The trick with relying upon IIS is that IIS bindings can be different from your public URLs (WCF I'm looking at you), especially with multi-homed production machines. I tend to vector toward using configuration to explicitly define the "base" url for external purposes as that tends to be a bit more successful than extracting it from the Request object.
For an absolute base URL use this. Works with both HTTP and HTTPS.
new Uri(Request.Url, Url.Content("~"))
This is a conversion of an asp.net property to MVC . It's a pretty much all singing all dancing get root url method.
Declare a helper class:
namespace MyTestProject.Helpers
{
using System.Web;
public static class PathHelper
{
public static string FullyQualifiedApplicationPath(HttpRequestBase httpRequestBase)
{
string appPath = string.Empty;
if (httpRequestBase != null)
{
//Formatting the fully qualified website url/name
appPath = string.Format("{0}://{1}{2}{3}",
httpRequestBase.Url.Scheme,
httpRequestBase.Url.Host,
httpRequestBase.Url.Port == 80 ? string.Empty : ":" + httpRequestBase.Url.Port,
httpRequestBase.ApplicationPath);
}
if (!appPath.EndsWith("/"))
{
appPath += "/";
}
return appPath;
}
}
}
Usage:
To use from a controller:
PathHelper.FullyQualifiedApplicationPath(ControllerContext.RequestContext.HttpContext.Request)
To use in a view:
#using MyTestProject.Helpers
PathHelper.FullyQualifiedApplicationPath(Request)
In MVC _Layout.cshtml:
<base href="#Request.GetBaseUrl()" />
Thats what we use!
public static class ExtensionMethods
{
public static string GetBaseUrl(this HttpRequestBase request)
{
if (request.Url == (Uri) null)
return string.Empty;
else
return request.Url.Scheme + "://" + request.Url.Authority + VirtualPathUtility.ToAbsolute("~/");
}
}
This works fine for me (also with a load balancer):
#{
var urlHelper = new UrlHelper(Html.ViewContext.RequestContext);
var baseurl = urlHelper.Content(“~”);
}
<script>
var base_url = "#baseurl";
</script>
Especially if you are using non-standard port numbers, using Request.Url.Authority appears like a good lead at first, but fails in a LB environment.
You could have a static method that looks at HttpContext.Current and decides which URL to use (development or live server) depending on the host ID. HttpContext might even offer some easier way to do it, but this is the first option I found and it works fine.
You can use the following script in view:
<script type="text/javascript">
var BASE_URL = '<%= ResolveUrl("~/") %>';
</script>
For ASP.NET MVC 4 it is a bit different:
string url = HttpContext.Request.Url.AbsoluteUri;
This is working in ASP .NET MVC 4
In any controller action you can write:
1stline gets the whole url+Query String.
2nd line remove local path & query ,last '/' symbol.
3rd line add '/' symbol at last position.
Uri url = System.Web.HttpContext.Current.Request.Url;
string UrlLink = url.OriginalString.Replace(url.PathAndQuery,"");
UrlLink = String.Concat(UrlLink,"/" );
in simple html and ASP.NET or ASP.NET MVC if you are using tag:
About us
For url with aplication alias like http://example.com/appAlias/... You can try this:
var req = HttpContext.Current.Request;
string baseUrl = string.Format("{0}://{1}/{2}", req.Url.Scheme, req.Url.Authority, req.ApplicationPath);
On the webpage itself:
<input type="hidden" id="basePath" value="#string.Format("{0}://{1}{2}",
HttpContext.Current.Request.Url.Scheme,
HttpContext.Current.Request.Url.Authority,
Url.Content("~"))" />
In the javascript:
function getReportFormGeneratorPath() {
var formPath = $('#reportForm').attr('action');
var newPath = $("#basePath").val() + formPath;
return newPath;
}
This works for my MVC project, hope it helps
This was my solution (using .net core 3.1, in an api controller):
string baseUrl = $"{Request.Scheme}://{Request.Headers.Where(h => h.Key == "Host").First().Value}";
For MVC 4:
String.Format("{0}://{1}{2}", Url.Request.RequestUri.Scheme, Url.Request.RequestUri.Authority, ControllerContext.Configuration.VirtualPathRoot);
I put this in the head of my _Layout.cshtml
<base href="~/" />
Maybe it is a better solution.
#{
var baseUrl = #Request.Host("/");
}
using
Base URL
#{
var baseurl = Request.Url.Scheme + "://" + Request.Url.Host + ":" + Request.Url.Port + Url.Content("~");
}
#baseurl
--output
http://localhost:49626/TEST/
In .net core 3.1 I used this approach:
$"{Request.Scheme}://{Request.Host}{Url.Content("~/")}"
The following worked solidly for me
var request = HttpContext.Request;
var appUrl = System.Web.HttpRuntime.AppDomainAppVirtualPath;
if (appUrl != "/")
appUrl = "/" + appUrl + "/";
var newUrl = string.Format("{0}://{1}{2}{3}/{4}", request.Url.Scheme, request.UrlReferrer.Host, appUrl, "Controller", "Action");
Also you can use this. For the razor pages, it is better to use it than the others.
https://ml-software.ch/posts/getting-the-base-url-for-an-asp-net-core-mvc-web-application-in-your-static-javascript-files
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<base href='#Url.AbsoluteContent("~/")'>
<title>#ViewBag.Title - ASP.NET Core Web Application</title>
<!-- ... -->
</head>
<body>
add this function in static class in project like utility class:
utility.cs content:
public static class Utility
{
public static string GetBaseUrl()
{
var request = HttpContext.Current.Request;
var urlHelper = new UrlHelper(request.RequestContext);
var baseUrl = $"{request.Url.Scheme}://{request.Url.Authority}{urlHelper.Content("~")}";
return baseUrl;
}
}
use this code any where and enjoy it:
var baseUrl = Utility.GetBaseUrl();
Simply in one line get BaseUrl
string baseUrl = new Uri(Request.Url, Url.Content("~")).AbsoluteUri;
//output example: https://stackoverflow.com