passing optional parameter to GET method of ASP.NET API - c#

I am learning ASP.NET API. in the controller I have this methof for GET Verb
public HttpResponseMessage Get(string gender="All")
{
using (EmployeeDBEntities entities = new EmployeeDBEntities())
{
switch(gender.ToLower())
{
case "all":
return Request.CreateResponse(HttpStatusCode.OK, entities.Employees.ToList());
case "female":
case "male":
return Request.CreateResponse(HttpStatusCode.OK,
entities.Employees.Where(x=>x.Gender==gender).ToList());
default:
return Request.CreateErrorResponse(HttpStatusCode.NotFound, " value of gender is wrong");
};
}
}
when I browse to http://localhost:61491/api/Employees/gender=female , I recieve the following error:
<Error>
<Message>The request is invalid.</Message>
<MessageDetail>The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Net.Http.HttpResponseMessage Get(Int32)' in 'EmployeeService.Controllers.EmployeesController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.</MessageDetail>
</Error>
/**Edit
This is the web.config file of API Service
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="EmployeeDBEntities" connectionString="metadata=res://*/EmployeeDataModel.csdl|res://*/EmployeeDataModel.ssdl|res://*/EmployeeDataModel.msl;provider=System.Data.SqlClient;provider connection string="data source=localhost;initial catalog=EmployeeDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
</httpModules>
</system.web>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<remove name="ApplicationInsightsWebTracking" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />
</compilers>
</system.codedom>
</configuration>
what could be the reason?

Your code is fine. It's your url that is wrong:
http://localhost:61491/api/Employees/gender=female
I will give a quick solution as to what it should be, then give more details I highly recommend you read if you are learning APIs. Your URL should be:
http://localhost:61491/api/Employees?gender=female
With C# APIs you can send data in 3 possible ways:
Query Parameter
Route Parameter
In the Request Body
Query Parameters
This is the default type. Meaning if you don't specify the method it will always assume your inputs are query parameters. Not only that, but query parameters are by default optional and nullable. If you put in a null for a query parameter it will be assigned the default value.
Query parameters can be identified in a URL by the ? mark. Any data after that are query parameters and can be assigned in any order. For example:
MyUrl?Name=Jhon&Age=20&Sex=M
The & shows it's a split. The data above will map to the endpoint:
public HttpResponseMessage Get(string name, string sex, int age)
The paremeters can be in any order. It will map correctly.
Route Paremeters
These are queries taken directly from route. Adapting your request it will look like this:
/api/Employees/gender/female
And the endpoint itself will look as follow:
[HttpGet("gender/{sex}")]
public HttpResponseMessage Get([FromRoute] string sex) {...}
You can't by default use Route parameters, you will need to specify it is a route parameter by:
Putting the parameter in the route for the end point in brackets {}
Indicate with the [FromRoute] attribute that the api should use the route to get the attribute. By Default the route is required. You cannot use it as an optional parameter.
Body Parameters
This is simply you read the body of the request as a parameter. Good when you are posting or putting data Not going into too much detail but it will look as follow:
public HttpResponseMessage Get([FromBody] Model data) {...}
It is important to note that the [FromBody] parameters aren't compatible with Get requests.
Request Types
One important thing you will need to know is the request types. There are many but by default it will always be a Get request.
Your code:
public HttpResponseMessage Get(...) {...}
Is not a get reqest because you wrote GET. You can name that request whatever you like such as:
public HttpResponseMessage ThisIsMyPostRequest(...) {...}
But you will still be able to retrieve data using a GET request. The Specify what type of requests it is, you can add a http attribute tag:
[HttpGet]
public HttpResponseMessage MyGetFuncName(){...}
[HttpPost]
public HttpResponseMessage MyPostFuncName(){...}
[HttpPut]
public HttpResponseMessage MyPutFuncName(){...}
[HttpDelete]
public HttpResponseMessage MyDeleteFuncName(){...}
[HttpOptions]
public HttpResponseMessage MyOptionsFuncName(){...}
[HttpHead]
public HttpResponseMessage MyHeadFuncName(){...}
...
It is really that easy. The different HttpRequest mostly work the same. But there are a few differences. The most common used are GET, POST, PUT and DELETE.
This becomes usefull when say you want to use the same route but different functions. For example GET and DELETE can be on the same route:
/api/Employees/Byname?name=Jhon
but depending on the request type will either return the user or delete it.
Custom Routes
The last important and powerfull thing you will need to know is Routes. If I am not mistaken at the top of your controller page you have the following attribute:
[Route("[controller]")]
or
[Route("api/[controller]")]
What that function does is it ands a prefix to all of the requests on the controller. Now you can actually add this to individual functions as well. Meaning if you have multiple GET functions on a single page, this will be essential to keep it working properly. Example:
[Route("ByGenders")]
public HttpResponseMessage Get(string gender="All")
/api/Employees/ByGenders?gender=female
...
[Route("Byname")]
public HttpResponseMessage Get(string name)
/api/Employees/Byname?name=Jhon
But it can actually be combined with the HttpRequest attributes. Meaning the above will be equivalent to:
[HttpGet("ByGenders")]
public HttpResponseMessage Get(string gender="All")
[HttpGet("Byname")]
public HttpResponseMessage Get(string name)
Ofcourse you can put all of the above together into a unique endpoint with a lot of details. Below is a small example:
[HttpGet("GetWithParams/{requiredInput}")]
public IActionResult GetWithParams(
[FromRoute] string requiredInput,
[FromQuery] string optionalInput)
{
return Ok($"Required Input: {requiredInput} | Optional Input: {optionalInput}");
}
Or
[HttpPost("UserId/{id}")]
public IActionResult SubmitApplication(
[FromRoute] int id,
[FromBody] UserApplicationModel application)
{
return BadRequest();
}

