如何修复:'Adding Face API to the project failed'
How to fix: 'Adding Face API to the project failed'
我正在尝试将 Face API 连接的服务添加到 C# Web 应用程序,但是当服务是 'Creating new Face API...' 时我收到错误:将 Face API 添加到项目失败: 'properties' 字段无效,错误:'将值 {null} 转换为类型 'System.Boolean' 时出错。路径 'isMigrated'.'.
我已经更新了我的 .NET 和 vs 2017 版本。创建了新项目但没有成功。当前项目是一个全新的项目,没有任何改变。我使用的是试用版 Azure 帐户。问题似乎与 Face API 的实施有关,因为 'isMigrated' 到目前为止没有出现在我的代码中的任何地方。
我在遵循这个 official guide 时得到了和你一样的错误。我不确定 vs 中的组件是否有问题,也许是错误之类的。
我对其进行了一些研究,发现所有这些连接服务所做的就是在您的订阅中创建一个 Face API 服务,并在您的 Web 应用程序中写入 API 密钥和端点 appsettings.json
文件。事实上,我们可以手动完成这个过程。
这些是我在我这边制作演示的步骤:
- 转到 Azure portal,创建人脸 API 认知服务
创建服务后,将其密钥和端点复制到此处:
- 在VS中创建一个.net core web app,替换里面的内容
appsettings.json
内容如下:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"FaceAPI_ServiceKey": "<key in previous step>",
"FaceAPI_ServiceEndPoint": "<endpoint in previous step>"
}
用下面的代码替换startup.cs中的内容:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.IO;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;
namespace <your name space here>
{
public class Startup
{
private IConfiguration configuration;
public Startup(IConfiguration configuration)
{
this.configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env)
{
// TODO: Change this to your image's path on your site.
string imagePath = @"images/face1.jpg";
// Enable static files such as image files.
app.UseStaticFiles();
string faceApiKey = this.configuration["FaceAPI_ServiceKey"];
string faceApiEndPoint = this.configuration["FaceAPI_ServiceEndPoint"];
HttpClient client = new HttpClient();
// Request headers.
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", faceApiKey);
// Request parameters. A third optional parameter is "details".
string requestParameters = "returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise";
// Assemble the URI for the REST API Call.
string uri = faceApiEndPoint + "/detect?" + requestParameters;
// Request body. Posts an image you've added to your site's images folder.
var fileInfo = env.WebRootFileProvider.GetFileInfo(imagePath);
var byteData = GetImageAsByteArray(fileInfo.PhysicalPath);
string contentStringFace = string.Empty;
using (ByteArrayContent content = new ByteArrayContent(byteData))
{
// This example uses content type "application/octet-stream".
// The other content types you can use are "application/json" and "multipart/form-data".
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
// Execute the REST API call.
var response = client.PostAsync(uri, content).Result;
// Get the JSON response.
contentStringFace = response.Content.ReadAsStringAsync().Result;
}
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
/// <summary>
/// Returns the contents of the specified file as a byte array.
/// </summary>
/// <param name="imageFilePath">The image file to read.</param>
/// <returns>The byte array of the image data.</returns>
static byte[] GetImageAsByteArray(string imageFilePath)
{
FileStream fileStream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read);
BinaryReader binaryReader = new BinaryReader(fileStream);
return binaryReader.ReadBytes((int)fileStream.Length);
}
/// <summary>
/// Formats the given JSON string by adding line breaks and indents.
/// </summary>
/// <param name="json">The raw JSON string to format.</param>
/// <returns>The formatted JSON string.</returns>
static string JsonPrettyPrint(string json)
{
if (string.IsNullOrEmpty(json))
return string.Empty;
json = json.Replace(Environment.NewLine, "").Replace("\t", "");
string INDENT_STRING = " ";
var indent = 0;
var quoted = false;
var sb = new StringBuilder();
for (var i = 0; i < json.Length; i++)
{
var ch = json[i];
switch (ch)
{
case '{':
case '[':
sb.Append(ch);
if (!quoted)
{
sb.AppendLine();
}
break;
case '}':
case ']':
if (!quoted)
{
sb.AppendLine();
}
sb.Append(ch);
break;
case '"':
sb.Append(ch);
bool escaped = false;
var index = i;
while (index > 0 && json[--index] == '\')
escaped = !escaped;
if (!escaped)
quoted = !quoted;
break;
case ',':
sb.Append(ch);
if (!quoted)
{
sb.AppendLine();
}
break;
case ':':
sb.Append(ch);
if (!quoted)
sb.Append(" ");
break;
default:
sb.Append(ch);
break;
}
}
return sb.ToString();
}
app.Run(async (context) =>
{
await context.Response.WriteAsync($"<p><b>Face Image:</b></p>");
await context.Response.WriteAsync($"<div><img src=\"" + imagePath + "\" /></div>");
await context.Response.WriteAsync($"<p><b>Face detection API results:</b></p>");
await context.Response.WriteAsync("<p>");
await context.Response.WriteAsync(JsonPrettyPrint(contentStringFace));
await context.Response.WriteAsync("<p>");
});
}
}
}
在wwwroot下添加一个文件夹,并在此处放置一张图片,本例中图片名称为face1.jpg
:
完成这些步骤后,运行您可以看到该项目如官方演示所示完美运行:
如果这个post有帮助,请点击这个答案左边的灰色大复选按钮来标记这个答案,这样它会帮助其他有同样问题的人:)
我正在尝试将 Face API 连接的服务添加到 C# Web 应用程序,但是当服务是 'Creating new Face API...' 时我收到错误:将 Face API 添加到项目失败: 'properties' 字段无效,错误:'将值 {null} 转换为类型 'System.Boolean' 时出错。路径 'isMigrated'.'.
我已经更新了我的 .NET 和 vs 2017 版本。创建了新项目但没有成功。当前项目是一个全新的项目,没有任何改变。我使用的是试用版 Azure 帐户。问题似乎与 Face API 的实施有关,因为 'isMigrated' 到目前为止没有出现在我的代码中的任何地方。
我在遵循这个 official guide 时得到了和你一样的错误。我不确定 vs 中的组件是否有问题,也许是错误之类的。
我对其进行了一些研究,发现所有这些连接服务所做的就是在您的订阅中创建一个 Face API 服务,并在您的 Web 应用程序中写入 API 密钥和端点 appsettings.json
文件。事实上,我们可以手动完成这个过程。
这些是我在我这边制作演示的步骤:
- 转到 Azure portal,创建人脸 API 认知服务
- 在VS中创建一个.net core web app,替换里面的内容
appsettings.json
内容如下:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"FaceAPI_ServiceKey": "<key in previous step>",
"FaceAPI_ServiceEndPoint": "<endpoint in previous step>"
}
用下面的代码替换startup.cs中的内容:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.IO;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;
namespace <your name space here>
{
public class Startup
{
private IConfiguration configuration;
public Startup(IConfiguration configuration)
{
this.configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env)
{
// TODO: Change this to your image's path on your site.
string imagePath = @"images/face1.jpg";
// Enable static files such as image files.
app.UseStaticFiles();
string faceApiKey = this.configuration["FaceAPI_ServiceKey"];
string faceApiEndPoint = this.configuration["FaceAPI_ServiceEndPoint"];
HttpClient client = new HttpClient();
// Request headers.
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", faceApiKey);
// Request parameters. A third optional parameter is "details".
string requestParameters = "returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise";
// Assemble the URI for the REST API Call.
string uri = faceApiEndPoint + "/detect?" + requestParameters;
// Request body. Posts an image you've added to your site's images folder.
var fileInfo = env.WebRootFileProvider.GetFileInfo(imagePath);
var byteData = GetImageAsByteArray(fileInfo.PhysicalPath);
string contentStringFace = string.Empty;
using (ByteArrayContent content = new ByteArrayContent(byteData))
{
// This example uses content type "application/octet-stream".
// The other content types you can use are "application/json" and "multipart/form-data".
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
// Execute the REST API call.
var response = client.PostAsync(uri, content).Result;
// Get the JSON response.
contentStringFace = response.Content.ReadAsStringAsync().Result;
}
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
/// <summary>
/// Returns the contents of the specified file as a byte array.
/// </summary>
/// <param name="imageFilePath">The image file to read.</param>
/// <returns>The byte array of the image data.</returns>
static byte[] GetImageAsByteArray(string imageFilePath)
{
FileStream fileStream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read);
BinaryReader binaryReader = new BinaryReader(fileStream);
return binaryReader.ReadBytes((int)fileStream.Length);
}
/// <summary>
/// Formats the given JSON string by adding line breaks and indents.
/// </summary>
/// <param name="json">The raw JSON string to format.</param>
/// <returns>The formatted JSON string.</returns>
static string JsonPrettyPrint(string json)
{
if (string.IsNullOrEmpty(json))
return string.Empty;
json = json.Replace(Environment.NewLine, "").Replace("\t", "");
string INDENT_STRING = " ";
var indent = 0;
var quoted = false;
var sb = new StringBuilder();
for (var i = 0; i < json.Length; i++)
{
var ch = json[i];
switch (ch)
{
case '{':
case '[':
sb.Append(ch);
if (!quoted)
{
sb.AppendLine();
}
break;
case '}':
case ']':
if (!quoted)
{
sb.AppendLine();
}
sb.Append(ch);
break;
case '"':
sb.Append(ch);
bool escaped = false;
var index = i;
while (index > 0 && json[--index] == '\')
escaped = !escaped;
if (!escaped)
quoted = !quoted;
break;
case ',':
sb.Append(ch);
if (!quoted)
{
sb.AppendLine();
}
break;
case ':':
sb.Append(ch);
if (!quoted)
sb.Append(" ");
break;
default:
sb.Append(ch);
break;
}
}
return sb.ToString();
}
app.Run(async (context) =>
{
await context.Response.WriteAsync($"<p><b>Face Image:</b></p>");
await context.Response.WriteAsync($"<div><img src=\"" + imagePath + "\" /></div>");
await context.Response.WriteAsync($"<p><b>Face detection API results:</b></p>");
await context.Response.WriteAsync("<p>");
await context.Response.WriteAsync(JsonPrettyPrint(contentStringFace));
await context.Response.WriteAsync("<p>");
});
}
}
}
在wwwroot下添加一个文件夹,并在此处放置一张图片,本例中图片名称为face1.jpg
:
完成这些步骤后,运行您可以看到该项目如官方演示所示完美运行:
如果这个post有帮助,请点击这个答案左边的灰色大复选按钮来标记这个答案,这样它会帮助其他有同样问题的人:)