How do I get the domain name from a request? - c#

Well, the answer should be simple. The documentation is pretty clear as I can use the Host property of the Uri class. However, this host would also include the subdomain. I just want the main domain.
So, simple solution is to use a regular expression or other string operation to get the text before and after the last dot in this host. So www.contoso.com would just return the bold part. Except, it doesn't work for domain names which end with e.g. co.uk, like www.contoso.co.uk and other domains. There are a few countries that have these kinds of second-level domains and unfortunately, .co is a top-level domain too. There are a few other second-level domains like .edu, .as, .sch and possibly a few more and I don't want to add exceptions in my code for all these variants. I could, by retrieving data from publicsuffix.org about all the domain suffices that are possible, but I wonder if there's an easier method.
So, can this be done in an easier way?
FYI, I have a web application that crawls the Internet and thus gets a lot of uris that it needs to process. I want to group them based on the domain name, and it's annoying if that name is co.jp or botanical.museum or whatever they use. I can parse that list, put it all in a database table and filter uris based on these, but it just seems messy. I want something cleaner...
I don't think there's a cleaner option, though. Still, if I don't ask, I'll never know for sure.

Related

Loading .resx file by custom string that doesn't map to a culture

I'm making a website for use by multiple clients and I need to offer the flexibility to change labels on various places. For example, if one client wants to call the login "Email" and another wants to call it "Employee ID." Though I've never used them, I thought that resx resource files used for localization would be a good idea, but I'm having problems setting it because what I'm doing isn't a real localization that maps to any culture.
My testing has these resource files:
Global.resx
Hello "Hello!"
Global.Casual.resx
Hello "Sup!"
Global.Formal.resx
Hello "Greetings!"
Then in my cshtml view, I can say #Resources.Global.Hello and that works as expected. My question is, how can I set it to display Casual by default? If I rename Casual and Formal to es and ru, I can do something like this:
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("es");
And that works just fine. But if I try that with "Casual" I get that it "is an invalid culture identifier." I can explicitly show it by saying #Resources.Global_Casual.Hello in the view, but that's obviously not what I'm after.
Am I going the complete wrong direction here, trying to use something for a purpose contrary to its design? I just want to load resource files by arbitrary string values. Do I need to roll my own database-driven approach?
This looks very similar to this SO question, which never got an answer: How to specify a custom culture?
Personally I feel that this kind of customisation belongs in the database - not least because you can then allow the clients to customise it themselves if required. If you are concerned about performance then you can cache the terms into a dictionary and even create a class that will expose the strings either from the dictionary (if the client has customised them) or from a resource file if not. This allows you to present reasonable defaults which can be changed on demand. Alternatively you could present a number of alternatives in the database, and a flag to allow selection per term of the word to be displayed in the UI.
I had a similar problem of allowing customisation within an application in the SO question Localization vs Customization which you may find useful.

Pre-process MVC Razor File For Multi-Lingual Language Strings?

In my application we have multi-lingual language strings which are stored in custom tables, as the user can edit, delete, import new languages etc... via a UI
Currently, what I'm doing is at the beginning of each request is. I'm going off and getting all the language strings (From our database) for the currently selected language and sticking them in a dictionary.
I then have a Html Helper extension method which I use in the razor views (See below), which fishes in the dictionary I got at the beginning of the request to pull out the correct language based on the key supplied in the helper.
Html.LanguageString("MyLanguage.KeyHere")
Now this works fine. However, as the application is getting bigger. We are getting more and more language strings. It's not an issue right now, as its still very fast as there are only around 200 strings to get.
But this also means I'm getting all of them, even if a page has say one on it. I'd ideally like a way of processing the LanguageString("")'s before hand and doing a query to just get those that are needed at the beginning of the request? Or maybe my own linq based language that can be processed and product a more efficient call.
I'm looking for some advice on how to do this. As I'd like the application to be as efficient as possible. Any advice, help, tips are greatly received. Thanks.
I'd suggest caching language strings on the application basis rather than fetching them for every request. For example, this can be done by maintaining a static dictionary and invalidating the cache only when the user makes changes to these strings. This will make your application more responsive as well as save you from implementing (imho) rather more complex and not necessarily efficient technique of loading this data on-demand.
As a side note I'd add the following: it's usually a good practice to address these kinds of problems when they arise (rather than fixing something that is not broken) and focus on more important things. I totally agree that performance implications of a given solution must always be taken into consideration, I'm just saying that premature optimizations are not always a good idea.

How do you set OptionSet Values in Microsoft CRM 2011, based on the text or label?

I am implementing a web service that receives information and needs to map them on the MS Dynamics CRM.
So, when it comes to setting OptionSet values, since I am not the one who implemented the CRM, I have no idea what indices are set up. All I know are the labels. Naturally so do the ones consuming my service. e.g. I call an Opportunity Warm or Cold, not 10033004 and 10033005. But I still need to set this value on the Opportunity entity.
I have found this link - but I think it's really overkill and if that's the only way I can access the OptionSet, then that's just sad.
Couple of options here.
Use the metadata services e.g. Your link, I agree this feels like a bit of an overkill, but you could add caching to reduce the overhead of multiple service calls. If you really don't know what the value is going to be at run time then this is probably the best way.
Just hard code it, if you know at compile time what the values will be then this is probably the quickest option. I've done this before and its usually fine. However this will obviously break if someone changes CRM.
Use the strongly typed classes, this is effectively hard coding just the system does it for you. However you will have regenerate them if CRM changes.
So none of these are a perfect option I'm afraid, but they all get the job done.
Edit
Re: option 3; I mean the early bound entities described here: http://msdn.microsoft.com/en-us/library/gg328210.aspx. I'm not sure how much they will help in this situation. They are strongly types classes which are used instead of the entity class. E.g. contact.firstname instead of entity["firstname"]. I suppose you might be able to use them as a form of metadata - never tried it myself though. Also it has the same problem as option 2, when CRM changes they need to be updated and then compiled.
In this case I'm veering towards option 1 and querying the metadata services, if you do this once and cache the results at the beginning of your process you will always have the most up to date information. This example shows how to get all the metadata in the system http://msdn.microsoft.com/en-us/library/jj603008.