Related

C# Entity Framework: Keyword not supported: 'port'

Hello I have more than one project connecting to a certain DB that is CodeFirst Entity Framework.
All Projects are able to connect successfully except for one stubborn one.
The error I am getting is: Keyword not supported: 'port'
I have looked through countless stackoverflow questions, mysql forums, entity framework forums etc. including:
MappingException Edm.String not compatible with SqlServer.varbinary
Keyword not supported in MySQL's connection string
Keyword not supported: 'metadata' + MySQL
My connection string looks like:
server=myservername;port=3306;uid=myaccount;database=mydb;pwd=mypwd123
My db.cs file looks like:
public partial class MyDB : DbContext
{
public MyDB ()
: base("server=myservername;port=3306;uid=myaccount;database=mydb;pwd=mypwd123")
{
Logger.Trace("test123");
}
public virtual DbSet<MyItem> MyItems {
get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyItem>()
.Property(e => e.Content)
.IsUnicode(false);
}
}
When I remove the port:3306 from the connection string I get this:
System.Data.Entity.Core.MappingException: Schema specified is not valid. Errors:
(8,12) : error 2019: Member Mapping specified is not valid. The type 'Edm.DateTime[Nullable=False,DefaultValue=,Precision=]' of member 'Time' in type 'something.Model.MyItem' is not compatible with 'SqlServer.timestamp[Nullable=False,DefaultValue=,MaxLength=8,FixedLength=True,StoreGeneratedPattern=Identity]' of member 'time' in type 'CodeFirstDatabaseSchema.MyItem'.
at System.Data.Entity.Core.Mapping.StorageMappingItemCollection.Init(EdmItemCollection edmCollection, StoreItemCollection storeCollection, IEnumerable`1 xmlReaders, IList`1 filePaths, Boolean throwOnError)
at System.Data.Entity.Core.Mapping.StorageMappingItemCollection..ctor(EdmItemCollection edmCollection, StoreItemCollection storeCollection, IEnumerable`1 xmlReaders)
at System.Data.Entity.ModelConfiguration.Edm.DbDatabaseMappingExtensions.ToStorageMappingItemCollection(DbDatabaseMapping databaseMapping, EdmItemCollection itemCollection, StoreItemCollection storeItemCollection)
at System.Data.Entity.ModelConfiguration.Edm.DbDatabaseMappingExtensions.ToMetadataWorkspace(DbDatabaseMapping databaseMapping)
at System.Data.Entity.Internal.CodeFirstCachedMetadataWorkspace..ctor(DbDatabaseMapping databaseMapping)
at System.Data.Entity.Infrastructure.DbCompiledModel..ctor(DbModel model)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
at System.Data.Entity.DbSet`1.Add(TEntity entity)
at MyFunction(Int32 userId, String id, String type, String contentJsonString) in
I am using MySql Connector and not Sql Server...
I am completely stumped by this as well as the rest of my team.
Edit:
Here is my Web.Config
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
</configSections>
<appSettings file="config-sources\app-settings.config"/>
<system.web>
<compilation debug="true" targetFramework="4.5.2">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<httpRuntime targetFramework="4.5.1"/>
</system.web>
<connectionStrings configSource="config-sources\ef-connection-strings.config"/>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MySql.Data" publicKeyToken="C5687FC88969C44D" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.8.3.0" newVersion="6.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-3.3.0.0" newVersion="3.3.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.2.29.0" newVersion="4.2.29.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="POST,HEAD,GET" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<security>
<requestFiltering>
<verbs>
<add verb="POST" allowed="true"/>
</verbs>
</requestFiltering>
</security>
<defaultDocument>
<files>
<add value="webhook.ashx"/>
</files>
</defaultDocument>
</system.webServer>
</configuration>
The argument of the used base DbContext constructor is called nameOrConnectionString. Hence it supports a name of a connection string from the configuration file, or like in your case an actual connection string.
The problem with the later is that it doesn't allow specifying the provider name as with the former coming from the configuration, in which case EF uses the one specified in the defaultConnectionFactory configuration element, which in your case is System.Data.Entity.Infrastructure.SqlConnectionFactory, in other words - Sql Server, hence the port not supported exception.
There are several ways to fix the issue.
(A) Change the defaultConnectionFactory configuration:
<defaultConnectionFactory type="MySql.Data.Entity.MySqlConnectionFactory, MySql.Data.Entity.EF6"></defaultConnectionFactory>
(B) Use named configuration connection string and specify explicitly the provider:
<connectionStrings>
<add name="MyDB" providerName="MySql.Data.MySqlClient" connectionString="server=myservername;port=3306;uid=myaccount;database=mydb;pwd=mypwd123" />
</connectionStrings>
and change the constructor to
public MyDB()
{
// ...
}
or if the name is different than your DbContext derived class name:
public MyDB() : base(connection_string_name)
{
// ...
}
(C) Use DbConfigurationTypeAttribute:
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class MyDB : DbContext
{
// ...
}
I had this problem whilst developing a Web Application on Core 2. I had to change the default database connection used from SqlServer to MySql in the Startup.cs file where the application is configured.
The error similar to the one listed above comes while working with ASP.net core and Database. The default database Provider with the ASP.net core is the SQL Server but, in case you are using a different provider for example, PostgreSQL and didn't correctly write or configure the DBContext code in the startup.cs
For example - Following code is written with an intent to connect to PostgresSQL then it will result in error ArgumentException: Keyword not supported: 'port'.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var connection = #"Server=localhost;Port=5432;Database=NewDB;User Id=xxxxx;Password=cr#aaaa;";
services.AddDbContext<BloggingContext>(options => options.UseSqlServer(connection));
// ...
}
And the reasons is user is trying to connect to PostgreSQL but did change the default Option UseSQLServer after configuring the PostgreSQL string.
To fix the issue change the option
options.UseSqlServer(connection)) -> options.UseNpgsql(connection))
I definitively solved the problem using the MySql Connector 8.0.x and following instructions on this link: https://davidsekar.com/asp-net/mysql-error-the-provider-did-not-return-a-providermanifesttoken.
in details:
Install MySql.Data.EntityFramework. Do not install Install MySql.Data.Entity!
Configure web.config / app.config in this way:
2.1. Change the <entityFramework> tag to <entityFramework codeConfigurationType="MySql.Data.EntityFramework.MySqlEFConfiguration, MySql.Data.EntityFramework">
2.2. Add/change the provider. It has to be: <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.EntityFramework" />
2.3. Connection string now can be server=myservername;port=3306;uid=myaccount;database=mydb;pwd=mypwd123
Open your DbContext's configuration class (if presente) and place the following code in it's constructor:
SetSqlGenerator("MySql.Data.MySqlClient" new MySql.Data.EntityFramework.MySqlMigrationSqlGenerator());
In my case, connection string with explicit port has to be delimited by ,.
E.g.: Data Source=123.45.123.45,1433;...
Sometimes it's the simplest thing. Mine was a copy-paste error when I missed the "Server=" at the beginning of the connection string.

