|
Yeah, that helps to clarify things a bit. I would say that your not really storing user state or dealing with context at all in that situation. What you are doing is caching. I still think that storing your state in the session directly is creating an undesired link between your model and the system and frameworks that display data from the model. The simplest solution is to abstract the caching a bit by creating a simple, mockable caching system:
interface ICache
{
void Add(string key, object toCache);
object Get(string key);
void Remove(string key);
}
class SessionCache: ICache
{
private HttpSessionState Session
{
get
{
if (HttpContext.Current != null)
HttpSessionState.Current.Session;
return null;
}
}
private bool IsSessionAvailable
{
get { return HttpContext.Current != null; }
}
public void Add(string key, object toCache)
{
if (!IsSessionAvailable) throw new InvalidOperationException("Session cache is only available within an HttpContext.");
Session[key] = toCache;
}
public object Get(string key)
{
if (!IsSessionAvailable) throw new InvalidOperationException("Session cache is only available within an HttpContext.");
object item = Session[key];
return item;
}
public void Remove(string key)
{
if (!IsSessionAvailable) throw new InvalidOperationException("Session cache is only available within an HttpContext.");
Session.Remove(key);
}
}
class DictionaryCache: ICache
{
private Dictionary<string,> m_cache;
private Dictionary<string,> Cache
{
get
{
if (m_cache == null)
{
Interlocked.CompareExchange(ref m_cache, new Dictionary<string,>(), null);
}
return m_cache;
}
}
public void Add(string key, object toCache)
{
Cache.Add(key, toCache);
}
public object Get(string key)
{
object item = Cache[key];
return item;
}
public void Remove(string key)
{
Cache.Remove(key);
}
}
static class CacheManager
{
private static ICache s_cache;
public static ICache CacheInstance
{
private get { return s_cache; }
set { s_cache = value; }
}
public void Add(string key, object toCache)
{
CacheInstance.Add(key, toCache);
}
public object Get(string key)
{
return CacheInstance.Get(key);
}
public void Remove(string key)
{
CacheInstance.Remove(key);
}
}
public class Global: HttpApplication
{
public void Application_Start(object sender, EventArgs e)
{
ICache cache = new SessionCache();
CacheManager.CacheInstance = cache;
}
}
public class ModelEntity
{
public object LazyLoadedObject
{
object item = CacheManager.Get("LazyLoadedObject");
if (item == null)
{
item = GetLazyLoadedObject();
CacheManager.Add("LazyLoadedObject", item);
}
return item;
}
private object GetLazyLoadedObject()
{
}
}
[TestClass]
public class ModelEntityTests
{
public void LazyLoadedObject_Get_AlreadyCached()
{
ICache cache = new DictionaryCache();
CacheManager.CurrentCache = cache;
object originalInstance = new object();
cache.Add("LazyLoadedObject", originalInstance);
ModelEntity entity = new ModelEntity();
object cachedInstance = entity.LazyLoadedObject;
Assert.AreEqual(originalInstance, cachedInstance);
}
}
I am not sure the model entity and test represent exactly what your doing, but it should demonstrate the need to abstract where you store cached data from the activities of caching itself. If you do something like the example above, your model stuff is now bound to ICache and CacheManager...and the link to ASP.NET is gone...so your model should be more testable in isolation from the environment(s) it is used in/bound to. The example above isn't really ideal, either...I would say its probably better to cache at a lower level than the model objects themselves. I think there are some more blending of concerns in your system...I can't say exactly as I don't know enough about it. The list of Commands should probably be separated from the model objects as well: WorkItem and WorkItemData are entities...however, Commands is a persistance utility, and probably belongs in a separate facility that handles the persistence and retrieval of your entities separately. Thats really a different discussion though...even the discussion above isn't directly tied to MVP, although it does provide a useful abstraction that lets you keep ASP.NET elements out of your model objects, and makes it easier to put your Presenters in a separate library from your views and models in a separate library from both.
|
|
|
|
|
Jon, thanks for all the help, I had one of those moments where I thought I knew what I was doing and in a few simple sentances I realise how wrong I was.
I would like to continue the 'conversation' about this but not sure the forum is the best place for this.
Thanks again for all the help.
|
|
|
|
|
Hi Nathan,
I would love to continue the conversation as well. Perhapse IM would be best...a real-time forum might be best suited to helping you improve your architecture. I'll email you my contact info.
|
|
|
|
|
That would be greatly appreciated Jon.
'bout to pack it in this evening but sure can arrange time when both of us are around
|
|
|
|
|
Hi Jon,
I tried to email you via the link but don't know if its working. Hoping you'll get notified of this as could do with discussing the architecture.
You can get me at nathans.FICTICIOUSVALUE.dropbox@NONSENSEVALUE.googlemail.RANDOMVALUE.com
I'll leave you to sort out the email address
|
|
|
|
|
Hi all,
I have used this code for sending mail using Outlook but its giving access denied problem
<%
function SendMessages()
' Dim MyDB As Database
'Dim MyRS As Recordset
'Dim objOutlook As Outlook.Application
set objOutlook = CreateObject("Outlook.Application")
set objOutlookMsg = CreateObject("Outlook.MailItem")
set objOutlookRecip = CreateObject("Outlook.Recipient")
set objOutlookAttach = CreateObject("Outlook.Attachment")
Dim TheAddress
Dim ThePhone
Dim SendEmail
Dim SendPhone
Set MyDB = CurrentDb
Set MyRS = MyDB.OpenRecordset("tblMailingList")
MyRS.MoveFirst
' Create the Outlook session.
'Set objOutlook = CreateObject("Outlook.Application")
end function
%>
|
|
|
|
|
Because your asp.net dont have permission to acces the Outlook Application.
for that in "Run" type dcomcnfg and press enter.
now go to Component Services -> Computer -> My Computer -> DCOM Config.
then find your "Microsoft Outlook Application".
righ click and select "Property".
go to Security -> Access Permission -> Customize -> Edit.
Now add "Everyone" and Allow both the options ticked.
Note : You can search on internet for specific accounts instead of giving access to everyone.
I think you can try just "ASPNET", But I am not sure.
And why you want to send mail using Outlook. you can use inbuilt classes in .net framework. that is much easier and less resource hungry. MS Office integration will eat up your resource. also there is very difficult to distroy the object. After running this if you see your Taskbar. you will see many running instance of Outlook.exe. that you cannot stop from your web application. I have used Excel so I know this problem.
|
|
|
|
|
Why would you need to use outlook on the server ? You realise this won't use outlook on your users machine, right ?
Christian Graus
Driven to the arms of OSX by Vista.
|
|
|
|
|
Hi,
Now i am not using outlook for sending mail,i m sending mail through .net classes,but thanx for giving feedback for my question
N!dh!
|
|
|
|
|
hi,
how to render a gridview from 2 database tables,all the columns from 1 table and only 1 from another table?I am using MS SQL and c# language.
Regards,
Bill
|
|
|
|
|
billcodes wrote: how to render a gridview from 2 database tables,all the columns from 1 table and only 1 from another table?
Then why you are not joining those Two table ?
|
|
|
|
|
i have added column of checkbox in a gridview..now i want to delete rows for which checkbox is checked..how can it be done?? i am doing it in asp.net(C#)
|
|
|
|
|
|
i am displaying all users name on my page and on mouseover i have to show
some datail information of that user in hover
i have done this for 1 user
<cc1:HoverMenuExtender ID="HoverMenuExtender2" runat="server" TargetControlID="LinkButton2" PopupControlID="PanelPopUp1" PopupPosition="Right" PopDelay="100" HoverCssClass="popupHover">
</cc1:HoverMenuExtender>
<asp:Panel ID="PanelPopUp1" runat="server" Width="95px" CssClass="popupMenu" BorderColor="Transparent">
<asp:GridView ID="gvPopup1" runat="server" AutoGenerateColumns="False" GridLines="None" DataSourceID="SqlDataSource2" OnSelectedIndexChanged="gvPopup1_SelectedIndexChanged" Width="194px" DataKeyNames="TaskId">
<Columns>
<asp:ButtonField CommandName="Select" Text="Select" Visible="False" />
<asp:BoundField DataField="TaskId" HeaderText="TaskId" SortExpression="TaskId" Visible="False" />
<asp:TemplateField>
<ItemTemplate>
<table>
<tr>
<td>
<asp:LinkButton ID="LinkbtnTask" ForeColor="#808080" runat="server" OnClick="LinkbtnTask_Click" CommandName="Select"><%# Eval("Task") %></asp:LinkButton>
<%--<asp:Label ID="lblTask" runat="server" Text='<%# Eval("Task") %>' Width="141px"></asp:Label>--%>
</td>
<td style="width:10px;">
</td>
<td>
<asp:Label ID="lblStatus" runat="server" Text='<%# Eval("Remark") %>'></asp:Label>
</td>
</tr>
</table>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:WebSiteConnectionString %>"
SelectCommand="DailyReport" SelectCommandType="StoredProcedure" ProviderName="<%$ ConnectionStrings:WebSiteConnectionString.ProviderName %>">
<SelectParameters>
<asp:Parameter DefaultValue="TS" Name="oprtype" Type="String" />
<asp:Parameter DefaultValue="3" Name="LoginId" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
</asp:Panel>
<asp:LinkButton ID="LinkButton2" runat="server" Visible="false" ForeColor="ControlDarkDark" Font-Bold="True">Alien </asp:LinkButton>
but i want to do it dynamically for all users
is it possible
with regards
rahul
|
|
|
|
|
I don't see the issue. Take the code that defines the one user you did it for, and then generate code that works for all users.
Christian Graus
Driven to the arms of OSX by Vista.
|
|
|
|
|
Hi experts,
Is there a possible way to set filter options like in .net ".rpt" or any file extension?
Thanks in Advance ^^
|
|
|
|
|
There is no way to set the filter when selecting file. You can check the file extension on server side and inform about unsupported file types.
|
|
|
|
|
What is your preferred implementation for AJAX modal popups?
I think that the Netflix implementation is pretty standard.
Does .NET provide a good AJAX popup implementation out of the box or do you tend to use third party controls for this instead?
|
|
|
|
|
|
I'm using ASP.NET 2.0, Visual Studio 2005, AJAX, C#.
I have a search results page that lists out products that a user is searching for inside the Repeater control. I have an image inside every product that when a user clicks on it I need to query the database to get the data. All the samples I have found show code with the panel already populated with data. I want to do it on demand. I've attempted to use the DropDownExtender, HoverMenuExtender and PopupControlExtender with no luck.
|
|
|
|
|
Hi,
I have this popup page where i am doing this in the button click:
Response.Write("<script language='javascript'>function changeParent(){window.opener.document.getElementById('ctl00$ContentPlaceHolder1$txtChange').value='Change';}window.close();</script>");
In the parent form I have a hidden textbox set to autopostback=true and in the textchanged event handler, I am doing response.redirect(url).
In the script above(in the popup), I am changing the value of the textbox located in the parent page.
So, I was expecting it to work, but its not.
Any idea?
Thanks.
|
|
|
|
|
You can call the function __doPostback event in the parent window. Take a look at the parent's source and see what script the hidden field is invoking (in case it's not the default __doPostback). Add that code to your popup window script.
|
|
|
|
|
I've found this in the parent's source:
onchange="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$txtChange\',\'\')', 0)"
But what would be the syntax to call this from the popup window script? Do I call it after changing the value? like:
Response.Write("<script language='javascript'>function changeParent(){window.opener.document.getElementById('ctl00$ContentPlaceHolder1$txtChange').value='Change';<br />
__doPostBack(\'ctl00$ContentPlaceHolder1$txtChange\',\'\')', 0);<br />
}window.close();</script>");<br />
Thanks.
|
|
|
|
|
Put a client side javascript function call in the onchange event of your field in the parent window. That should fire when your popup changes the field. You can force the postback in that function.
|
|
|
|
|
Hi guys i am adding many dynamic LinkButton inside a table cell. What i want to do is if the row gets full move the move the next LinkButton to underneath the current row. and each LinkButton should have background colour.
I am thinking of nested tables but how can move the LinkButton to the next row if the top one get fills up.
Thanks in advance
|
|
|
|