我正在使用 ASP.NET MVC 3 编写一个 RESTful Web 服务。我分别使用基本的 GET/POST/PUT 映射进行检索/创建/更新操作。它适用于我的一种域类型,但我正在为另一种类型实现完全相同的一组操作,并且我从本地 ASP.NET 开发服务器收到 401 Unauthorized 响应。
首先,这里是创建路由的 MyApiAreaRegistration.cs 中 RegisterArea 方法的相关部分(为简洁起见,我删除了 Update 方法):
// student detail
context.MapRoute(
"StudentDetailV1",
"MyApi/v1/family/{email}/student/{id}",
new { controller = "Student", action = "StudentDetail" },
new { httpMethod = new HttpMethodConstraint("GET") }
);
// create student
context.MapRoute(
"CreateStudentV1",
"MyApi/v1/family/{email}/student",
new { controller = "Student", action = "CreateStudent" },
new { httpMethod = new HttpMethodConstraint("POST") }
);
// family detail
context.MapRoute(
"FamilyDetailV1",
"MyApi/v1/family/{email}",
new { controller = "Student", action = "FamilyDetail" },
new { httpMethod = new HttpMethodConstraint("GET") }
);
// create family
context.MapRoute(
"CreateFamilyV1",
"MyApi/v1/family",
new { controller = "Student", action = "CreateFamily" },
new { httpMethod = new HttpMethodConstraint("POST") }
);
在 StudentController 中:
/// <summary>
/// return json representation of FamilyDto
/// </summary>
/// <param name="email"></param>
/// <returns></returns>
[HttpGet]
public ActionResult FamilyDetail(string email)
{
Family f = _studentDataAccess.GetFamilyByEmail(email.Trim());
if (f == null)
{
return HttpNotFound();
}
FamilyDto familyDto = FamilyDtoAssembler.GetDtoFromFamily(f);
return Json(familyDto, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult CreateFamily(FamilyDto familyDto)
{
if (string.IsNullOrWhiteSpace(familyDto.Email))
{
return new HttpStatusCodeResult(409, "Email address is required.");
}
// check for already existing family with that email.
Family f = _studentDataAccess.GetFamilyByEmail(familyDto.Email.Trim());
if (f != null)
{
return new HttpStatusCodeResult(409, "Email address must be unique.");
}
// turn family into a Family object with Parents
Family family = FamilyDtoAssembler.GetFamilyFromDto(familyDto);
// save family via dal (username = family email)
_studentDataAccess.CreateFamily(family, family.Email);
// return redirect to family detail
return RedirectToRoute("FamilyDetailV1", new { email = family.Email });
}
[HttpPost]
public ActionResult CreateStudent(string email, StudentDto studentDto)
{
if (string.IsNullOrWhiteSpace(email))
{
return HttpNotFound();
}
Family family = _studentDataAccess.GetFamilyByEmail(email.Trim());
if (family == null)
{
return HttpNotFound();
}
Student s = StudentDtoAssembler.GetStudentFromDto(_repository, studentDto);
s.Family = family;
_studentDataAccess.CreateStudent(s, email);
return RedirectToRoute("StudentDetailV1", new { email = email, id = s.Id });
}
[HttpGet]
public ActionResult StudentDetail(string email, int id)
{
Student s = _studentDataAccess.GetStudent(id);
if (s == null || s.Family.Email != email)
{
return HttpNotFound();
}
StudentDto studentDto = GeneralDtoAssembler.GetSingleStudentDto(s, s.MatsRegistrations);
return Json(studentDto, JsonRequestBehavior.AllowGet);
}
现在,当我使用 Fiddler 为“创建家庭”操作制作 POST 请求时,使用正确的 JSON 请求正文以匹配家庭 DTO 的定义,该操作返回一个 302 响应,该响应重定向到新创建的家庭详细信息操作家庭。这正是我想要的。然而问题是“创建学生”动作。当我在调试器中单步执行它时,它可以正常工作并返回 RedirectToRoute 结果,但是我在 Fiddler 中看到的只是以下响应:
HTTP/1.1 401 Unauthorized
Server: ASP.NET Development Server/10.0.0.0
Date: Tue, 17 Apr 2012 16:42:10 GMT
X-AspNet-Version: 4.0.30319
jsonerror: true
Cache-Control: private
Content-Type: application/json; charset=utf-8
Content-Length: 105
Connection: Close
{"Message":"Authentication failed.","StackTrace":null,"ExceptionType":"System.InvalidOperationException"}
我已经尝试了我能想到的一切,从在 web.config 中将身份验证模式从“Windows”更改为“None”,到重新排序路由,再到返回 RedirectToAction 而不是 RedirectToRoute,但没有任何效果。请注意,如果我只是从 CreateStudent 返回一个直接的 Json 结果而不是 RedirectToRoute 结果,那么它可以正常工作(200 状态,我看到结果很好)。但是我不明白为什么 CreateStudent 和 CreateFamily 的行为不同,这已经让我发疯了 2 天。哈;lp?