MVC and Entity Framework : Unable to retrieve the metadata for the model

Let’s say you are developing an MVC application and you want to add a generated controller with the associated views.

You do this:

  1. Setting the controller’s name
  2. Choosing the template: mvc controller with read/write actions and views, using Entity Framework
  3. Choosing the model class
  4. Choosing the data context
  5. Clicking “Add”

image001

It’s possible that you get this error:

image002

The solution is quite simple:

Just go in the web.config file and comment the connection string

image004

Then try again

image005

It works!

Don’t forget to uncomment your connection string and you are done.

Incoming search terms:

  • unable to retrieve metadata for model class
  • MVCandEntityFramework:Unabletoretrievethemetadataforthemodel
  • unable to retrieve metadata for
  • unable to retrieve metadata for model
  • unable to retrieve metadata for mvc
  • unable to retrieve metadata
  • entity framework unable to retrieve metadata
  • asp net mvc unable to retrieve metadata
  • mvc unable to retrieve metadata
  • yhs-fullyhosted_003

A simple local storage explorer

When building web apps using the html5 local storage, it’s sometimes hard to check what is actually stored in the browser’s local storage

Of course the chrome resources explorer is nice, but there is no formatting when we want to see datas stored as json

And the technique used to see what’s in the local storage is not the same in all browsers

So I ended up with creating a small html page using some javascript projects such as jQuery, highlight and vkbeautify

It’s not really beautiful, but I think it might be helpful

You can download it here if you want to use it :Â http://www.sambeauvois.be/codes/20120611.sbe.LocalStorageExplorer.zip

Incoming search terms:

  • active localstorage in ie
  • chrome storage explorer
  • localstorage in ie and chrome
  • storage itvds local
  • vkbeautify
  • yesterday3kb

Simple proxy to bypass cors

CORS is a pain in the ass, all works great with chrome and firefox,but, as often, internet explorer doesn’t (it should work with ie 10 but you know…)

So the proxy solution is simple and works, even if I would prefer a full html/jquery solution.

To create a proxy for the get requests it’s simple.

Create an asp.net webform, add this in the pageload.


protected void Page_Load(object sender, EventArgs e)
{
 string serviceUrl = HttpContext.Current.Request.Params["service"];
 if (string.IsNullOrEmpty(serviceUrl))
 {
  return;
 }

 string query = string.Empty;
 int firstParamIndex = HttpContext.Current.Request.Url.Query.IndexOf('&');

 if (firstParamIndex > -1)
 {
  query = HttpContext.Current.Request.Url.Query.Remove(0,firstParamIndex+1);
 }

 string service = serviceUrl + "?" + query;

 WebClient client = new WebClient();

 foreach (string headerKey in HttpContext.Current.Request.Headers.Keys)
 {
  try
  {
    client.Headers[headerKey] = HttpContext.Current.Request.Headers[headerKey];
  }
  catch (Exception ex)
  {
    System.Diagnostics.Debug.WriteLine(ex.Message);
  }
 }

 // specify encoding : avoid special characters to be unrecognized.
 client.Encoding = Encoding.UTF8;
 string resultString = client.DownloadString(service);

 // carriage returns.
 Response.Write(resultString.Replace(@"\u000d\u000d", "<br/>"));
}

you can restrict some headers this way


protected void Page_Load(object sender, EventArgs e)
{
 string[] allowedHeaders =
 {
  "x-headers1",
  "x-headers2",
  "x-headers3"
 };

 string serviceUrl = HttpContext.Current.Request.Params["service"];
 if (string.IsNullOrEmpty(serviceUrl))
 {
  return;
 }

 string query = string.Empty;
 int firstParamIndex = HttpContext.Current.Request.Url.Query.IndexOf('&');

 if (firstParamIndex > -1)
 {
 query = HttpContext.Current.Request.Url.Query.Remove(0,firstParamIndex+1);
 }

 string service = serviceUrl + "?" + query;

 WebClient client = new WebClient();

 foreach (string headerKey in HttpContext.Current.Request.Headers.Keys)
 {
  if (allowedHeaders.Contains(headerKey))
  {
   try
   {
     client.Headers[headerKey] = HttpContext.Current.Request.Headers[headerKey];
   }
   catch (Exception ex)
   {
     System.Diagnostics.Debug.WriteLine(ex.Message);
   }
  }
 }

 // specify encoding : avoid special characters to be unrecognized.
 client.Encoding = Encoding.UTF8;
 string resultString = client.DownloadString(service);

 // carriage returns.
 Response.Write(resultString.Replace(@"\u000d\u000d", "<br/>"));
}

