Get media url including server part - c#

Is it possible to get url with MediaManager.GetMediaUrl that always includes the server part?

Just to bump this up, in Sitecore 7 the AlwaysIncludeServerUrl option is also included in MediaUrlOptions (I don't know since which version of Sitecore)
Like this:
MediaUrlOptions muo = new MediaUrlOptions();
muo.AlwaysIncludeServerUrl = true;
String url = MediaManager.GetMediaUrl((MediaItem)item, muo);

I've discovered that the following will work for producing fully qualified urls for media items:
public static string GetMediaUrlWithServer(MediaItem mediaItem, Item item = null)
{
item = item ?? Sitecore.Context.Item;
var options = new UrlOptions {AlwaysIncludeServerUrl = true, AddAspxExtension = false};
var itemUrl = LinkManager.GetItemUrl(item, options);
var mediaOptions = new MediaUrlOptions {AbsolutePath = true};
var mediaUrl = MediaManager.GetMediaUrl(mediaItem, mediaOptions);
return itemUrl + mediaUrl;
}
The urls produced will be relative to item so you may want to supply a reference to your Home item instead of Sitecore.Context.Item

I just answered a similar question on Stack Overflow recently. I believe the answer applies to yours as well.
Short summary: there is no configuration to do this, you need to override some of the built-in methods to do this. See the above link for the exact details.

Yes, you can do that!
The correct way of setting this parameter is specifying within config file at linkManager section, where you have this anŠ² the rest of settings regarding how you URLs will be resolved. Here's the whole section, you're interested in alwaysIncludeServerUrl parameter:
<linkManager defaultProvider="sitecore">
<providers>
<clear />
<add name="sitecore" type="Sitecore.Links.LinkProvider, Sitecore.Kernel"
alwaysIncludeServerUrl="true"
addAspxExtension="true"
encodeNames="true"
languageEmbedding="asNeeded"
languageLocation="filePath"
shortenUrls="true"
useDisplayName="false" />
</providers>
</linkManager>

Related

Determine if a given url (from a string) is from my domain or not

I'm trying to check from c# code if a given url is from my domain or not, in order to add the "nofollow" and "target _Blank" attributes for external links.
When i talk about external links i refer to any link outside my domain.
By default it does not have that attributes. I tried a lot of stuff, basically this is the part i need to fix:
public void PrepareLink(HtmlTag tag)
{
string url = tag.attributes["href"];
if (PrepareLink != null)
{
if (it is from an external site???)
{
tag.attributes["rel"] = "nofollow";
tag.attributes["target"] = "_blank";
}
}
Edit:
things i've tried:
string dominioLink = new Uri(url).Host.ToLower();
if (!dominioLink.Contains(myDomainURL))
{
tag.attributes["rel"] = "nofollow";
tag.attributes["target"] = "_blank";
}
Which has the issue that dont take in mind subdomains
i.e. if a link created is http://www.mydomain.com.anotherfakedomain.com, it will return true and work well.
I've looked in every Uri property but didn't seem to contains the base domain.
I'm currently using .NET Core 2.0.
thankS! please if you need any other data just let me know.
You can use the Uri.Host property to obtain the domain from a URL string, then compare it to your own. I suggest using a case-insensitive match.
var url = tag.attributes["href"];
var uri = new Uri(url);
var match = uri.Host.Equals(myDomain, StringComparison.InvariantCultureIgnoreCase)

Moving files with Google Drive API v3

Im trying to move a file from one folder to another using the Google Drive API v3. I found documentation how to this here. I used the .NET sample code from the documentation page and created a method that looks like this:
public ActionResult MoveFile(string fileToMove, string destination)
{
DriveService service = new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = <USER CREDENTIAL>,
ApplicationName = "APPNAME"
});
var searchFiles = service.Files.List();
searchFiles.Corpus = FilesResource.ListRequest.CorpusEnum.User;
searchFiles.Q = "name = '" + fileToMove + "'";
searchFiles.Fields = "files(*)";
string fileToMoveId = searchFiles.Execute().Files[0].Id;
searchFiles.Q = "name = '" + destination + "'";
string destinationId = searchFiles.Execute().Files[0].Id;
//Code used from documentation
// Retrieve the existing parents to remove
var getRequest = service.Files.Get(fileToMoveId);
getRequest.Fields = "parents";
var file = getRequest.Execute();
var previousParents = String.Join(",", file.Parents);
// Move the file to the new folder
var updateRequest = service.Files.Update(file, fileToMoveId);
updateRequest.Fields = "id, parents";
updateRequest.AddParents = destinationId;
updateRequest.RemoveParents = previousParents;
file = updateRequest.Execute();
return RedirectToAction("Files", new {folderId = destinationId});
}
When I execute this code I get the following error:
The parents field is not directly writable in update requests. Use the
addParents and removeParents parameters instead.
The error doesn't really makes sense to me because this code sample came from the documentation page itself. I can't figure out what other paramters they mean. What addParents and removeParents parameters do they mean? Are updateRequest.AddParents and updateRequest.RemoveParents not the right parameters?
Ok here is the problem.
var updateRequest = service.Files.Update(file, fileToMoveId);
The method is requiring that you send a body of a file to be updated. This normally makes sense as any changes you want to make you can add to the body.
Now the problem you are having is that you got your file from a file.get. Which is totally normal. This is how you should be doing it. THe problem is there are some fields in that file that you cant update. So by sending the full file the API is rejecting your update. If you check Files: update under Request body you will see which fiends are updateable.
Issue:
Now this is either a problem with the client library or the API I am going to have to track down a few people at Google to see which is the case.
Fix:
I did some testing and sending an empty file object as the body works just fine. The file is moved.
var updateRequest = service.Files.Update(new Google.Apis.Drive.v3.Data.File(), fileToMove.Id);
updateRequest.AddParents = directoryToMove.Id;
updateRequest.RemoveParents = fileToMove.Parents[0];
var movedFile = updateRequest.Execute();
This method works well when working in your own drive, but not in a team drive where a file (folder) can only have 1 parent strictly. I do not have the solution in a team drive

