Tag Archives: C#

Dynamic Robots.txt with Web Api 2

Hi everyone,

For a project I’m currently working on I needed a dynamic robots.txt. Because our test environment is public facing we want to keep it from being indexed by Google etc. It took a bit of Googling to find a solution that worked, but in the end it was actually pretty simple.

Here’s the action in one of the API Controllers:

    public class UtilitiesController : CustomBaseApiController
    {
        [Route("Robots.txt")]
        [HttpGet]
        public HttpResponseMessage GetRobotsFile()
        {
            var resp = new HttpResponseMessage(HttpStatusCode.OK);
            var stringBuilder = new StringBuilder();
 
            if (Helpers.IsProduction())
            {
                // Allow bots in production
                stringBuilder.AppendLine("user-agent: *");
                stringBuilder.AppendLine("disallow: ");
            }
            else
            {
                // Don't allow bots in non-production environments
                stringBuilder.AppendLine("user-agent: *");
                stringBuilder.AppendLine("disallow: *");
            }
 
            resp.Content = new StringContent(stringBuilder.ToString());
 
            return resp;
        }
    }

Also need to add the following to your web.config so that the robots.txt file can processed by the routing handler. Without this IIS will attempt to serve it as a static file and will return a 404 when it’s not found:

<system.webServer>
    <modules>
    <!-- ... -->
        <handlers>
        <add name="RobotsTxt" path="robots.txt" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
        <!-- Other handlers -->
    </modules>
    <!-- ... -->
</system.webServer>

In production you’ll end up with the following:

user-agent: *
disallow:

And any other environments:

user-agent: *
disallow: *

Thanks to these answers on stackoverflow for the info:
https://stackoverflow.com/a/52270877/522859
https://stackoverflow.com/a/17037935/522859

Error Number:8152,State:10,Class:16 String or binary data would be truncated. The statement has been terminated. – Entity Framework

Hi everyone,

I ran into the following error after adding model validation attributes to a database with existing values:

Error Number:8152,State:10,Class:16
String or binary data would be truncated.
The statement has been terminated.

The solution is pretty straightforward if you’re happy to truncate the values. Simply run the query below, swapping Title for your column name, Products for your table name and 25 for your new column length:

UPDATE Products
SET Title = LEFT(Title, 25)
WHERE LEN(Title) > 25

You should then be able to run update-database without any issues:

PM> update-database
Specify the ‘-Verbose’ flag to view the SQL statements being applied to the target database.
Applying explicit migrations: [201806240741543_product_validation].
Applying explicit migration: 201806240741543_product_validation.
Running Seed method.
PM>

Thanks to David in for his answer on Stackoverflow: https://stackoverflow.com/a/24931522/522859

LINQ to Entities does not recognize the method ‘System.Linq.IQueryable

Hi everyone,

I ran into the following error today while attempting to use a raw query with entity framework:

LINQ to Entities does not recognize the method ‘System.Linq.IQueryable…method, and this method cannot be translated into a store expression

I was using FromQuery, and while I’m not too sure what was causing the issue, switching to SqlQuery resolved it:

// Original code
var carList = resp.Db.Cars.FromSql(“SELECT * FROM cars”);
// Changed code
var carList = resp.Db.Cars.SqlQuery(“SELECT * FROM cars”);

Hopefully that’s able to help out anyone else with the issue.

Thanks,
Chris

Web API 2 – ExceptionMessage=No MediaTypeFormatter is available to read an object of type ‘HttpPostedFileBase’ from content with media type ‘multipart/form-data’.

Hi everyone,

I ran into the following error while trying to get image uploads working with Web API 2:

ExceptionMessage=No MediaTypeFormatter is available to read an object of type ‘HttpPostedFileBase’ from content with media type ‘multipart/form-data’.

I had been trying to copy the following from an mvc controller in another project:

public IHttpActionResult Upload(HttpPostedFileBase file, Models.Image.ImageAssociationType associationType, int associationId)

The fix was to use the following instead:

public IHttpActionResult Upload(Models.Image.ImageAssociationType associationType, int associationId)
{
var file = HttpContext.Current.Request.Files.Count > 0 ? HttpContext.Current.Request.Files[0] : null;

Thanks to this stackoverflow post for the info: https://stackoverflow.com/a/28370156/522859

DbSet does not contain a definition for ‘FromSQL’ and no extension method ‘FromSql’ accepting an argument of type ‘DbSet‘ could be found.

Hi everyone,

I ran into the following error while attempting to use a custom query with EntityFramework:

DbSet does not contain a definition for ‘FromSQL’ and no extension method ‘FromSql’ accepting an argument of type ‘DbSet‘ could be found.

This one’s pretty straight forward:

// Install the following package via nuget
Install-package Microsoft.EntityFrameworkCore.Relational

//Add the following namespace to your file
using Microsoft.EntityFrameworkCore;

Hopefully that’ll solve it for you, but if not there’s a lot a more information in these posts:
https://stackoverflow.com/a/38919326/522859
https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/issues/146

Include UserId in Login Response (Token) – Web API 2

Hi everyone,

A quick post on how to include the user’s id in your login response when using Web API 2.

The default response to the /Token request is as follows:

{
“access_token”: “xxxxxxxxxxxxx_xxxx”,
“token_type”: “bearer”,
“expires_in”: 1209599,
“userName”: “test@test.com”,
“.issued”: “Mon, 23 Apr 2018 06:08:03 GMT”,
“.expires”: “Mon, 07 May 2018 06:08:03 GMT”
}

Once the changes below have been made the response will include a userId field:

{
“access_token”: “xxxxxxxxxxxxx_xxxx”,
“token_type”: “bearer”,
“expires_in”: 1209599,
“userName”: “test@test.com”,
“.issued”: “Mon, 23 Apr 2018 06:08:03 GMT”,
“.expires”: “Mon, 07 May 2018 06:08:03 GMT”,
“userId”: “xxxxxxx”
}

There are three very small changes required in order to add this functionality.

First, add an additional argument to CreateProperties in ApplicationOAuthProvider.cs

public static AuthenticationProperties CreateProperties(string userName, string userId)
{
IDictionary data = new Dictionary
{
{ "userName", userName },
// Add
{ "userId", userId }
};
return new AuthenticationProperties(data);
}

Pass userId to CreateProperties in ApplicationOauthProvider.

// ApplicationOAuthProvider.cs > GrantResourceOwnerCredentials
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType);
ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
CookieAuthenticationDefaults.AuthenticationType);

// Add user id
AuthenticationProperties properties = CreateProperties(user.UserName, user.Id);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);

Pass userId to CreateProperties in AccountController.

// AccountController.cs > GetExternalLogin
if (hasRegistered)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);

ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager, OAuthDefaults.AuthenticationType);
ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
CookieAuthenticationDefaults.AuthenticationType);

// Add userid
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName, user.Id);
Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);

Unsupported_Grant_Type – MVC Web Api (error)

Hi everyone,

I ran into the following error while attempting to authenticate using .NET Web Api:

POST http://localhost:63720/Token HTTP/1.1
Host: localhost:63720
Content-Type: application/json
Content-Length: 0
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Date: Mon, 16 Apr 2018 14:18:06 GMT
Content-Length: 34

{“error”:”unsupported_grant_type”}

This one was pretty straight forward. Ensure that have the correct content-type:

Content-Type: application/x-www-form-urlencoded

And finally, ensure that you provide a grant type in the request body:

grant_type=password&username=test_username&password=test_password

Thanks to the following stackoverflow post for the info: https://stackoverflow.com/a/29261024/522859

Exited with code 9009 – Visual Studio Build

Hey everyone,

I ran into the following error today while attempting to build a solution:

combiner exited with code 9009

It apparently means that a file couldn’t be found. The solution was to simply restart visual studio.

I’d been manually adding them to the directory and this is apparently a common cause. See the following Stackoverflow post for more info: https://stackoverflow.com/a/28198020/522859

Unilateral receiver not allowed in chained payment is restricted – Adaptive Payment DotNet SDK

Hey everyone,

Just an error I ran into today while using the Adaptive Payments SDK for C#/.NET:

Unilateral receiver not allowed in chained payment is restricted

Thankfully this one is fairly simple – one of the receivers hasn’t confirmed their account.

http://stackoverflow.com/a/32816078/522859

Could not find part of the path ‘C:\x\lib’ – Adding new Web API Project

Hey everyone,

I ran into the following error when I tried to add a new Web API project in Visual Studio Express 2015 for Web:

Could not find part of the path ‘C:\x\lib’

The workaround for this was to temporarily unbind the project from TFS: File > Source Control > Advanced > Change Source Control > Click unbind on each of the projects

While not the same problem, this post helped me out: https://github.com/NuGet/Home/issues/1164