In your web client :


if (jQuery.support.ajax)
{
 $.ajax({
 headers:
 {
  "x-headers1": "header value 1",
  "x-headers2": "header value 2",
  "x-headers3": "header value 3"
 },
 contentType: "application/json; charset=utf-8",
 dataType: "json",
 url: "youpage.aspx?service=yourservicecompleteurl",
 data:
 {
  param1: value1,
  param2: value2
 },
 success: function (msg)
 {
  callback(msg);
 },
 error: function (errormsg)
 {
  if (errorCallback != 'undefined')
  {
  errorCallback(errormsg);
  }
 }
 });
 }
 else
 {
  alert('You browser doesnt support ajax.');
 }

I could use a webservice, but it would force me to do POST requests and I doesn’t want to make changes in my jscripts.

[Update 20120405 ]

Here is the full proxy code, which handles both get and post requests :


using System;
using System.Linq;
using System.Web;
using System.Text;
using System.Net;
using System.IO;

namespace yournamespace
{
 public partial class Proxy : System.Web.UI.Page
{
/// <summary>
/// Definition of the headers to transfer.
/// </summary>
private static string[] requiredHeaders =
{
"x-your-required-header-1",
"x-your-required-header-2",
"x-your-required-header-3",
"Content-type"
};

/// <summary>
/// Overrides the onload event to handle get and post requests.
/// </summary>
/// <param name="e"></param>
protected override void OnLoad(EventArgs e)
{
bool isPost = string.Equals(HttpContext.Current.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase);
string serviceUrl = HttpContext.Current.Request.Params["service"];
if (string.IsNullOrEmpty(serviceUrl))
{
return;
}

string service = serviceUrl + (isPost ? "" : "?" + GetQuery());
WebClient client = new WebClient();

// copy required headers
foreach (string headerKey in HttpContext.Current.Request.Headers.Keys)
{
if (requiredHeaders.Contains(headerKey))
{
try
{
client.Headers[headerKey] = HttpContext.Current.Request.Headers[headerKey];
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
}

// specify encoding : avoid special characters to be unrecognized.
client.Encoding = Encoding.UTF8;
string resultString = string.Empty;
try
{
if (isPost)
{
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");

using (MemoryStream str = new MemoryStream())
{
HttpContext.Current.Request.InputStream.CopyTo(str);
byte[] result = client.UploadData(service, str.ToArray());
resultString += Encoding.UTF8.GetString(result);
}
}
else // GET
{
resultString = client.DownloadString(service);
}
}
catch (WebException wex)
{
System.Diagnostics.Debug.Write(wex);
resultString = "<h1>An error occured : " + wex.Message + "</h1>";
resultString += "<br/>Status : " + wex.Status;
if (wex.Status == WebExceptionStatus.ProtocolError)
{
HttpWebResponse httpResponse = wex.Response as HttpWebResponse;
if (httpResponse != null)
{
resultString += string.Format("<br/>Status Code : {0}", httpResponse.StatusCode);
resultString += string.Format("<br/>Status Description : {0}", httpResponse.StatusDescription);
}
}
resultString += "<br/><br/>Requested service : " + service;
}
catch (Exception ex)
{
System.Diagnostics.Debug.Write(ex);
resultString = "<h1>An error occured : " + ex.Message + "</h1>";
resultString = ex.GetFullMessage();
resultString += "<br/><br/>requested service : " + service;
}
finally
{
client.Dispose();
}
Response.Clear();
Response.Write(resultString);
}

/// <summary>
/// Gets the query part.
/// </summary>
/// <returns></returns>
private static string GetQuery()
{
string query = string.Empty;
int firstParamIndex = HttpContext.Current.Request.Url.Query.IndexOf('&');
if (firstParamIndex > -1)
{
query = HttpContext.Current.Request.Url.Query.Remove(0, firstParamIndex + 1);
}

return query;
}
}
}

Incoming search terms:

