|
Has anyone on here had any experience getting server-side Blazor to work with IE11?
The reason I ask is that some large companies and government agencies still require all web apps to run on IE11. Regardless of how wrong that may be, it is currently an immutable requirement.
When I create a new server-side Blazor project in VS 2019 16.3.0 Preview 1, I can run it using IIS Express and targeting IE11. The web site comes up and runs, but the "onclick" event does not change the counter value display. You can recreate this issue by simply creating a new server-side Blazor app in that version of VS 2019 Preview.
I would appreciate knowing the specifics of how anyone has been successful at making their server-side Blazor app with IE11. I've done several web searches, and saw some suggestions about PolyFill.io, but nothing concrete.
Thanks in advance for those willing to help.
|
|
|
|
|
I thought this would be pretty simple to do, but has turned into a circular headache.
It's hard to find info on the internet on this subject, for most are using MailKit and MimeKit, others using SendGrid.
Plus I read that SmtpClient has been obsoleted as well with MailKit being reccomended.
So I have my secrets file working,
My Google OAuth2 Credentials have been tested and works.
Altered my Startup.cs to add Google credentials to services.
Altered my Startup.cs to services.AddAuthentication().AddGoogle
I did the example that opens up the browser to a Google Auth Page, writes the token with successful auth.
So here is my circular headache ....
Using Nuget MailKit/MimeKit, it doesn't register with .Net Core V2.2
Using Nuget SendGrid, same thing, doesn't register, get the caution or warning icon in dependencies nuget.
I can do this now, but I don't have any code to actually send the email.
var secrets = new Google.Apis.Auth.OAuth2.ClientSecrets
{
ClientId = Environment.GetEnvironmentVariable("GMailClientId"),
ClientSecret = Environment.GetEnvironmentVariable("GMailClientSecret")
};
var googleCredentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, new[] { GmailService.Scope.MailGoogleCom }, email, CancellationToken.None);
if (googleCredentials.Token.IsExpired(SystemClock.Default))
{
await googleCredentials.RefreshTokenAsync(CancellationToken.None);
}
I'm not sure which way I should proceed.
I can't find any references, or documentation for .Net Core V2.2
I must admit that the SendGrid SAS looks pretty cool for sending email from my website.
Any help would be appreciated!
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Quote: Using Nuget MailKit/MimeKit, it doesn't register with .Net Core V2.2 Perhaps some other thing is causing this issue, the dependencies should be restored properly. Can you try removing this dependency to see if that works; oh and do not forget to drill down the dependency tree to see what is actual root cause for the yellow sign.
Check this article for more on that, ASP.NET Core 2.2 - SMTP EmailSender Implementation - KenHaggerty.Com , he was able to have this setup in ASP.NET Core 2.2.
Secondly for the Gmail API, I believe you are missing out the GmailSend scope,
var googleCredentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, new[] { GmailService.Scope.MailGoogleCom }, email, CancellationToken.None); This should include the GmailSend scope,
var googleCredentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, new[] { GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailSend }, email, CancellationToken.None); See this another thread on CodeProject that discusses this, Send email using gmail api in C#.
Lastly, it is always a good practice to try something as small as a hello world program. You can get started for a hello world program for Gmail API from here, .NET Quickstart | Gmail API | Google Developers, and then extend the program by reading the references and the SDK API, gmail: Main Page
The sh*t I complain about
It's like there ain't a cloud in the sky and it's raining out - Eminem
~! Firewall !~
|
|
|
|
|
Thanks for the quick reply!
Took your advice and reinstalled Mailkit/MimeKit, to drill down on the dependencies and so far it just installed without the caution icon. That's strange and not sure what to say about that.
Looks like you gave me enough info to get something going today, I'll let you know how it works out.
Thank you very much!
Jim
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
I'm up and running now, Thanks!
The secrets file didn't work out due to me running in a Docker Linux container.
Thanks for the tip on the Gmail Send Scope for sending without the Browser auth.
Porting over the code I already wrote was a easy drop in for me.
Thanks!
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Worked fine in Debug, but in Debug Docker and Release Docker, I get the failed to open browser error here.
So I call this function
using (var credentials = SendGmailAsync.Create_GoogleCredentials(ms))
{
var result = await SendGmailAsync.Send_GmailAsync(await credentials, message, 5);
SendGmailAsync.ProcessSendResult(model, result);
}
That's calls this function
public static async Task<UserCredential> Create_GoogleCredentials(MAILSERVER ms)
{
var secrets = new Google.Apis.Auth.OAuth2.ClientSecrets
{
ClientId = ms.OAuthCredentials.ClientId,
ClientSecret = ms.OAuthCredentials.ClientSecret
};
var googleCredentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(
secrets,
new[] { GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailSend },
ms.AccountName,
CancellationToken.None
);
if (googleCredentials.Token.IsExpired(SystemClock.Default))
{
await googleCredentials.RefreshTokenAsync(CancellationToken.None);
}
return googleCredentials;
}
It's the end of the day, I'll look at it in more detail tomorrow or Sunday.
I thought this scope GmailService.Scope.GmailSend would not trigger the browser authentication.
Guess I was wrong on that. hmm....
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
There are so many caveats to using a gmail account to just send email.
To the best of my knowledge from what I have learned, if you have a free gmail account, you have to use OAuth2 with clientId and use the browser to authenticate. That's the price of free!
If you have a domain verified Gmail account or Google Cloud account that you pay for; you need service account credentials to use that Gmail account to send email. But with this account type you can access the other services available as well such as Calendar, Drive. $6 a month for each account.
I have the latter paid account, a domain verified Google Cloud account, so I had to create service account credentials, then acquire API permission to the Gmail Service, and then go back to my Google Cloud account and go to security, advanced and set the API permissions to the projectId and service scope for sending email using Gmail. Here you can assign various scopes to the API's you selected to subscribe to. This is the key part or else you get strange errors.
Last I had to write different code and use different form of authentication to get a token and send email.
So I wrote a PFX version to send email, which will be obsolete soon, so now I have to write a Json version to replace it next.
I just tested my prototype code in a production version Docker container on my development machine (Docker for Windows - Linux Container) and it works fine so far, email sent in the background without browser authentication and no token written to the project that I can see. I just tested it in a Linux Docker container running on the production server and the message sent.
It's too bad that the internet is polluted with old documentation and misinformation.
The previous help in this thread was helpful, but was targeted towards the free Gmail Account and didn't work in a Docker container. I have achieved the desired result now but I need to go back and refactor the whole thing to clean it up.
This is the new unrefactored code, which is already obsolete because I'm using a straight P12 certificate that is replaced with consuming the JSON P12 file that has the certificate in it.
Note: the password is really the password for the certificate.
public static async Task<ServiceAccountCredential> Create_GoogleCredentialsWithAccessToken(MAILSERVER ms)
{
var certBuffer = File.ReadAllBytes("projectName-xxxxxxxxxx.p12");
var certificate = new X509Certificate2(certBuffer, "notasecret", X509KeyStorageFlags.Exportable);
var serviceAccountEmail = "xxxxxxxxxx-xxxxxx.iam.gserviceaccount.com";
var userAccountEmail = "xxx@xxxxxx.com";
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
User = userAccountEmail,
Scopes = new[] { GmailService.Scope.MailGoogleCom }
}.FromCertificate(certificate));
if (await credential.RequestAccessTokenAsync(CancellationToken.None))
{
var service = new GmailService(
new Google.Apis.Services.BaseClientService.Initializer()
{
HttpClientInitializer = credential
}
);
}
return credential;
}
public static async Task<SendEmailCompletedEventArgs> Send_GmailServiceAsync(ServiceAccountCredential serviceCredentials, MimeMessage message, int retryCount)
{
var currentTry = 0;
while ((currentTry < retryCount))
{
try
{
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
client.AuthenticationMechanisms.Remove("XOAUTH2");
var oauth2 = new SaslMechanismOAuth2(serviceCredentials.User, serviceCredentials.Token.AccessToken);
client.Authenticate(oauth2);
await client.SendAsync(message);
client.Disconnect(true);
}
return new SendEmailCompletedEventArgs(null, false, null, currentTry);
}
catch (Exception ex)
{
currentTry++;
if ((currentTry >= retryCount))
{
return new SendEmailCompletedEventArgs(ex, true, null, currentTry);
}
}
}
return new SendEmailCompletedEventArgs(null, true, null, currentTry);
}
I used the MimeKit to create my message, then I called the function to authenticate and send.
using (var credentials = SendGmailServiceP12Async.Create_GoogleCredentialsWithAccessToken(ms))
{
var result = await SendGmailServiceP12Async.Send_GmailServiceAsync(await credentials, message, 5);
SendGmailServiceP12Async.ProcessSendResult(model, result);
}
This is valuable info that should be written up professionally and posted here at Code Project.
I need to rewrite this in the new format first and dial it in, before considering posting an article.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
modified 3-Aug-19 19:59pm.
|
|
|
|
|
Really just a reference for me in case I need to dig it up again.
But I spent the morning refactoring the previous code. Took some time because documentation was limited to just 1 post on GitHub of a user suggesting a change to the API. So this takes a service Json file created on Google Cloud or API when you create a Service Account using the Json option, and not the PFM option, and loads the file from the root of the project directly, and creates a ServiceAccountCredential. I added a User "user: me@mydomain.com" to the Google Service Json file in which the Google API didn't seem to mind it being there. The user is my email address required for the Initializer. The MAILSERVER really just contains the name of the Google Service File. So ms.GoogleServiceFile can be replaced with the name of your file.
Not too happy with the double stream, or the use of File.ReadAllTextAsync , because I needed the user parameter that I added and the GoogleCredential.FromStream would not pass it along. I thought about making a copy of the stream, or rewinding it back to 0. The user field is in the ServiceCredentials, perhaps I just need to rename user to something else that can be read.
So far so good; it works in my Debug Docker Linux container and in my production Docker container as well.
Hope this helps the next guy looking to do the same when Google discontinues "Use less secure settings" in Gmail when they remove the option next October.
This should be backwards compatible with MVC, and I wrote this for .Net Core V2.2+ using NeGet
Google.Apis.Gmail.v1.40.2.1635 GitHub - googleapis/google-api-dotnet-client: Google APIs Client Library for .NET
MailKit V2.2
MimeKit V2.2 MimeKit
public static async Task<ServiceAccountCredential> Create_GoogleCredentialsWithAccessToken(MAILSERVER ms)
{
ServiceAccountCredential credentials = null;<br />
var serviceStream = await File.ReadAllTextAsync(ms.GoogleServiceFile);
var parameters = new NewtonsoftJsonSerializer().Deserialize<GoogleServiceApi>(serviceStream);
using (var stream = new FileStream(ms.GoogleServiceFile, FileMode.Open, FileAccess.Read))
{
ServiceAccountCredential original = (ServiceAccountCredential)
GoogleCredential.FromStream(stream).UnderlyingCredential;
var initializer = new ServiceAccountCredential.Initializer(original.Id)
{
User = parameters.user,
ProjectId = parameters.project_id,
Key = original.Key,
Scopes = new[] { GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailSend }
};
credentials = new ServiceAccountCredential(initializer);
if (await credentials.RequestAccessTokenAsync(CancellationToken.None))
{
var service = new GmailService(
new BaseClientService.Initializer()
{
HttpClientInitializer = credentials
}
);
}
}
return credentials;
}
public static async Task<SendEmailCompletedEventArgs> Send_GmailServiceAsync(ServiceAccountCredential serviceCredentials, MimeMessage message, int retryCount)
{
var currentTry = 0;
while ((currentTry < retryCount))
{
try
{
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
var oauth2 = new SaslMechanismOAuth2(serviceCredentials.User, serviceCredentials.Token.AccessToken);
client.Authenticate(oauth2);
await client.SendAsync(message);
client.Disconnect(true);
}
return new SendEmailCompletedEventArgs(null, false, null, currentTry);
}
catch (Exception ex)
{
currentTry++;
if ((currentTry >= retryCount))
{
return new SendEmailCompletedEventArgs(ex, true, null, currentTry);
}
}
}
return new SendEmailCompletedEventArgs(null, true, null, currentTry);
}
Class to code against for NewtonSoftJsonSerializer
public class GoogleServiceApi
{
public string type { get; set; }
public string user { get; set; }
public string project_id { get; set; }
public string private_key_id { get; set; }
public string private_key { get; set; }
public string client_email { get; set; }
public string client_id { get; set; }
public string auth_uri { get; set; }
public string token_uri { get; set; }
public string auth_provider_x509_cert_url { get; set; }
public string client_x509_cert_url { get; set; }
}
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Please, can you help me.
I adapted the example above to asp.net (vb), but it records the same date.
Ex: 08/01/2019 to 08/31/2019, interval of 7 days.
The correct would be to record 08/01 ... 08/08 ... 15/08 ... 22/08 ... 29/08 ... But recorded the 5 days as 01/08.
Follows the code and thanks in advance.
Dim conexao As SqlConnection
Dim cmd As SqlCommand
Dim sql As String
Dim startDate As Date = txtDataCurso.Text
Dim endDate As Date = startDate.AddDays(txtIntervalo.Text) - "This interval is the number of days (end date - initial)"
Dim currDate As Date = startDate
Do While (currDate < endDate)
sql = "INSERT INTO tre_Eventos (Id_Curso, DataEvento) VALUES ('" & ddlCursos.SelectedValue & "', '" & endDate & "')"
currDate = currDate.AddDays(7)
Try
conexao = New SqlConnection(strConn)
conexao.Open()
cmd = New SqlCommand(sql, conexao)
cmd.ExecuteNonQuery()
conexao.Close()
SetFocus(Label1)
Label1.Visible = True
Label1.Text = "Evento Cadastrado com Sucesso"
Catch
SetFocus(Label1)
Label1.Visible = True
Label1.Text = "Ocorreu um erro!" + Err.Description
End Try
|
|
|
|
|
Bartt_dmr wrote: sql = "INSERT INTO tre_Eventos (Id_Curso, DataEvento) VALUES ('" & ddlCursos.SelectedValue & "', '" & endDate & "')"
Don't do it like that!
Your code is almost certainly vulnerable to SQL Injection[^]. NEVER use string concatenation to build a SQL query. ALWAYS use a parameterized query.
You'll need to execute your query for each date you want to insert. Currently, you're only executing it for the end date.
Wrap your command and connection objects in Using blocks so that they're cleaned up properly.
And you should probably wrap the whole thing in a transaction - either all of the dates are inserted, or none of them are. You don't want to be in a position where the loop fails part-way through and you don't know what state your database is in.
Const sql As String = "INSERT INTO tre_Eventos (ID_Curso, DataEvento) VALUE (@ID_Curso, @DataEvento)"
Using conexao As New SqlConnection(strConn)
conexao.Open()
Using transaction As SqlTransaction = conexao.BeginTransaction()
Using cmd As New SqlCommand(sql, conexao)
cmd.Transaction = transaction
cmd.Parameters.AddWithValue("@ID_Curso", ddlCursos.SelectedValue)
Dim pDate As New SqlParameter("@DataEvento", SqlDbType.DateTime)
cmd.Parameters.Add(pDate)
Dim currDate As Date = startDate
Do While currDate < endDate
pDate.Value = currDate
cmd.ExecuteNonQuery()
currDate = currDate.AddDays(7)
Loop
End Using
transaction.Commit()
End Using
End Using
Everything you wanted to know about SQL injection (but were afraid to ask) | Troy Hunt[^]
How can I explain SQL injection without technical jargon? | Information Security Stack Exchange[^]
Query Parameterization Cheat Sheet | OWASP[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
my App is a published website. This error happened when I save the data. Please help.
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.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[NullReferenceException: Object reference not set to an instance of an object.]
Money_Changer.Cusinfo.BtnSave_Click(Object sender, EventArgs e) in C:\Users\Zeeyana\source\repos\Money Changer\Money Changer\Cusinfo.aspx.cs:138
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +9782310
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +204
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +12
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +15
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +35
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1639
darwinahmed
|
|
|
|
|
You already asked this question[^] in the Quick Answers sections. Posting it on several forums will not help you to get a quicker answer; please do not cross-post your questions.
enum HumanBool { Yes, No, Maybe, Perhaps, Probably, ProbablyNot, MostLikely, MostUnlikely, HellYes, HellNo, Wtf }
|
|
|
|
|
This is a very, very, easy problem to solve and only you can do it since we can't run your code. You are trying to access something that is null. Debug your code and you'll find it right away. Simple.
Social Media - A platform that makes it easier for the crazies to find each other.
Everyone is born right handed. Only the strongest overcome it.
Fight for left-handed rights and hand equality.
|
|
|
|
|
I have a VB.Net application using Windows authentication and I would like to implement impersonation. I think that if I can set the value of HttpContext.Current.User to a new username, I can impersonate who ever I wish. Please let me know if this is the correct approach and if so how do I change the value of HttpContext.Current.User.
Thanks in advance.
|
|
|
|
|
|
Apart from what Richard mentioned, I believe you will only mess up with the framework.
Can you share the underlying goals to impersonate the users, so that maybe we can provide you with a better alternative for the approach?
The sh*t I complain about
It's like there ain't a cloud in the sky and it's raining out - Eminem
~! Firewall !~
|
|
|
|
|
No, you cannot impersonate that way. That would be a HUGE security hole. Just google asp.net impersonation. It is very easy to do and a couple of ways of doing it. One via web.config and another via code.
Social Media - A platform that makes it easier for the crazies to find each other.
Everyone is born right handed. Only the strongest overcome it.
Fight for left-handed rights and hand equality.
|
|
|
|
|
Greetings experts,
When I run my app with the following code:
Private Sub SearchCustomers()
Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
Dim startDate As DateTime
Dim EndDate As DateTime
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand()
Dim sql As String = "spGetLogs"
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("@uuid", suuid.Text)
cmd.Parameters.AddWithValue("@callerlist", caller_list_id.Text)
cmd.Parameters.AddWithValue("@phone", phonenumber.Text)
If DateTime.TryParseExact(date_start.Text, "yyyy-MM-dd HH:mm:ss", Nothing, System.Globalization.DateTimeStyles.None, startDate) Then
cmd.Parameters.AddWithValue("@start", startDate)
Else
cmd.Parameters.AddWithValue("@start", DBNull.Value)
End If
If DateTime.TryParseExact(date_end.Text, "yyyy-MM-dd HH:mm:ss", Nothing, System.Globalization.DateTimeStyles.None, EndDate) Then
cmd.Parameters.AddWithValue("@Endd", EndDate)
Else
cmd.Parameters.AddWithValue("@Endd", DBNull.Value)
End If
cmd.Parameters.AddWithValue("@calltype", call_type.SelectedValue)
'Response.Write(sql)
'Response.End()
cmd.CommandText = sql
cmd.CommandTimeout = 600
cmd.Connection = con
Using sda As New SqlDataAdapter(cmd)
Dim dt As New DataTable()
sda.Fill(dt)
gvCustomers.DataSource = dt
gvCustomers.DataBind()
End Using
End Using
End Using
End Sub
It just keeps timing out.
However, if I run the query used in the spGetLogs stored procedure to get a count of records, it is only 191,000.
Is there something wrong with the code below?
I will be happy to post the query inside the spGetLogs stored procedure.
I have been thrust into a demo of this app on Monday.
In fact, we went through this with the users a couple of hours ago and now I run into this huge issue.
Any assistance is greatly appreciated.
|
|
|
|
|
All your code does is call SQL. So, no, the problem is not in the code. You'll have to debug your sql to find out why it is slow.
Social Media - A platform that makes it easier for the crazies to find each other.
Everyone is born right handed. Only the strongest overcome it.
Fight for left-handed rights and hand equality.
|
|
|
|
|
This may be too late, but …
Try this:
1) Move the Dim dt as New DataTable() before the Using sda statement
2) Move the gvCustomers.DataSouce and Databind statement after the end Using
3) Leave the sda.Fill(dt) inside the Using … end Using block
My theory is that the databinding is taking too long and subsequently the SQL fails because everything is wrapped inside the Using … end Using block.
Just a theory. Give it a shot and post back your results.
|
|
|
|
|
Hi all,
Im looking for information but I dont know if there is a special phase or term to describe it.
Basically, I am building a little Ticketing/Helpdesk system. I do not want to hard code the Questions/Forms. I want an admin to be able to create a Questions/FOrms under a specific Subject.
What should i be searching for to find information on this?
Thanks
Chris
Chris Wright
|
|
|
|
|
This is more a design issue.
You need to store the questions somewhere, usually a database.
You then need to create a form so the admin can create the the questions, storing them in your data store.
You then need to collect the responses for each question and store them in your data store.
After that you have to create the workflow that will support your business requirement.
All of the above can be achieved with winforms and a database. I would probably search for survey or help desk or bug tracking examples.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
Thank you for the reply. It gives me an idea of how the stucture needs to be. I need to make sure I get the database right. It's going to be very complex.
Im going to struggle figuring how to separate the data into tables and then link it all back together to display it within the front end.
Chris Wright
|
|
|
|
|
Take a look at http://www.databaseanswers.org/data_models/[^] and see if there is one that meets your needs. It is a good site to study the structures of databases.
And yes put lot of effort into designing your data structure, think through your requirements before you start creating your database.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
In the first DropdownList should display the Countries and in the second should display Cities based on the Country like .. USA then display just cities in USA . well i am getting undefined in dropdown city the Question is why i am getting always undefined in City dropDown list ?
here is countrol :
<pre> public ActionResult Index()
{
Details();
return View();
}
public void Details (
{
var model = db.GetUniversities().ToList();
List<SelectListItem> li = new List<SelectListItem>();
li.Add(new SelectListItem { Text = "Please select Country",Value="0"});
foreach (var item in model)
{
li.Add(new SelectListItem { Text = item.Country, Value = item.Id.ToString()});
ViewBag.state = li;
}
}
[HttpPost]
public JsonResult GetCity (int id)
{
var ddlCity = db.GetUniversities().Where(x => x.Id == id).ToList();
List<SelectListItem> licities = new List<SelectListItem>();
if (ddlCity != null)
{
foreach (var x in ddlCity)
{
licities.Add(new SelectListItem { Text = x.City, Value = x.Id.ToString() });
}
}
return Json(new SelectList(licities, "Text", "Value"));
}
here view
<div class="form-group">
@Html.LabelFor(model => model.Country, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.Country, ViewBag.state as List<SelectListItem>, new { style = "width: 200px;" })
@Html.ValidationMessageFor(model => model.Country, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.City, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.City, new SelectList(string.Empty, "Value", "Text"), "--Select City--", new { style = "width:200px" })
@Html.ValidationMessageFor(model => model.City, "", new { @class = "text-danger" })
here jQuery
$(document).ready(function () {
$("#Country").change(function () {
$("#City").empty();
$.ajax({
type: 'POST',
url: '@Url.Action("GetCity")',
dataType: 'json',
data: { id: $("#Country").val() },
success: function (city) {
$.each(city, function (i, city) {
$("#City").append('<option value="' + city.Value + '">'+ city.Text + '</option>');
});
},
error: function (ex) {
alert('Failed.' + ex);
}
});
return false;
})
});
|
|
|
|
|