Entity SetInitializer gets an SQL timeout

Using Entity's visual designer I have created the most basic entity possible. I want to seed some sample data to a database I created which holds the schema for this basic entity on Azure. I want to use this db in an asp.net web form but when I go to seed the init data I get an SQL timeout error.
I am aware that when using entities Database.SetInitializer the seed operation is only called when the context is used so I forced the initialization. It seems to try yet I still get the timeout. I created a basic console application and wrote a test program to load some values into the table and it worked fine so I know it is not the connection to the DB, it is something to do with the Seeding.
Here is the actual error:
A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in EntityFramework.SqlServer.dll
An exception of type 'System.Data.SqlClient.SqlException' occurred in EntityFramework.SqlServer.dll but was not handled in user code
Additional information: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Context File
namespace SlowTest.DB
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class ModelContainer : DbContext
{
public ModelContainer()
: base("name=ModelContainer")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Books> Books { get; set; }
}
}
Entity Class
namespace SlowTest.DB
{
using System;
using System.Collections.Generic;
public partial class Books
{
public int BookId { get; set; }
public string Author { get; set; }
}
}
Initializer
namespace SlowTest.DB
{
public class Init : DropCreateDatabaseAlways<ModelContainer>
{
protected override void Seed(ModelContainer context)
{
GetBooks().ForEach(c => context.Books.Add(c));
}
private static List<Books> GetBooks()
{
var B = new List<Books>
{
new Books{
BookId = 0,
Author = "Neville",
},
new Books{
BookId = 3,
Author = "Steve",
},
};
return B;
}
}
}
Global.asax.cs
namespace SlowTest
{
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Database.SetInitializer<ModelContainer>(new Init());
ModelContainer db = new ModelContainer();
db.Database.Initialize(true);
}
}
}
EDIT
Here is my web.config. Most of which is auto generated by visual studio or entity
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-SlowTest-20150812115338.mdf;Initial Catalog=aspnet-SlowTest-20150812115338;Integrated Security=True" providerName="System.Data.SqlClient" />
<add name="ModelContainer" connectionString="metadata=res://*/DB.Model.csdl|res://*/DB.Model.ssdl|res://*/DB.Model.msl;provider=System.Data.SqlClient;provider connection string="data source=uvic.database.windows.net;initial catalog=TrojanDB;persist security info=True;user id=nhoughto;password=Password;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.web>
<authentication mode="None" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<pages>
<namespaces>
<add namespace="System.Web.Optimization" />
<add namespace="Microsoft.AspNet.Identity" />
</namespaces>
<controls>
<add assembly="Microsoft.AspNet.Web.Optimization.WebForms" namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt" />
</controls>
</pages>
<membership>
<providers>
<!--
ASP.NET Membership is disabled in this template. Please visit the following link http://go.microsoft.com/fwlink/?LinkId=301889 to learn about the ASP.NET Membership support in this template
-->
<clear />
</providers>
</membership>
<profile>
<providers>
<!--
ASP.NET Membership Profile is disabled in this template. Please visit the following link http://go.microsoft.com/fwlink/?LinkId=301889 to learn about the ASP.NET Membership support in this template
-->
<clear />
</providers>
</profile>
<roleManager>
<!--
ASP.NET Membership Role is disabled in this template. Please visit the following link http://go.microsoft.com/fwlink/?LinkId=301889 to learn about the ASP.NET Membership support in this template
-->
<providers>
<clear />
</providers>
</roleManager>
<!--
If you are deploying to a cloud environment that has multiple web server instances,
you should change session state mode from "InProc" to "Custom". In addition,
change the connection string named "DefaultConnection" to connect to an instance
of SQL Server (including SQL Azure and SQL Compact) instead of to SQL Server Express.
-->
<sessionState mode="InProc" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
</providers>
</sessionState>
</system.web>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" culture="neutral" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" culture="neutral" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" culture="neutral" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" culture="neutral" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" culture="neutral" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
I know this is an old question, but in case anyone stumbles here from Google... you need to increase your CommandTimeout to give Azure enough time to create the db.
There is an incredibly detailed StackOverlow answer explaining why here:
Timeout when setting up Entity Framework connecting to Azure
The gist of it is that you need to add a single line into your DbContext constructor:
public MyContext() : base("name=MyContext")
{
// three minute command timeout
this.Database.CommandTimeout = 180;
}