  • cors proxy
  • bypass cors jquery
  • corsproxy
  • how to bypass cors
  • bypass cors
  • CORS and proxy
  • use proxy to support browser that doesnt support cors
  • bypass chrome cors
  • avoid cors proxy
  • ajax cors request behind client proxy

Dynamic is magic : A solution to use the ASP.NET profile in web applications.

Profiles are not auto generated with Web Applications, so you can’t just add them in the web.config and use them directly. (unless …)

The WebSite project do a magic thing : when you add properties to the profile in the web.config file, a class is autogenerated and allow the developer to access these properties. The web application project don’t do that.

You can find some workarounds over the web, here is some

The “dynamic” keyword help us here.

So, no more chit chat, here is the code snippets for a profile with 3 parameters : LastName, FirstName and GSM

web.config:


<profile enabled="true">
 <providers>
 <clear/>
 <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="MyApp"/>
 </providers>
 <properties>
 <add name="FirstName" type="string"/>
 <add name="LastName" type="string"/>
 <add name="GSM" type="string"/>
 </properties>
 </profile>

A “business” class, I called it “ProfilePresenter”, it returns the profile of the logged user and allow modifications:


public class ProfilePresenter
{
 public dynamic GetProfile()
 {
 return HttpContext.Current.Profile;
 }
 public dynamic UpdateProfile(string FirstName, string LastName, string GSM)
 {
 HttpContext.Current.Profile.SetPropertyValue("FirstName", FirstName);
 HttpContext.Current.Profile.SetPropertyValue("LastName", LastName);
 HttpContext.Current.Profile.SetPropertyValue("GSM", GSM);
 HttpContext.Current.Profile.Save();
 return HttpContext.Current.Profile;
 }
}

A page that uses the ProfilePresenter class : displaying the profile properties, and edit them

ObjectDataSource:


<asp:ObjectDataSource runat="server" ID="ProfileODS" TypeName="Board.Presenters.ProfilePresenter"
 SelectMethod="GetProfile" UpdateMethod="UpdateProfile"/>
<pre>

FormView: Display part

 <asp:FormView runat="server" ID="ProfileFV" DataSourceID="ProfileODS" RenderOuterTable="false">
 <EmptyDataTemplate>
 <p>
 No profil datas
 </p>
 </EmptyDataTemplate>
 <ItemTemplate>
 <h2>
 Profil informations</h2>
 <div>
 <asp:Button runat="server" ID="Edit" CommandName="Edit" Text="Edit" /></div>
 <table>
 <thead>
 <tr>
 <th colspan="2">
 Infos
 </th>
 </tr>
 </thead>
 <tbody>
 <tr>
 <th>
 LastName
 </th>
 <td>
 <%# Eval("LastName")%>
 </td>
 </tr>
 <tr>
 <th>
 FirstName
 </th>
 <td>
 <%# Eval("FirstName")%>
 </td>
 </tr>
 <tr>
 <th>
 GSM
 </th>
 <td>
 <%# Eval("GSM")%>
 </td>
 </tr>
 </tbody>
 </table>
 </ItemTemplate>

FormView : the Edit part

 <EditItemTemplate>
 <h2>
 Profil Update</h2>
 <div>
 <asp:Button runat="server" ID="Edit" CommandName="Cancel" Text="Annuler" />
 <asp:Button runat="server" ID="Button1" CommandName="Update" Text="Sauver" /></div>
 <table>
 <thead>
 <tr>
 <th colspan="2">
Infos
 </th>
 </tr>
 </thead>
 <tbody>
 <tr>
 <th>
 LastName
 </th>
 <td>
 <asp:TextBox runat="server" ID="LastName" Text='<%# Bind("LastName")%>' />
 </td>
 </tr>
 <tr>
 <th>
 FirstName
 </th>
 <td>
 <asp:TextBox runat="server" ID="FirstName" Text='<%# Bind("FirstName")%>' />
 </td>
 </tr>
 <tr>
 <th>
 GSM
 </th>
 <td>
 <asp:TextBox runat="server" ID="GSM" Text='<%# Bind("GSM")%>' />
 </td>
 </tr>
 </tbody>
 </table>
 </EditItemTemplate>
 </asp:FormView>

A simple use :


dynamic profil = HttpContext.Current.Profile;
if (profil != null)
{
 Console.Writeline(profil.GSM);
}

Another example : retrieve the gsm numbers from  members of a security role. It shows how to retrieve the profile of an other user


string[] users = Roles.GetUsersInRole(role);

List<string> gsm = new List<string>();
foreach (string user in users)
{
 dynamic profil = HttpContext.Current.Profile;
 dynamic profi = profil.GetProfile(user);
 if (profi != null)
 {
 if (!string.IsNullOrEmpty(profi.GSM))
 {
 gsm.Add(profi.GSM);
 }
 }
}

Let me know what you think !