Wednesday, June 24, 2015

@RenderBody is a must in _Layout.cshtml otherwise error is thrown : The "RenderBody" method has not been called for layout page "~/Views/Shared/_Layout.cshtml".

 
Yes, RenderBody should be included on every layout page, regardless the nesting.
@RenderBody works as a placeholder for the engine to know where to drop the content of the view using the layout page.


http://stackoverflow.com/questions/18323268/renderbody-and-rendersection-must-be-on-every-child-layout

Sunday, February 2, 2014

Requirements for using EF in a layered project

A layered project will typically have EF model in different project
and UI and other logic in different projects. There are some wierd things
required to do this.



Steps to be followed when accessing EF model in a different project.

1. Add a reference to "System.Data.Entity" in the refering project.
2. Add the following line to web.config of refering application
 <add assembly="System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
This is required in addition to step 1 above.
3. Add the same connection string in refering project as that of the
refered project.
4. In both the connections, change the file path to actual full path.



=============================================================
A TUTORIAL FOR THE ABOVE
=============================================================

1. Create a new mvc app, say MvcApplication1.

2. Create a new class lib project, say ClassLibrary1.

3. Add a new "Service Based Database"  to class library project, say Database1.mdf.

4. Add a new table to the .mdf file, say "Table1". Create some fields and add a couple of rows.

5. Add new ADO.NET Entity Data Model, say "Model1.edmx" and generate it from database.
   By default, it will create "Database1Entities" and corresponding connection string.
   For now, do not touch the connection string.
   Accept the defaults and go ahead.
6. In the default class, now add a method to return all records from table1 :

namespace ClassLibrary1
{
    public class Class1
    {
        public List<Table1> GetTable1()
        {
            return (new Database1Entities()).Table1.ToList();
        }
    }
}

7. Build ClassLibrary1.

8. In MVCApplication1, access Class1.GetTable, may be in homecontroller.
namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewData["Message"] = "!";
            ClassLibrary1.Class1 cls = new ClassLibrary1.Class1();
            return View(cls.GetTable1());
        }

        public ActionResult About()
        {
            return View();
        }
    }
}

9. Now build solution and run.

10. The first error you will encounter will be :

The type 'System.Data.Objects.DataClasses.EntityObject' is defined in an assembly
that is not referenced. You must add a reference to assembly
'System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

To solve this error, right click MvcApplication1, and "Add Reference" to
"System.Data.Entity"

Build and run the project.

11. When you run the project, you will encounter next error:
"The specified named connection is either not found in the
configuration, not intended to be used with the EntityClient
provider, or not valid."

To solve this error, copy the connection string from class library's
app.config to MvcApplication's outer web.config.

(If there are two connection strings found in app.config,you have
to copy the one which has metadata information.)

Build and run the project.

12. When you run, you will encounter the following error:

"The underlying provider failed on Open.", with following InnerException:
"An attempt to attach an auto-named database for file
e:\Documents and Settings\rajesh\My Documents\Visual Studio 2008\Projects\MvcApplication1\MvcApplication1\App_Data\Database1.mdf failed.
 A database with the same name exists, or specified file cannot be opened, or it is located on UNC share."


This error is due the path of the mdf file, which MVC or ASP.NET normally try to find
in App_Data.

To solve this error, go to properties of mdf file and copy the
"Primary File Path".

Replace the path of the mdf file with this one in both places, i.e. class lib and mvc app.

Build and run the app.

13. Now when you run the code which accesses the library function,
you will get following error :


CS0012: The type 'System.Data.Objects.DataClasses.EntityObject' is
defined in an assembly that is not referenced. You must add a
reference to assembly
'System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

To solve this error, add the following line in the <assemblies> section of MvcApplication1 :

<add assembly="System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>


Build and run the app.

Everything should work as expected.

Tuesday, January 7, 2014

knockout options binding : setting intial value