Error controller not hit when using httpErrors in web.config

I am struggling to setup the httpErrors section correctly in my web.config to capture both ASP.NET MVC errors and IIS errors. I am getting 403 status codes and blank pages. I am testing with 404 errors by typing incorrect URLS and file names in the URL, for example:
www.mywebsite.com/test
www.mywebsite.com/test.html
I am using the latest version of ASP.NET MVC 5. This web application is running on IIS 7.5 with an application pool using integrated mode.
This is what my web.config looks like at the root of the application (this is all that I currently have):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="webpages:Version" value="3.0.0.0"/>
<add key="webpages:Enabled" value="false"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
<system.web>
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5.2"/>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<remove statusCode="500" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
<error statusCode="500" responseMode="ExecuteURL" path="/Error" />
</httpErrors>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed"/>
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
</dependentAssembly>
<!-- ...and so forth... -->
</assemblyBinding>
</runtime>
</configuration>
My global.asax.cs file:
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
protected void Application_Error()
{
// Break point has been set here for testing purposes
}
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 404)
{
// Break point has been set here for testing purposes
}
}
}
My error controller:
public class ErrorController : Controller
{
public ActionResult Index()
{
// Break point has been set here for testing purposes
Response.StatusCode = 500;
return View();
}
public ActionResult Forbidden()
{
// Break point has been set here for testing purposes
Response.StatusCode = 403;
return View();
}
public ActionResult NotFound()
{
// Break point has been set here for testing purposes
Response.StatusCode = 404;
return View();
}
}
They have their corresponding views in the Views folder.
My break points are never hit in my error controller. I don't understand why? I have looked at many examples on Stackoverflow and this is how every suggests that I do it. When would the break points not be reached given my code? All that happens is a 403 error status and a BLANK white page. The break points in Application_Error() and Application_EndRequest() are hit, but not the break points in the error controller.
There is code that I can write in Application_Error() and Application_EndRequest() that lets me set the error controller and action method, but why do that if I can use the web.config? This should also work?
Man, you have mentioned statusCode as 404 then how can you expect as 200 OK ? :)
just remove Response.StatusCode = 404; line from action method
Bellow code should work
public ActionResult NotFound()
{
return View();
}

