Spent several hours figuring our what was going wrong with my ajax calls. After the initial ajax call to a controller method that returns a JSONResult, the subsequent calls weren't even hitting the controller code. This was working fine in Chrome all along.
I moved my asp.net app from a Win 2003 Server to a Win 2008 Server running IIS7 and I started getting Permission denied for "System.Web.AspNetHostingPermission" errors for my .ascx files.
Turns out that you have to set the "Load User Profile" for the specific application pool to True. That took care of the issue.
LocalDb - introduced around the Sql 2012 RC release is a geared toward developers and dev machines. Acting much like Sql Express simplifies development, without having to maintain a full blown Sql express instance. Localdb is spawned on demand via Visual studio without having to keep a SQL process/service running in the background all the time - adding a little more processing power to dev machines.
You can connect to the LocalDb instance like this - (LocalDb)\v11.0
Read more about LocalDb - http://blogs.msdn.com/b/sqlexpress/archive/2011/07/12/introducing-localdb-a-better-sql-express.aspx
While using Code first in EF 4.3 the default generated db name will look like your namespace something.datacontext.
To change this behavior and use a custom name:
public class StockWatchDataContext:DbContext
{
public StockWatchDataContext(): base("StockWatch") //add your db name and override the base constructor
{ }
public DbSet Security { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove();
}
}
Also make sure that you are not using localdb as the db server instance or you wont see that in SQL management studio.
Tried almost everything to get some JSON from YQL and just could not loop through the items. What worked was to parse the JSON using JSON.parse(jsondata). No problems there after.
var getStockQuote = function () {
var url = "/api/stockquote/sd";
$.getJSON(url, function (data) {
var json = JSON.parse(data);
$.each(json.query.results, function (i, results) {
formatting.updateSecurity(results);
});
});
Apparently you will need to run the exe for Sql Server 2008 SP2 to upgrade you Sql 2008 Express instances to SP2. The installer for the express SP2 editions will only let you create a new instance, but not upgrade an existing instance.
SQL server has two functions EncryptByPassPhrase and DecryptByPassPhrase which encrypt/decrypt data with a passphrase using a TripleDES algorithm with a 128 bit key.
Leaving the question of weather this is a good practice or not, there is a way to have multiple submit buttons on a single form. Clicking on any of the buttons will post to the same action, so how do you tell which one was clicked.
On your View:
[HttpPost]
public ActionResult Profile(Model model,string submitButton)
{
Member member = new Member();
switch (submitButton)
{
case "Save1": //do something;
break;
case "Save2": //do something;
break;
}
return View(model);
}
In one of my projects I needed to dynamically display fields to enter information for a collection of objects. Specifically speaking I had a POCO "User" class with FK to a POCO "Child" class. I needed a way to generate text boxes based on how many kids a user had. This involves several steps and here's what I had to do.
1. Create a partial view with the fields you need to capture the info for a "Child"
@{
var seed = ViewBag.Seed;
@{
@*MVC renders fields for a collection by appending an index, which I am setting up below*@
var ageIdText = "Children_" + seed + "__Age";
var ageNameText = "Children[" + seed + "].Age";
var genderIdText = "Children_" + seed + "__Gender";
var genderNameText = "Children[" + seed + "].Gender";
var deleteIdText = "Children_" + seed + "__Delete";
var deleteNameText = "Children[" + seed + "].Delete";
}
Remove
}
MVC renders controls for collections by attaching an index for the collection. I had to code this in to render based on the number of controls that need to be displayed. Ex: the age text field will be Children_[1]__Age and so forth. I will explain the reason for having a delete field a little later.
2. Create an action in the controller that will return the partial view
public ActionResult RenderChildren(int? id, int? seed, string viewType)
{
//if no of children to be rendered in the view was not send in the request url, then render only one child
if (id.HasValue)
ViewBag.Children = id;
else
ViewBag.Children = 1;
//if the collection index was not indicated, then start rendering the controls from 0.
//This will come in handy when there are already controls on the page and we want to add more.
if (seed.HasValue)
ViewBag.Seed = seed;
else
ViewBag.Seed = 0;
return PartialView(viewType);
}
It is important to keep track on the index for the collection, or you will get unexpected results.
3. Create the javascript that will call the action above from another control. ex: onclick event of a link that should add the control for adding a "Child"
function addChild(method,container,type) {
var noofChild = $(container).find('.mark-for-delete').length;
$.get('/account/'+method+'?seed=' + (noofChild)+"&viewtype="+type, function (template) { $(container).append(template); });
}
function deleteChildren(element, deleteElement) {
$container = $(element).parent();
$container.find(deleteElement).val('True');
$container.hide();
}
This will take care of dynamically rendering the required number of fields for "Child"
5. Handling the deletes - I also needed to provide the user to delete existing fields
To handle the delete I need some more javascript code that will add some value to the hidden field that I added to my partial view. This value can then be picked up via the model while updating the database. I do have a property in the "Child" POCO class for setting the delete value. This field is not mapped to the database.
It's awesome that WCF support all the different bindings and protocols. Connect with multiple apps running different protocols all with the same code. Here's a list of all the different bindings that WCF support. I snagged this from - http://msdn.microsoft.com/en-us/library/bb310550.aspx. This link is a highly recommended read - has info on speed comparisons etc.
Bindings
Description
BasicHttpBinding
A binding that is suitable for communication with WS-Basic Profile conformant Web Services like ASMX-based services. This binding uses HTTP as the transport and Text/XML as the message encoding.
WSHttpBinding
A secure and interoperable binding that is suitable for non-duplex service contracts.
WSDualHttpBinding
A secure and interoperable binding that is suitable for duplex service contracts or communication through SOAP intermediaries.
WSFederationHttpBinding
A secure and interoperable binding that supports the WS-Federation protocol, enabling organizations that are in a federation to efficiently authenticate and authorize users.
NetTcpBinding
A secure and optimized binding suitable for cross-machine communication between WCF applications
NetNamedPipeBinding
A secure, reliable, optimized binding that is suitable for on-machine communication between WCF applications.
NetMsmqBinding
A queued binding that is suitable for cross-machine communication between WCF applications.
NetPeerTcpBinding
A binding that enables secure, multi-machine communication.
MsmqIntegrationBinding
A binding that is suitable for cross-machine communication between a WCF application and existing MSMQ applications.
You can use Winrar to create self-executing installer from the msi's and setup files you create from a Visual Studio Setup project.
Here are the steps:
1. Put your MSI and exe files in a folder.
2. Right click folder and select "Add to Archive"
3. Make sure that the archive format is set to "RAR" and check "Create SFX Archive" and "Create Solid Archive". The archive name extension automatically changes to ".exe"
4. Click on the "Advanced" tab and click on the "SFX Options" button.
5. In the "Advanced SFX Options" dialog - enter the path name to your .exe file. In my case "\Program\Setup.exe".
6. Click on the "Modes" tab and select "Hide all" under "Silent Mode" radio button group.
7. Click on Update tab. I set the "Overwrite All Files" as my overwrite mode. This will replace all install files.
8. To set an icon to your installer, click on the "Text and Icon" tab and set your options
9. Click OK on both the open dialogs and you'll have your self-extracting exe
There are several other options you can change based on your needs.
I ran into an interesting situation on a site using forms authentication, where the user had to be logged into both a domain and its subdomain once authenticated. Here's what I had to do to get this to work.
Both sites being seperate applications in themselves the authentication cookies generated by asp.net would be different due the encryption keys used by the sites. The Auth cookie generate by domain.com cannot be read by subdomain.domain.com. To get over this issue we need to add a machine key element in the web.config's of the both the apps. This key is going to be the same in both apps.
There are several different options in setting up these keys. Read more about it in this page. It also includes some code on how to generate a machine key using a console app - http://msdn.microsoft.com/en-us/library/ff649308.aspx
Once this is taken care of, the next issue we are going to have is the cookie itself. When a cookie is created - it is domain specific, so a cookie created by a sub domain will not be accessible to its parent level domain. In my case, the user authentication was to be performed on a subdomain using MVC. So I had to generate cookies for both the sub domain and domain upon authentication from my subdomain.
For Login
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
Account account = new Account();
//modify the Domain attribute of the cookie to the second level domain
HttpCookie MyCookie = FormsAuthentication.GetAuthCookie(model.UserName, model.RememberMe);
MyCookie.Domain = "domain.com";//the second level domain name
Response.AppendCookie(MyCookie);
string userName = account.GetUserName(model.UserName);
Session["ActualName"] = userName;
HttpCookie userCookie = new HttpCookie("IGNUS");
userCookie.Domain = "domain.com";
userCookie.Values["Name"] = userName;
if (model.RememberMe)
userCookie.Expires = DateTime.Now.AddDays(2);
Response.Cookies.Add(userCookie);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Member");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
If you are near the server you can just look around and find the Service Tag sticker. But, if you are logged in remotely here's how to get the service tag Type "wmic bios get serialnumber" into the command prompt and press enter.