Consider the knockout options binding. Take example 3 from the knockout documentation (http://knockoutjs.com/documentation/options-binding.html). Suppose in this example, we want to assign an initial selected value to, say country "USA".

I tried to modify the given sample as follows ( note the selectedCountry : it is given a default value below)

<p>
    Your country:
    <select data-bind="options: availableCountries, optionsText: 'countryName', value: selectedCountry, optionsCaption: 'Choose...'"></select>
</p>
 
<div data-bind="visible: selectedCountry"> <!-- Appears when you select something -->
    You have chosen a country with population
    <span data-bind="text: selectedCountry() ? selectedCountry().countryPopulation : 'unknown'"></span>.
</div>
 
<script type="text/javascript">
    // Constructor for an object with two properties
    var Country = function(name, population) {
        this.countryName = name;
        this.countryPopulation = population;
    };
 
    var viewModel = {
        availableCountries : ko.observableArray([
            new Country("UK", 65000000),
            new Country("USA", 320000000),
            new Country("Sweden", 29000000)
        ]),
        selectedCountry : ko.observable(this.availableCountries()[1]) // Nothing selected by default
    };
</script>


This does not work.

On the other hand, the following code (which uses function syntax to declare viewModel) perfectly works :


    <p>
    Your country:
    <select data-bind="options: availableCountries, optionsText: 'countryName', value: selectedCountry, optionsCaption: 'Choose...'"></select>
</p>

<div data-bind="visible: selectedCountry"> <!-- Appears when you select something -->
    You have chosen a country with population
    <span data-bind="text: selectedCountry() ? selectedCountry().countryPopulation : 'unknown'"></span>.
</div>

<script type="text/javascript">
    // Constructor for an object with two properties
    var Country = function(name, population) {
        this.countryName = name;
        this.countryPopulation = population;
    };

    var viewModel = function() {
        this.availableCountries = ko.observableArray([
            new Country("UK", 65000000),
            new Country("USA", 320000000),
            new Country("Sweden", 29000000)
        ]);
        this.selectedCountry = ko.observable(this.availableCountries()[1]);
    };

    ko.applyBindings(new viewModel());

</script>


This means that we have to find some better syntax in first approach to declare initial selection value !

Tuesday, November 5, 2013

wcf message security using certificates

=======================================================
WCF MESSAGE SECURITY USING CERTIFICATE PART 1 : SERVICE
=======================================================


1. Create a new Web Site.

2. Add a WCF web service to the site.

3. Change the DoWork function: (in both IService.cs and Service.cs)
string DoWork(int a)
{
return "You entered " + a.ToString();
}
4. In principle, following things are required to enable certificate
security at service level :
a. Define the security level : either transport or message
  This is defined in the binding configuration
b. Provide the certificate :
  This is done in ServiceBehaviors - ServiceCredentials tag.
c. Attach the above to Service.
  Attach message security by specifying bindingConfiguration in
  endpoint.
  Attach service certificate by specifying behaviorConfiguration
  in service.

4a.
<bindings>
      <wsHttpBinding>
        <binding name="mybind" >
          <security mode="Message">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

4b.
<serviceBehaviors>
        <behavior name="my">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceCredentials>
            <serviceCertificate findValue="CN=tempCert" storeLocation="LocalMachine" storeName="My"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>


5. Mex endpoint : this is extra; but may be required.
a. In service behavior :
    <serviceMetadata httpGetEnabled="true" />
b. In <service> tag, add another endpoint for mex:
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" ></endpoint>

6. The total config should now look like following :
 <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="mybind" >
          <security mode="Message">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="my">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceCredentials>
            <serviceCertificate findValue="CN=tempCert" storeLocation="LocalMachine" storeName="My"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
   
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <services>
      <service name="Service" behaviorConfiguration="my" >
        <endpoint address="" binding="wsHttpBinding" contract="IService" bindingConfiguration="mybind"></endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" ></endpoint>
      </service>
    </services>
  </system.serviceModel>

7. Run the web site with Service.svc open. You should see familiar blue/white WSDL screen for the service.
   The url of the page looks something like "http://localhost:4348/WebSite1/Service.svc"

======================================================
WCF MESSAGE SECURITY USING CERTIFICATE PART 2 : CLIENT
======================================================

1. Create a new web site.

2. Add a Label Label1 on default.aspx.

3. Add a service reference to the project.
Right click the project in solution explorer, select "Add Service Reference".
Copy and paste the url of the service from the page displayed in step 7 above.
        Click "Go" in the "Add Service Reference" dialog.
The service should be seen in "Services" pane of the dialog.
Click "OK" to add the reference.
4. Add the following code to Page_Load event of Default.aspx :
        ServiceReference1.ServiceClient svc = new ServiceReference1.ServiceClient();
        Label1.Text = svc.DoWork(4);

5. Run the project. You should get "InvalidOperationException" exception:
"The client certificate is not provided. Specify a client certificate in ClientCredentials."

6. To correct this error, you need to provide a certificate to the client.
   This done in the endpoint behavior.
   So you need to create an endpoint behavior and attach it to endpoint.

7.Here we will the same certificate as that of service, since we are trying this on the same machine.
Add the following to the <system.serviceModel> section:
   <behaviors>
      <endpointBehaviors>
        <behavior name="myb">
          <clientCredentials>
            <clientCertificate findValue="CN=tempCert" storeLocation="LocalMachine" storeName="My"/>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>

8. Attach this behavior to the endpoint specified in <client> tag.
The total configuration looks like following :

  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="myb">
          <clientCredentials>
            <clientCertificate findValue="CN=tempCert" storeLocation="LocalMachine" storeName="My"/>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
          <security mode="Message">
            <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
            <message clientCredentialType="Certificate" negotiateServiceCredential="true" algorithmSuite="Default"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:4348/WebSite1/Service.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService" contract="ServiceReference1.IService" name="WSHttpBinding_IService" behaviorConfiguration="myb">
        <identity>
          <certificate encodedValue="AwAAAAEAAAAUAAAAJdm3kjyo+3IINpRcCcL18xAHDJMgAAAAAQAAAPMBAAAwggHvMIIBXKADAgECAhAJcTbJKUQFrkBJG29u5jGAMAkGBSsOAwIdBQAwFTETMBEGA1UEAxMKUm9vdENBVGVzdDAeFw0xMzEwMjkxMzI1MTlaFw0zOTEyMzEyMzU5NTlaMBMxETAPBgNVBAMTCHRlbXBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsThCFbp8o2lRth4OHqTYUZzvh08fnkEn+mlVKiJwe1uBOcPSCummedCI2SOkH/pCFc6VRcJcSv77UL1fI8KcQbJWgNwwlikrjJxJfuzQT8I/3ECWCaE3iZRqHMqE31BNgQR/dp/mRo8U3KSUzkgnmS/pcceDO4TA/ZX3gB399CQIDAQABo0owSDBGBgNVHQEEPzA9gBCKdgxdb66XAzRBYr0zZTZMoRcwFTETMBEGA1UEAxMKUm9vdENBVGVzdIIQp+Iu4taQ8a9NIeWKlHq9YDAJBgUrDgMCHQUAA4GBAAKB8SfWcyTkFeOdfx1YEEfjqYRuwgZBn7eHEhCk6lxFi5OZLtxZfxULR0bSbd6F4QMBDlcHM0LFaf6SKJ6JCXZQ5dfBHzgcJJ5j+Okj59be9DrYIbunut5uMLWJAx+nIFCItxe4hw452U+DAKEOSHI83OANdzzbFgAckiwFheOu"/>
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>


9.Run the project. Now it should run without exception and should show a message like following on default.aspx:
"You enetered 4".




NOTE 1 : In both service and client, you can use "CN=" prefix in certificate, You then need not to specify x509FindType.
specifying "CN=" is equivalent to x509FindType="FindBySubjectName".

NOTE 2: In general the certificate should be valid. To check this, double click on the certicate in MMC.
In the "General" tab, look at the "Certificate Information". This information should not be something like certificate not trusted,
certificate expired, etc.

In one of the cases, a certificate was having this info (status) as
"This CA Root certificate is not trusted because it is not in the Trusted Root Certification Authorities store."

This certificate was placed in LocalMachine TrustedPeople.

The exception received was SecurityNegotiationException :
"The caller was not authenticated by the service."

NOTE 3: Also verify that the certificate is having a private key.
This can be verified on the "General" tab, at the bottom you should see a message like :
"You have a private key that corresponds to this certificate."


Tuesday, July 30, 2013

: One to many relationship and ObjectStateManager error

Understand basic navigation with Entity Framework Code First (4.3) with 1 to many relationship


Entity Framework 4.3: An object with the same key already exists in the ObjectStateManager
http://patrickdesjardins.com/blog/entity-framework-4-3-an-object-with-the-same-key-already-exists-in-the-objectstatemanager

Microsoft Links : MVC 3, MVC 4 tutorials

Table of Contents

MVC 4

·         ASP.NET MVC 4 Mobile Features
·         Bundling and Minification
·         Custom MVC Template

MVC Music Store

·         Part 2: Controllers
·         Part 3: Views and ViewModels
·         Part 4: Models and Data Access

Getting Started with EF using MVC

·         ASP.NET Data Access Content Map

Views

·         Dynamic v. Strongly Typed Views

Controllers and Routing

·         Creating Custom Routes (C#)
·         Creating Custom Routes (VB)

Security

JavaScript

Deployment

Getting Started with ASP.NET MVC3

Older Versions

·         Getting Started With MVC
·         Models (Data)
·         ASP.NET MVC Views
·         Controllers and Routing
·         Deployment
·         Security
·         Unit Testing
·         Contact Manager
·         NerdDinner
·         Movie Database
·         JavaScript
·         Overview

Hands On Labs

·         What's New in ASP.NET MVC 4
·         ASP.NET MVC 4 Fundamentals

MVC 5

·         Introduction to ASP.NET MVC 5