404 not found error when locally testing web api

This is my first time trying to use the WEB API in a project and am not having any success with it...
I keep getting 404 errors when I try and reach my api route in Fiddler.
I tried looking a lot on the web and even here at the following link, but there are so many combinations, that I'm not sure what would work.
HTTP 404 Page Not Found in Web Api hosted in IIS 7.5
If somebody can please help me with this to get the right settings I would really appreciate it.
Here is my code:
Web.config file:
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=301879
-->
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="FuelTicketImageRetrievalSvc.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="AssignedGroup" value="FMS Maintenance Level 3" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
</system.web>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.serviceModel>
<bindings />
<client />
</system.serviceModel>
<applicationSettings>
<FuelTicketImageRetrievalSvc.Properties.Settings>
<setting name="FuelTicketImageRetrievalSvc_IncidentService_HPD_IncidentInterface_Create_WSService" serializeAs="String">
<value>http://miavsbremweb/arsys/services/ARService?server=miavsbremapp.ryder.com&webService=HPD_IncidentInterface_Create_WS</value>
</setting>
</FuelTicketImageRetrievalSvc.Properties.Settings>
</applicationSettings>
</configuration>
WebApiConfig.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace FuelTicketImageRetrievalSvc
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
Global.asax.cs file:
using FuelTicketImageRetrieval;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace FuelTicketImageRetrievalSvc
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
Controller method that I'm trying to call. It's just a dummy method that simply returns null with no parameters. It's name is FuelTicketImageRetrievalController:
public string GetSpecificFuelTicket()
{
try
{
return null;
}
catch (Exception ex)
{
return null;
}
}
The name of my project is called FuelTicketImageRetrievalSvc. I have verified through the web settings in the project that IIS Express is being used and is set to
http://localhost:11581/
url path call.
http://localhost:11581/FuelTicketImageRetrievalSvc/api/GetSpecificFuelTicket
You don't need FuelTicketImageRetrievalSvc in uri, it should work simply with /api/...
that's what your route matches, having svc name there causes it to not match.
You need to add your controller in the path and remove your project
http://localhost:11581/api/FuelTicketImageRetrieval/GetSpecificFuelTicket
You remove the Controller part when referencing it - the /FuelTicketImageRetrieval/ is from the FuelTicketImageRetrievalController not the project. Web API will auto add the controller back on the name when looking for the correct class.
For a quick guaranteed run (and sometimes preferred approach), add HTTP action prefix and route attributes before your method:
[HttpGet]
[Route("api/Products/SpecificFuelTicket")]
public string GetSpecificFuelTicket()
{
try
{
return null;
}
catch (Exception ex)
{
return null;
}
}
Now, you can access it using URL:
http://localhost:xxxx/api/products/SpecificFuelTicket
Points to note:
HTTPGet ensures that only Get action is mapped to this method
Route value ensures a direct mapping to a URL. As REST standard, "Get", "Delete" etc.. are not used as prefix in URL. The HTTP action is used for that.
Some methods are automatically mapped to suitable URLs, but since your class name is "FuelTicketImageRetrievalController" and method name is "GetSpecificFuelTicket", it is not trivial.
Returning null is not an issue. it is returned serialized as "null".
For your another question to Charles, if you want to use URL "localhost:xxxx/api/GetSpecificFuelTicketAsync/6460194", and your method signature takes int, you can change the route prefix as following (again, not using "Get" in the route):
[HttpGet]
[Route("api/Products/SpecificFuelTicket/{value}")]
public string GetSpecificFuelTicket(int value)
{
try
{
return "Your ticket is " + value.ToString();
}
catch (Exception ex)
{
return null;
}
}
However, as Charles suggested, using "api/Products/SpecificFuelTicket?value=6460194" format is perhaps better. Any parameter name in the method is automatically mapped to similar name query parameter. So, your method'd look like:
[HttpGet]
[Route("api/Products/SpecificFuelTicket")]
public string GetSpecificFuelTicket(int value)
{
....
}
For, a detailed understanding of URL mapping and routing web-API, refer to link:
Attribute Routing in Web API 2
Routing and Action Selection
I originally had a 404 error when I added WebApi support to my Mvc solution.
My global.asax.cs contained the lines:
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configure(WebApiConfig.Register);
What I found is that when I changed he WebApiConfig line, so that the code block became:
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
it fixed my problem