ASP.NET MVC 3 Razor View Restrictions

I apologize in advance for the generic nature of my question, but I was unable to find any helpful advice from people trying to do the same thing as me on the web. Let me describe my scenario:
I am providing end users/designers of a website the ability to customize their views by storing the views (using Razor) in the database. I have all of this working, but my question is the following; From a security standpoint, how can I ensure and enforce that unwanted code doesn't get executed in the user-defined view? There are two basic approaches that I think will work conceptually, but am not sure which one is more possible or feasible.
Option 1: Create a validation method in the administration tool that allows the user to input the view code. This would need to either take a whitelist or blacklist approach to what is allowable or not.
Option 2: Prevent unwanted code from being able to execute when rendering of the view occurs.
As a quick example of something that would need to be blocked, we wouldn't want to allow access to read or write files, access any data access functions, or even access configuration settings, etc. in the web.config. There will likely be a decently-sized list of things that probably shouldn't be allowable, but I'll need to sit down and try to think of as many security-related concerns as possible.
My question then is, which method would be the best bet? Also, can any direction be provided on how to go about either? I thought I might be able to make trust-level based change which would be Option 2, but couldn't find any way to make that work in a per-view based manor (the administration code is allowed to execute whatever it wants). I'm thinking Option 1 will end up being the best bet and I'll have to check for the input of certain framework functions that shouldn't be allowed. Does anyone have any experience doing anything like what I'm trying to do? ANY feedback is much appreciated!
This would be extremely difficult.
You could run the the template through the Razor preprocessor, then use Roslyn (still in early beta) to parse the generated file and look through all method calls (or constructors) and return an error if it calls something you don't like.
I strongly recommend that you use a whitelist for that, since the .Net framework is big enough that you are bound to overlook something in a blacklist.
However, I would instead recommend that you not use Razor at all and instead use a templating engine that does not allow real C# code.

Email templating engine

I am about to write a simple email manager for the site I'm working on (asp.net/c#); the site sends out various emails, like on account creation, news, some user actions, etc. So there will be some email templates with placeholders like [$FirstName] which will be replaced by actual values. Pretty standard stuff. I'm just wondering if someone can advise on existing code - again, i need something very simple, without many bells/whistles, and obviously with source code (and free)
Any ideas/comments will be highly appreciated!
Thanks,
Andrey
There are several threads on Stack Overflow about this already, but I ended up rolling my own solution from various suggestions there.
I used this FormatWith extension method to take care of simple templating, and then I made a basic Email base class to take care of common tasks, like pulling in an appropriate template and replacing all the requisite info, as well as providing a Send() method.
All the emails I need to send have their own subclass deriving from the base, and define things unique to them, such as TemplateText, BindingData, Recipients, and Subject. Having them each in their own class makes them very easy to unit test idependently of the rest of the app.
So that your app can work with these email classes without really caring which one it's using, it's also a good idea to implement an interface, with any shared methods (the only one I cared about was Send()), so then your app can instantiate whatever email class it wants and work with them in the same way. Maybe generics could be used, too, but this was what I came up with.
IEmail email = new MyEmailClass();
email.Send();
Edit: There are many more suggestions here: Can I set up HTML/Email Templates with ASP.NET?
I always do the following. Templates = text string with {#} placeholders. To use a template I load the string (from whatever store) and then call string.Format(template,param1,param2..)
Simple and works well. When you need something stronger you can move to a framework of some kind but string.format has always worked well for me.
note
Alison R's link takes this method to the next step using 3.5's anonymous types to great effect. If you are 3.5 I recommend using the FormatWith there (I will) otherwise this way works well.
Having just done this myself, there is some great information at: Sending Email Both in HTML and Plain Text. Best part is, you don't need anything other than .NET.
Essentially, you create an HTML page (AKA, your formatted e-mail) with the tags that you want to replace (in the case of this solution, tags will be in the format of: <%TAGNAME%>). You then utilize the information found at the above website to create a mail template with the tags filled with the appropriate data, and the injections will be done for you into your HTML template. Then, you just use the SMTP classes built into .NET and send the mail on its way. It's very simple and straightforward.
Let me know if you have any additional questions. Hope that helps!
If you are using ASP.NET, you already have a templating engine available to you. Simply create an ASP.NET page that will produce the results for you (using whatever controls, etc, etc) you want, as well as setting the ContentType of the response to the appropriate type (either text or HTML, depending on the email format)
Make sure that this url is not publically exposed.
Then, in your code, you would create an HttpWebRequest/HttpWebResponse or WebClient and then fetch the URL and get the contents. The ASP.NET engine will process the request and return your formatted results, which you can then email.
If you want something simpler, why not use a RegEx and match? Just make sure you have a fairly unique identifer for your fields (prefix and suffix, which you can guarantee will never be used, or, you can at least write an escape sequence for it) and you could easily use the Match method to do the replace.
The only "gotcha" to the RegEx approach is that if you have to do embedded templating, then that's going to require a little more work.

Categories