I learned that in umbraco, we have to use a master template for a custom user control. I have a custom form and a submit button. I created a control that sends an email once the 'submit" button is pressed. the control basically gets all the fields like name, address. It works when I create a new template and insert the macro.
However when I try to use it with a master template, it does not work. The submit button refreshes the page but never goes to my c# part where it sends the mail
and if I do this
<form name="myform" target="_self" method="post" action="index">
it goes to the index page, but no email is sent.
But it works on a clean or new template. Is there a way to use custom control with master template in umbraco 4
EDIT -
This is how I am using macro
<form name="myform" target="_self" method="post" action="index">
<umbraco:Macro Alias="sendMail" runat="server"></umbraco:Macro>
</form>
Looking at the code it looks like you are missing the runat="server" attribute on the form tag.
<form name="myform" runat="server">
<umbraco:Macro Alias="sendMail" runat="server"></umbraco:Macro>
</form>
By using the runat=server attribute the form tag will be rendered with the correct attributes. Note you can only have one runat="server" form on a page.
There's some more information on this concept on W3Schools
I assume you are using ASP.NET WebForms. I have Umbraco sites in which I also use a Master Template and a Macro which contains a form. This should work normally.
What I notice is that you have set the "action" attribute which is ignored. Also the "method" attribute default value is "post" so you don't need to set both these properties.
An ASP.NET Webform is always posting to itself, so you can remove the "target" property here. I'm not sure that removing these "unwanted" attributes will solve your problem.
If not, are you using nested .NET Forms? That is throwing errors and strange behavior as well.
Related
I'm having a problem while creating dynamically a web page in ASP.NET (C#).
I need to insert multiple form tags in that page, I know that I can't put
more than one with runat="server" attribute and I don't need it.
I want to place them from C# (one for each element I've got to manage), without the runat attribute but the HtmlForm object
that I use for insert the form adds the runat attribute automatically and I can't remove it
(tried with form.Attributes.Remove("runat"))
If I use a simple string like:
"<form id="someID" method="POST" action=""></form>"
and I add it multiple times into my div it works.
The point is that I don't want to insert ALL my HTML objects writing them in a string
and add it with InnerHTML method. I'm looking for an object that manage a Form without
the runat attribute or a way to remove that from HtmlForm.
A user control is probably the cleanest solution but you can add an HtmlGenericControl instead of a HtmlForm object which isn't bound to any specific attributes.
Dim ctrl As New HtmlGenericControl("form")
ctrl.Attributes.Add("id", "someID")
ctrl.Attributes.Add("method", "POST")
ctrl.Attributes.Add("action", "")
OuterDivContainer.Controls.Add(ctrl)
If you want to add controls dynamically to a page and make the web page render them as pure html, instead of rendering asp:Controls you can use the Literal control. Check this link or this one
I have a fairly simple page with a set of jQuery tabs, the content of some is called via ajax. I also have a search box in the masterpage in my header.
When I open the tabbed page the search box works fine. However once I have clicked on one of the ajax tabs the search box fails to work with an "Invalid Viewstate" yellow screen of death.
I believe this is because the ajax page is replacing the __VIEWSTATE hidden input with its own.
How can I stop this behaviour?
UPDATE: I have noticed that the YSOD only appears in IE and Chrome, Firefox doesn't seem to have the same issue. Although how the browser influences the ViewState, I'm not sure.
UPDATE: I've put a cut down version of the site that shows the issue here: http://dropbox.com/s/7wqgjqqdorgp958/stackoverflow.zip
The reason of such behavior is that you getting content of the ajaxTab.aspx page asynchronously and paste it into another aspx page. So you getting two instances of hidden fields with __VIEWSTATE name and when page posted back to server theirs values are mixing (might depends on how browser process multiple controls with same name on submit). To resolve this you can put second tab's content into a frame:
<div id="tabs">
<ul>
<li>Default Tab</li>
<li>ajax Content</li>
</ul>
<div id="tabs-1">
<p>
To replicate the error:
<ul>
<li>First use the search box top right to search to prove that code is ok</li>
<li>Then click the second ajax tab, and search again.</li>
<li>N.B. Chrome / IE give a state error, Firefox does not</li>
</ul>
</p>
</div>
<iframe id="tabs-2" src="ajaxTab.aspx" style="width:100%;" ></iframe>
</div>
Also, I'm not sure but this seems like error in the Web_UserControls_search control. In my opinion, NavBarSearchItemNoSearchItem_OnClick method must be refactored as below:
protected void NavBarSearchItemNoSearchItem_OnClick(object sender, EventArgs e)
{
var searchFieldTbx = NavBarSearchItemNo;
var navBarSearchCatHiddenField = NavBarSearchCatHiddenField;
var term = searchFieldTbx != null ? searchFieldTbx.Text : "";
if (term.Length > 0) //There is actually something in the input box we can work with
{
//Response.Redirect(Url.GetUrl("SearchResults", term));
Response.Redirect(ResolveClientUrl("~/Web/SearchResults.aspx?term=" + term + "&cat=" + navBarSearchCatHiddenField.Value));
}
}
Draw attention that we resolving client url when redirecting to search results page and instead of navBarSearchCatHiddenField use navBarSearchCatHiddenField.Value as cat parameter.
I guess that you use AJAX to fill the content of the tab. So in this case, content of your tab will be replaced by the new one from ajax and certainly _VIEWSTATE will be replaced. At server, do you use data from ViewState? In the "static tabs", you should prevent them auto reload by using cache:true
Your issue is that with your ajax call you bring in a complete ASPX page. Including the Form tag and its Viewstate. If you remove the Form tag from ajaxTab.aspx you will see everything works fine. asp.net does not know how to handle two Form tags in one page. Same goes for hidden Viewstate fields. You cannot bring in a full aspx page via ajax. Just bring in the content Div you want to display and you`ll be good to go.
I try to publish a C#/ASP.NET page and receive the following error message:
Control XXX must be placed inside a form tag with runat=server
When I add the <form runat="server"> tag, I receive the following error:
A page can have only one server-side Form tag.
I know that my master page has the runat=server form tag and that the content is encompassed within that tag. I also see that the error appears to be occuring within
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\a05ad405\1aeb0277\App_Web_lgjjhruj.3.cs:0
which is I suppose a temporary file?
My question is, has anyone had a similar error and how was it resolved?
Keep Only one in master page
Remove all the form tag from content page,
as well as head and body tag from content page.
and most importantly keep all the controls inside the content place holder that will be rendered inside form tag.
put run at server in all asp controls.
Do you have another form inside of your content page (which uses your master page)? You should have a form which runs at server only in your masterpage. Search your project (ctrl + shift + f) for
Check your MasterPage and make sure all controls with a runat="server" are contained within the <form runat="server"> element.
When building a custom control, how would you access the content between the opening and closing control tags?
<my:tag runat="server">
<p>...markup</p>...
</my:tag>
I am currently successfully using the Render method to output arbitrary markeup, but cannot seem to find out how to access the contained markup.
Take a look at this.Controls. This article :
http://msdn.microsoft.com/en-us/library/system.web.ui.control.controls(VS.71).aspx states "On an ASP.NET page, when controls are added declaratively between the opening and closing tags of a server control, ASP.NET automatically adds the controls to the containing server control's ControlCollection. "
As far as I understand, if you have
<yourcode:yourcontrol id="asdf" runat="server">
<p id="innerP" runat="server">Text here</p>
</yourcode:yourcontrol>
Then it would be possible to call this.FindControl("innerP").text="Other text here, since the P tag is generated on the server side.
However, if you do not have the runat="server" set on the P element:
<yourcode:yourcontrol id="asdf" runat="server">
<p id="innerP">Text here</p>
</yourcode:yourcontrol>
then you only can only find it through this.controls[0] since all the content will be rendered into a single Literal control.
I think you want to do this:
<my:tag runtat="server">
<p><asp:Label id="markupLabel" runat="server"/></p>
</my:tag>
And from the code-behind
markupLabel.text = "Foo";
If you add an ID to the my:tag tag, you should be able to access the controls inside of it using the .Controls collection of the tag.
I have a master page with one form on it. It is a search form which must always be visible. When the button of that form is clicked I want the form data to be sent to search.aspx. The problem is, I don't know how. I cannot set the form action to search.aspx, because all my other pages which use the master form will go to search.aspx. This I don't want.
Hope someone can help me out :)
Thnx.
In order to pass the values of the control "txtSearch", when Server.Transfer is executed, you could do many things, including passing it via a querystring variable or setting up a session variable, and then check either of those in the Page_Load event of Search.aspx, and if it's populated, call the event that is fired when the user would hit the submit button on the Search.aspx page.
Also, if the Search.aspx file is using the same masterpage, then you can use this.Master.FindControl("txtSearch") to get the control (it you look a the source of the file after it is generated in the browser, you'll notice that controls in the master page aren't really called by their ID, rather that have something appended to them (i.e. it would now possibly be called "ctl00_txtSearch")
You could create your search form in a separate form, and get it to use GET instead of POST.
Either that, or have the master form handle the search button click and use Server.Transfer to go to the search form.
You can have multiple forms in one page I believe. So one form (your search form) would have its action set to search.aspx and the other would be set for the page itself.
ASP.NET webform pages only have one form (which would generally be included on the master page). You can set the postback url for the search button to your search page..
<asp:Button ID="btnSearch" runat="server" Text="Search" PostBackUrl="~/search.aspx" />
..or just redirect to it from the handler in your master page like this:
protected void btnSearch_Click(object sender, EventArgs e)
{
Response.Redirect(#"~/search.aspx?q=" + Server.UrlEncode(txtSearch.Text));
}
..or use Server.Transfer as suggested by David Kemp.
Note: If you use Request.Query[#"q"] on your search page to get your query, you don't need to use Server.UrlDecode() - it's done for you.
I would:
Add some code to the master page code-behind to detect the source of the POST.
Once I have the source of the POST (e.g. the Search box). I would then pass its query to the Search form.
I used a similar process with having a HTML login form on the master page.
I posted a question and subsequent solution here - check it out:
Form Elements in ASP.NET Master Pages and Content Pages
Once I got my head round it, it seemed a pretty simple and reasonably elegant solution.
The benefit of this is that you have complete control over how the data is sent to the search form. And you don't need to enable transfer of form data to the search form and all that nasty stuff, just create a new GET request to the search page and let it do what it is supposed to do :)
Hope this helps.
NOTE:
You can only have one form with runat="server" on an ASPX page. Additional forms MUST be HTML FORMS.
Because your search form is in the master page, you can probably structure it to contain 2 forms. Place the search form tags with the action set to "search.aspx" outside of the tag that is used by the rest of the site.
<body>
<form action="search.aspx>
<!--search box and submit button-->
</form>
<form runat="server">
<!--rest of page inc placeholder-->
</form>
</body>
If the structure of the page will not enable this, you can set the submit button's PosbackUrl to point to "search.aspx". In this case, "search.aspx" would need to be coded to look in the PreviousPage property for the form data, or use Request.Form to access the input.