ASP.NET CORE w/ NEST/Elasticsearch.net: custom contract resolver

public ISearchResponse<object> GetById(string id) {
var uri = new Uri("<myendpoint>");
var settings = new ConnectionSettings(uri).DefaultIndex("useraction-*").PrettyJson().DisableDirectStreaming(); //or try _all
var client = new ElasticClient(settings);
var search = new SearchRequest<object>
{
Query = new TermQuery
{
Field = "field",
Value = "example"
}
};
var response = client.Search<object>(search);
return response;
}
I'm having trouble getting NEST to work. When I try to call the query defined above, I get the following error:
System.Exception: If you use a custom contract resolver be sure to subclass from ElasticResolver
at Nest.JsonExtensions.GetConnectionSettings(JsonSerializer serializer) in C:\Users\russ\source\elasticsearch-net-master\src\Nest\CommonAbstractions\Extensions\JsonExtensions.cs
I've searched the internet for mention of this and can't seem to find anything other than the source code. I've pretty much followed the documentation exactly so I don't know what to change.
Does anyone out there know what this error is trying to tell me? I feel like it's an error behind the scenes that I don't have control over.
I'm happy to answer additional questions if people need more info.
Thanks.
Also I don't know where that path is coming from in the exception because I have no user "russ"

Iterate through settings files