Inserting a new record updates LocalDB but not SQL server DB

I'm following MVC-Movies tutorial here , and I'm trying to update the records on SQL Server
and NOT on LocalDB .
When I add a new record in my program , for example :
The DB in SQL Server is not updated , only the LocalDB is .
Here is Web.config :
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=301880
-->
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=localhost;
AttachDbFilename=|DataDirectory|\aspnet-MvcMovie-20140418101450.mdf;
Initial Catalog=aspnet-MvcMovie-20140418101450;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="MovieDBContext"
connectionString="Data Source=(LocalDB)\v11.0;
AttachDbFilename=|DataDirectory|\Movies.mdf;
Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<authentication mode="None" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<modules>
<remove name="FormsAuthenticationModule" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
Where did I go wrong ?
Name of my DB in sql server is : MoviesDB
Thanks
EDIT:
Class Movie and MovieDBContext :
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
namespace MvcMovie.Models
{
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
public class MovieDBContext : DbContext
{
public DbSet<Movie> Movies { get; set; }
}
}
EDIT 2 :
I changed the connection string to
<add name="MovieDBContext"
connectionString="Data Source=localhost;
AttachDbFilename=|DataDirectory|\Movies.mdf;
Initial Catalog=MoviesDB;
Integrated Security=True"
providerName="System.Data.SqlClient" />
But then I get this :
Server Error in '/' Application.
Invalid value for key 'attachdbfilename'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: Invalid value for key 'attachdbfilename'.
Source Error:
Line 18: public ActionResult Index()
Line 19: {
Line 20: return View(db.Movies.ToList());
Line 21: }
Line 22:
Source File: c:\Users\X3\Documents\Visual Studio 2013\Projects\MvcMovie\MvcMovie\Controllers\MoviesController.cs Line: 20
Neither one of your connection strings there are referencing MoviesDB.
One is referring to aspnet-MvcMovie-20140418101450.mdf and the other Movies.mdf.
Your context will use the connection string that matches it's name, unless you override that setting. So you should modify the MovieDBContext connection string to point to your SQL instance instead of the LocalDB
Edit
I assume that this is similar to the connection string you actually want, but you should refer to the official Microsoft Reference for other examples.
<add name="MovieDBContext" providerName="System.Data.SqlClient"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=MoviesDB;
Integrated Security=True"/>
Change to :
<add name="MovieDBContext"
connectionString="Data Source=localhost;
AttachDbFilename=|DataDirectory|\MoviesDB.mdf;
Initial Catalog=MoviesDB;
Integrated Security=True"
providerName="System.Data.SqlClient" />

Categories