I have a complex Regex which is used to help strip out HTML from user input. I'm aware that .NET caches static Regex calls to some extent, but this one is big and used frequently, so I'd like it to hang around.
In a web site project, I'd like to define it as a shared object, within a helper class in App_Code, eg:
AppHelper.vb in App_Code:
Public Class AppHelper
Private Shared _rxRemoveHTML As New Regex("(<[\s\S]*?(style|script)[\s\S]*?>[\s\S]*?</[\s\S]*?(style|script)[\s\S]*?>)|<[^<>]*>|&#[0-9a-z]+;|&#|<|>|\\|`|\t", RegexOptions.IgnoreCase + RegexOptions.Multiline)
This will keep it alive for the life of the app.
A public function does the work:
Public Shared Function RemoveHTML(ByVal sIn As String) As String
Return _rxRemoveHTML.Replace(sIn, "")
End Function
The question is, is this thread-safe and otherwise ok for a web app?
Yes, it is perfectly safe to do so. Taken from MSDN:
Thread Safety
The Regex class is immutable (read-only) and thread safe. Regex objects can be created on any thread and shared between threads
Related
I could not find a similar question, and this could be a dumb question, not sure, I couldn't figure out what keywords to search for.
For example, we have some sort of request/response pair for accessing information from the database (forgive me, using VB .NET at work, not my choice, so I'm just staying consistent)
Public Class ItemAddRequest
Public param1 As String = ""
Public param2 As String = ""
End Class
Public Class ItemAddResponse
Public returnParameter As MyItemObject = ""
Public Function Invoke(req As ItemAddRequst)
' SQL Queries go here
' Build my returnParameter
End Function
End Class
So these are used for the front end to get information to display on the front end, but is it bad to use these somewhere else in your code for the sole purpose of getting that info or adding that info? Generally you would want to modularize (invented word) that and use methods of my MyItemObject to do this, but we already have a large collection of things that would need to be changed so we are not doing that, at least for now. So for example we are doing something like this
Public Class ParentItemAddRequest
Public param1 As String = ""
Public param2 As String = ""
End Class
Public Class ParentItemAddResponse
Public returnParameter As MyParentItemObject = ""
Public Function Invoke(req As ParentItemAddRequest)
' SQL Query goes here to add parent
' Now also need to add a regular MyItemObject
Dim itemReq as new ItemAddRequest()
Dim itemResp as new ItemAddResponse()
itemReq.param1 = 'whatever
itemReq.param2 = 'whatever
itemResp.Invoke(itemReq)
me.returnParameter = itemResp.returnParameter
End Function
End Class
Doing this seems to work fine, but what kind of problems could we anticpate to cause? Or is this a completely normal thing? Seems odd to us. Thanks for the help.
If this code works than not much is wrong. If it aint broke then dont fix it. That being said, the only thing wrong with this code, i think, is that it uses wrong patterns. It just looks wrong. The only problem it would create is that it would confuse the hell out of new hires. Another serious implication of working this way is that the Class is now responsible for two things (1) declaring the data contract (2) defining the algo to fill it. This mixup is frowned upon according to SOLID principles. The mixup of responsibilities make it difficult to do unit testing and impact analysis.
When I find a Request class and Response class, the immediate assumption is that you guys are using the DTO pattern. The classes are assumed to be data contracts because of their naming convention. Now, the dtos are supposed to be simple POCOs devoid of any business logic. This is so that you can put all such classes in a seperate dll and different clients can use the shared data structures. So I wont be expecting the Invoke method there. I would expect that the dto is filled at the DAL layer either by handcrafted sqls in a DAO class or via some orm like entity framework.
With handcrafted sqls, I would expect a set of classes like Class ParentItemDAO with methods like Function Add(req As AddParentItemRequest) As AddParentItemResponse. Similarly I would expect a method Function GetParentItemById returning either a business object or a dto.
our ASP.NET application is using COM+ to connect to Database
we have this structure:
A Base Class :
Imports System.EnterpriseServices
Public Class Base Inherits ServicedComponent
A Child Class:
Public Class Member Inherits Base
'Propreties
.
.
.
'Methods
Public Sub SetMember(ByVal SelectedQueue As String)
...
End Sub
In a Aspx page, we search for a member and set details:
Dim newMember As Member = New Member
newMember.SetMember(MemberNumber)
Session("SelectedMember") = newMember
We then dispose newMember:
If Not newMember Is Nothing Then
newMember.Dispose()
End If
but whenver we access the session we got an exception:
If Not Session("SelectedMember") Is Nothing Then
'Something
Else
'Something else
End If
the exception is :
Cannot access a disposed object. Object name: 'ServicedComponent'.
How can I dispose the object but keep my session valid?
I can see what you're doing wrong, but can't be clear on what would be right. Your logic as stated is:
Obtain object.
Store object.
Clean-up object, rendering it useless.
Retrieve object.
Use object.
Having 3 before 5 makes no sense.
If the object is quick to obtain, you should just do so on every page. (Often people over-estimate the cost of this).
If the object is slow to obtain, and it makes sense to store for a long term, then it shouldn't need to be cleaned-up. What is Dispose() actually doing here? With it obtaining and releasing resources used by members as needed.
I suspect that the first is the one to go for here, but that's mostly a guess.
I'd also be concerned when you talk about the database, does your object hold a database connection? If so, and pooling is available, then you should be releasing those connections as fast as possible, rather than holding onto them.
I had a problem (which is now fixed) but I've no idea why...
I have an Ajax AutoCompleteExtender with a WebService method to populate like
<WebMethod()> _
Public Shared Function populateACE(prefixText As String) As List(Of String)
However this didn't work - I put a breakpoint in, and it didn't even get hit. However...
<WebMethod()> _
Public Function populateACE(prefixText As String) As List(Of String)
..does work (the only difference being not Shared).
Fair enough, but why? If you have an instance of a class then you can access Shared methods of it; if you don't have an instance of a class then you can access Shared methods of it. So what is going on behind the scenes?
If you're calling a page method then it must be Shared/static. But when calling methods attached to asmx services, accordining to John Saunders in this question,
Why are Static Methods not Usable as Web Service Operations in ASMX Web Services?, web methods can't be Shared/static by design.
I'd have to guess that both are design limitations in the pipelines that retrieve pages vs. web methods.
To quote the relevant part from John Saunders' answer..
The answer is: because you can't.
It's not designed that way. The design is that an instance of the web
service class will be created, and then an instance method will be
called.
..but still worth having a look at the full answer.
I have to send emails when a person receives a personal message on my website and for that I use a StringBuilder to create the HTML markup of the email.
also since it is required at many other places as well I have made a Shared Function (I am using VB.NET). now my only concern is that since shared functions are shared among all objects and maybe asp.net sessions, can it be possible that before one person email is being formed and another person access the same function, it would cause the data in the stringbuilder to be overwritten..
Currently my site doesn't have many users but can this become an issue in the future... Please advise me on this... Is there any better way or standard procedure to follow when using shared functions?
Also at one time I made the mistake of using a shared connection object and it would cause close if many people were to access it.
Shared functions can only access static/global variables as well as variable inside the function scope. So, if the the function is working with any number of static/shared resources then you need to synchronize between the calls to the function.
In your case, however, it doesn't sound like you're working with any shared resources, so it shouldn't be a problem.
Here's a case that illustrates the problem:
private static myCounter As Integer = 0
public shared function IncreaseCount() As Integer
myCounter += 1
for i as integer = 0 to 10 million
//'do extensive work
next
return myCounter
End Function
Imagine that you call the function for the first time, and you would expect it to return the number 1. But due to the fact that the function was called again before the first function call got to return the counter was increased once more, which means that both function calls return 2 instead of respectively 1 and 2. All the problem arrives when you want several things working on the same static resource.
Instead of using a static method you can have an EmailSender object attach to current HttpContext.This way each user will have its own EmailSender instance.
Here's the code in C# :
private static EmailSender _instance;
public static EmailSender GetEmailSender()
{
if(System.Web.HttpContext.Current != null)
{
if(! System.Web.HttpContext.Current.Items.ContainsKey("EmailSender"))
System.Web.HttpContext.Items["EmailSender"]=new EmailSender();\
return (EmailSender)System.Web.HttpContext.Current.Items["EmailSender"];
}
if(_instance==null)
_instance=new EmailSender();
return _instance;
}
It will work in web and windows application.
now every time you want to send an email you can do as follows:
GetEmailSender().SendMail(MailInfo mailInfo);
Also, if you're using VB.NET on Framework 3.5, you may want to look into using XML literals to build your HTML instead of StringBuilder. XML literals will make your code SUPREMELY more readable, and allow for very easy insertion of data into your message.
As a SIMPLE example...
Dim msg = <html><body>
Message sent at <%= Now.ToString() %>
</body></html>
myMailMessage.IsBodyHtml = True
myMailMessage.Body = msg.ToString()
I have a class called MembershipHelper, which I am using in my ASP.NET project. It looks like this:
Public Class MembershipHelper
Public Shared Function IsMultiStoreUser() As Boolean
return Roles.IsUserInRole(....)
End Function
Public Shared Function IsAdmin() As Boolean
return Roles.IsUserInRole(....)
End Function
Public Shared Function IsReaderOnly() As Boolean
return Roles.IsUserInRole(....)
End Function
End Class
I read somewhere that its not a good idea to have a class with just shared functions - but I don't remember where.
Why is this bad and how can I improve it?
Thank you
From the naming that you used for your functions it seems that all functions describe properties of a user (e.g. whether the user is an admin).
Therefore it would seem more natural** to have these functions replaced by properties of your user object or by having your user implement an IRole interface.
** I'm not saying that your design is good or bad. Depending on the context such a helper class might very well be reasonable.
Shared functions are like static functions, which in turn are like global functions or objects.
What you are essentially doing in your example is adding some redirection and abstraction, which I think is fine for Helper/Extension classes.