I'm currently working on a VSTO project for which I have 5 .settings files:
Settings.settings (Default)
s201213.settings
s201314.settings
s201415.settings
s201516.settings
Over time there will be more settings files included following the same naming convention ('s' followed by a tax year).
I know I can iterate through a settings file, but is there a way to iterate through the actual settings files themselves?
I've tried things such as:
public void Example()
{
System.Collections.IEnumerator testSetting = MyAddIn.Properties.s201213.Default.Properties.GetEnumerator();
while (testSetting.MoveNext())
{
System.Diagnostics.Debug.WriteLine("Setting:\t" + testSetting.Current.ToString());
}
}
Which obviously only iterates through a single settings file, but I can't seem to figure out the logic of iterating through all the settings files as a collection, without explicitly naming each one in the code. I hope that makes sense, any help is appreciated.
Update:
I think I'm getting somewhere with the following code:
foreach(Type test in Assembly.GetExecutingAssembly().GetTypes())
{
if (System.Text.RegularExpressions.Regex.IsMatch(test.Name, "^s[0-9]{6}$"))
{
PropertyInfo value = test.GetProperty("LEL");
try
{
System.Diagnostics.Debug.WriteLine("Name:\t" + test.Name +
"\nNameSpace:\t" + test.Namespace +
"\nProperty:\t" + test.GetProperty("LEL").ToString() +
"\n");
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}
}
}
Which seems to be recognising the settings files and the stored values:
Output:
Name: s201213
NameSpace: MyAddIn.Properties
Property: Double LEL
Name: s201314
NameSpace: MyAddIn.Properties
Property: Double LEL
Name: s201415
NameSpace: MyAddIn.Properties
Property: Double LEL
Name: s201516
NameSpace: MyAddIn.Properties
Property: Double LEL
However I can't seem to get the actual value of the "LEL" setting which should return a Double?
2nd Update
I've actually given up and decided to use a local DB instead - but I would still like to know if this is possible, and I think other people would like to know too so I'm going to throw a bounty at it to try and generate some interest.
Jeremy's answer got me to the finish post, but thought I'd post the final code I used so that it can be seen in context:
public void GetLEL()
{
var fileMap = new ConfigurationFileMap(AppDomain.CurrentDomain.BaseDirectory + #"CustomAddIn.dll.config");
var configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
var sectionGroup = configuration.GetSectionGroup("userSettings");
var section = (ClientSettingsSection)sectionGroup.Sections.Get("MyAddIn.s201213");
var setting = section.Settings.Get("LEL");
System.Diagnostics.Debug.WriteLine(setting.Value.ValueXml.InnerXml);
// Prints "107" as expected.
}
The answer is really simple once you see it (no need to iterate through Types nor use System.IO directory):
using System.Configuration; //Add a reference to this DLL
...
var fileMap = new ConfigurationFileMap(Application.StartupPath + #"\GetSettingFilesValues.exe.config");
var configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
var sectionGroup = configuration.GetSectionGroup("applicationSettings"); // This is the section group name, change to your needs, ie application or user
var section = (ClientSettingsSection)sectionGroup.Sections.Get("GetSettingFilesValues.Properties.s201415"); //This is the section name, change to your needs (you know the tax years you need)
var setting = section.Settings.Get("LEL");
System.Diagnostics.Debug.WriteLine(setting.Value.ValueXml.InnerXml);
I agree with your approach to use the dB, though I'm sure this will benefit other people too.
I believe you can use the System.IO namespace classes for iterating through files with the same extension. There is no built-in mechanisms or properties for that.

Navigating to DNN Module

I'm forming a newsletter with links to various html modules within my DNN website. I have access to each of their ModuleID's and I'm wanting to use that to get the url. The current approach (made by a third party developer) worked, but only to a degree. The url's are incorrectly formed when the Modules are located deeper in the website.
For example module located at www.website.com/website/articles.aspx is works fine, but a module located www.website.com/website/articles/subarticles.aspx won't. I know this is because the url is incorrectly formed.
Here's the current code:
DotNetNuke.Entities.Modules.ModuleController objModCtrlg = new DotNetNuke.Entities.Modules.ModuleController();
DotNetNuke.Entities.Modules.ModuleInfo dgfdgdg = objModCtrlg.GetModule(ContentMID);
TabController objtabctrll = new TabController();
TabInfo objtabinfoo = objtabctrll.GetTab(tabidfrcontent);
string tabnamefremail= objtabinfoo.TabName;
moduletitlefrEmail = dgfdgdg.ModuleTitle;
string readmorelinkpath = basePath + "/" + tabnamefremail + ".aspx";
ContentMID is the current module ID I'm looking at. I've tried to use Globals.NavigateURL, but that always crashes with Object reference not set to an instance of an object. error. Same thing when I use objtabinfoo.FullUrl so I'm currently at a loss as to how I get the specific modules URL.
EDIT: Here's some more code as to how the tabId is retrieved.
IDictionary<int, TabInfo> dicTabInfo12 = new Dictionary<int, TabInfo>();
ContentMID = Convert.ToInt32(dsNewsList.Tables[0].Rows[i]["ModuleID"]);
dicTabInfo12 = objTabctrl.GetTabsByModuleID(ContentMID);
if (dicTabInfo12.Count > 0)
{
string tester = ""; //Debug
foreach (KeyValuePair<int, TabInfo> item1 in dicTabInfo12)
{
tabidfrcontent = item1.Key;
}
}
You really should be using NavigateUrl to build the links ance if you have the tabid, you are golden.
string readMoreLinkPath = NavigateUrl(tabidfrcontent);
Nice and simple
Okay, colleague suggested this and it works great within a scheduler.
string linkPath = basePath + "/Default.aspx?TabID=" + tabID;
Will Navigate you to the correct tab ID. So this would be the best solution if you're forced to work within a scheduler where you can't use NavigateUrl without some major workarounds.

Categories